diff --git a/app/plugins/CoreEnroller/src/Model/Table/BasicAttributeCollectorsTable.php b/app/plugins/CoreEnroller/src/Model/Table/BasicAttributeCollectorsTable.php index 5ed3d6aa..1ec67cea 100644 --- a/app/plugins/CoreEnroller/src/Model/Table/BasicAttributeCollectorsTable.php +++ b/app/plugins/CoreEnroller/src/Model/Table/BasicAttributeCollectorsTable.php @@ -45,6 +45,7 @@ class BasicAttributeCollectorsTable extends Table { use \App\Lib\Traits\PrimaryLinkTrait; use \App\Lib\Traits\TableMetaTrait; use \App\Lib\Traits\ValidationTrait; + use \App\Lib\Traits\LayoutTrait; /** * Perform Cake Model initialization. diff --git a/app/plugins/CoreEnroller/src/Model/Table/EnrollmentAttributesTable.php b/app/plugins/CoreEnroller/src/Model/Table/EnrollmentAttributesTable.php index cee5f79a..3ca48ba2 100644 --- a/app/plugins/CoreEnroller/src/Model/Table/EnrollmentAttributesTable.php +++ b/app/plugins/CoreEnroller/src/Model/Table/EnrollmentAttributesTable.php @@ -85,6 +85,10 @@ public function initialize(array $config): void { 'type' => 'enum', 'class' => 'RequiredAddressFieldsEnum' ], + 'addressGroupedFields' => [ + 'type' => 'enum', + 'class' => 'GroupedAddressFieldsEnum' + ], 'addressTypes' => [ 'type' => 'type', 'attribute' => 'Addresses.type' @@ -155,7 +159,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', @@ -404,8 +413,6 @@ public function validationDefault(Validator $validator): Validator { ]); $validator->allowEmptyString('attribute_mvea_parent'); - $this->registerStringValidation($validator, $schema, 'attribute_required_fields', false); - $this->registerStringValidation($validator, $schema, 'attribute_tag', false); $validator->add('status', [ diff --git a/app/plugins/CoreEnroller/src/config/plugin.json b/app/plugins/CoreEnroller/src/config/plugin.json index 158bf233..679d2cf6 100644 --- a/app/plugins/CoreEnroller/src/config/plugin.json +++ b/app/plugins/CoreEnroller/src/config/plugin.json @@ -72,7 +72,6 @@ "attribute_type": { "type": "integer", "foreignkey": { "table": "types", "column": "id" } }, "attribute_language": { "type": "string", "size": 16 }, "attribute_mvea_parent": { "type": "string", "size": 32 }, - "attribute_required_fields": { "type": "string", "size": 160 }, "attribute_tag": { "type": "string", "size": 128 }, "status": {}, "label": { "type": "string", "size": 80 }, diff --git a/app/plugins/CoreEnroller/templates/AttributeCollectors/dispatch.inc b/app/plugins/CoreEnroller/templates/AttributeCollectors/dispatch.inc index a90b4322..95288d70 100644 --- a/app/plugins/CoreEnroller/templates/AttributeCollectors/dispatch.inc +++ b/app/plugins/CoreEnroller/templates/AttributeCollectors/dispatch.inc @@ -28,7 +28,6 @@ declare(strict_types = 1); use App\Lib\Enum\StatusEnum; -use \Cake\Utility\Inflector; // This view is intended to work with dispatch if($vv_action !== 'dispatch') { @@ -54,83 +53,12 @@ foreach($vv_enrollment_attributes_sorted as $attr) { continue; } - // 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']]); + // Fieldset with legend for MVEAs + if(\in_array($attr->attribute, ['name', 'address', 'telephoneNumber'], true)) { + print $this->element('CoreEnroller.mveas/mvea-fieldset', compact('attr')); continue; } - // Print the element - print $this->element('form/listItem', [ - 'arguments' => $formArguments - ]); + // Default + print $this->element('CoreEnroller.field', compact('attr')); } \ No newline at end of file diff --git a/app/plugins/CoreEnroller/templates/EnrollmentAttributes/fields.inc b/app/plugins/CoreEnroller/templates/EnrollmentAttributes/fields.inc index dc30198b..9b17608f 100644 --- a/app/plugins/CoreEnroller/templates/EnrollmentAttributes/fields.inc +++ b/app/plugins/CoreEnroller/templates/EnrollmentAttributes/fields.inc @@ -168,30 +168,9 @@ if (\in_array($attribute_type, ['adHocAttribute'], true)) { } /* - * Attribute Required field * Attribute Language field - * - * Supported for attributes: name, address */ if(\in_array($attribute_type, ['name', 'address', 'pronoun'], true)) { - $requiredFieldsPopulated = $attribute_type . 'RequiredFields'; - // Pronouns have no required fields at the moment, as a result we will not render any. - if ($this->get($requiredFieldsPopulated) !== null) { - $label = __d('core_enroller', 'field.EnrollmentAttributes.' . $attribute_type . '_required_fields'); - print $this->element('form/listItem', [ - 'arguments' => [ - 'fieldLabel' => $label, - 'fieldName' => 'attribute_required_fields', - 'fieldOptions' => [ - 'empty' => true - ], - 'fieldType' => 'select', - 'fieldSelectOptions' => $this->get($requiredFieldsPopulated) - ] - ]); - } - - print $this->element('form/listItem', [ 'arguments' => [ 'fieldName' => 'attribute_language', diff --git a/app/plugins/CoreEnroller/templates/element/field.php b/app/plugins/CoreEnroller/templates/element/field.php new file mode 100644 index 00000000..68e4be12 --- /dev/null +++ b/app/plugins/CoreEnroller/templates/element/field.php @@ -0,0 +1,118 @@ +Petition->getSupportedEnrollmentAttribute($attr->attribute); + +// 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; +} + +$hidden = true; +// XXX We need to render a field that is required and expects a value from the environment but +// the env value is empty. +if ( + isset($attr->default_value_env_name, $attr->required) + && empty($options['default']) + && $attr->required +) { + $hidden = false; +} + +// Set the final fieldOptions +$formArguments['fieldOptions'] = $options; + +print match(true) { + // HIDDEN Field + // We print directly, we do not delegate to the element for further processing + // In case this is a hidden field, we need to get only the value + $attr->hidden && $hidden =>$this->Form->hidden($formArguments['fieldName'], ['value' => $options['default']]), + // Default use case + default => $this->element('form/listItem', ['arguments' => $formArguments]) +}; diff --git a/app/plugins/CoreEnroller/templates/element/mveas/fieldset-field.php b/app/plugins/CoreEnroller/templates/element/mveas/fieldset-field.php new file mode 100644 index 00000000..58c89298 --- /dev/null +++ b/app/plugins/CoreEnroller/templates/element/mveas/fieldset-field.php @@ -0,0 +1,64 @@ +Petition->getSupportedEnrollmentAttribute($attr->attribute); + +if(isset($supportedAttributes['mveaModel'])) { + $supportedAttributes = $this->Petition->getSupportedEnrollmentAttribute($attr->attribute); + $modelTable = $this->Petition->getTable($supportedAttributes['mveaModel']); + $isRequiredFromValidationRule = !$modelTable->getValidator()->field($field)->isEmptyAllowed(); +} + +// 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' => $modelTable->getSchema()->getColumn($field)['type'], + 'fieldNameAlias' => $attr->attribute // the field name to its enrollment attribute field name +]; +?> + +
"> + + element('form/requiredSpan') : ''?> + Field->formField(...$formArguments) ?> +
+ + diff --git a/app/plugins/CoreEnroller/templates/element/mveas/fieldset-group.php b/app/plugins/CoreEnroller/templates/element/mveas/fieldset-group.php new file mode 100644 index 00000000..380e77e8 --- /dev/null +++ b/app/plugins/CoreEnroller/templates/element/mveas/fieldset-group.php @@ -0,0 +1,81 @@ +attribute . 'GroupedFields'; +$groupedFieldsArray = []; +if(!empty($$groupedFieldsVar)) { + $groupedFieldsArray = collection(array_keys($$groupedFieldsVar))->map(static fn($fields) => explode(',', $fields))->toArray(); +} + +$permitted_fields_list = []; +$permitted_fields_variable_name = 'permitted_fields_' . Inflector::underscore($attr->attribute); +if (!empty($cosettings[0][$permitted_fields_variable_name])) { + $permitted_fields_list = explode(',', $cosettings[0][$permitted_fields_variable_name]); +} +// Address has no permitted fields configuration at CO level. We will get them from +// the model configuration +$supportedAttributes = $this->Petition->getSupportedEnrollmentAttribute($attr->attribute); +$modelTable = $this->Petition->getTable($supportedAttributes['mveaModel']); +if(empty($permitted_fields_list) && !empty($modelTable?->getPermittedFields())) { + $permitted_fields_list = $modelTable->getPermittedFields(); +} + +$permitted_fields_list_flipped = array_flip($permitted_fields_list); +?> + + $fields): ?> +
+ element('CoreEnroller.mveas/fieldset-field', compact('field', 'attr')); + } + // Remove the field we rendered from the permitted list. + unset($permitted_fields_list_flipped[$field]); + } + ?> +
+ + +element('CoreEnroller.mveas/fieldset-field', compact('field', 'attr')); +} +?> + + diff --git a/app/plugins/CoreEnroller/templates/element/mveas/mvea-fieldset.php b/app/plugins/CoreEnroller/templates/element/mveas/mvea-fieldset.php new file mode 100644 index 00000000..9bda744a --- /dev/null +++ b/app/plugins/CoreEnroller/templates/element/mveas/mvea-fieldset.php @@ -0,0 +1,58 @@ +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] + . ' ' + . Inflector::humanize(Inflector::underscore($attr->attribute)); +} + +?> + +
  • +
    + + + +
    + element('CoreEnroller.mveas/fieldset-group', compact( 'attr')) ?> +
    +
    +
  • diff --git a/app/resources/locales/en_US/enumeration.po b/app/resources/locales/en_US/enumeration.po index 9cd7394f..c6f01644 100644 --- a/app/resources/locales/en_US/enumeration.po +++ b/app/resources/locales/en_US/enumeration.po @@ -532,8 +532,14 @@ msgstr "Street" msgid "RequiredAddressFieldsEnum.street,locality,state,postal_code" msgstr "Street, City, State, Postal Code" -msgid "RequiredAddressFieldsEnum.street,locality,state,postal_code,country" -msgstr "Street, City, State, Postal Code, Country" +msgid "GroupedAddressFieldsEnum.street,room" +msgstr "Street, Room" + +msgid "GroupedAddressFieldsEnum.city,locality" +msgstr "City, Locality" + +msgid "GroupedAddressFieldsEnum.state,postal_code,country" +msgstr "State, Postal Code, Country" msgid "RequiredNameFieldsEnum.given" msgstr "Given" diff --git a/app/src/Controller/StandardEnrollerController.php b/app/src/Controller/StandardEnrollerController.php index 601141bb..e320eb39 100644 --- a/app/src/Controller/StandardEnrollerController.php +++ b/app/src/Controller/StandardEnrollerController.php @@ -55,10 +55,14 @@ 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) + // We need to include the Enrollment Flow of the Petition. + // The least, we can get if the co id which cannot be calculated + // for unauthenticated use cases. + ->contain(['EnrollmentFlows']) + ->firstOrFail() : null + ); return parent::beforeRender($event); } diff --git a/app/src/Lib/Enum/GroupedAddressFieldsEnum.php b/app/src/Lib/Enum/GroupedAddressFieldsEnum.php new file mode 100644 index 00000000..c44c7c27 --- /dev/null +++ b/app/src/Lib/Enum/GroupedAddressFieldsEnum.php @@ -0,0 +1,38 @@ + 'UK (+44)', + 1 => 'USA (+1)', + 213 => 'Algeria (+213)', + 376 => 'Andorra (+376)', + 244 => 'Angola (+244)', + 1264 => 'Anguilla (+1264)', + 1268 => 'Antigua & Barbuda (+1268)', + 54 => 'Argentina (+54)', + 374 => 'Armenia (+374)', + 297 => 'Aruba (+297)', + 61 => 'Australia (+61)', + 43 => 'Austria (+43)', + 994 => 'Azerbaijan (+994)', + 1242 => 'Bahamas (+1242)', + 973 => 'Bahrain (+973)', + 880 => 'Bangladesh (+880)', + 1246 => 'Barbados (+1246)', + 375 => 'Belarus (+375)', + 32 => 'Belgium (+32)', + 501 => 'Belize (+501)', + 229 => 'Benin (+229)', + 1441 => 'Bermuda (+1441)', + 975 => 'Bhutan (+975)', + 591 => 'Bolivia (+591)', + 387 => 'Bosnia Herzegovina (+387)', + 267 => 'Botswana (+267)', + 55 => 'Brazil (+55)', + 673 => 'Brunei (+673)', + 359 => 'Bulgaria (+359)', + 226 => 'Burkina Faso (+226)', + 257 => 'Burundi (+257)', + 855 => 'Cambodia (+855)', + 237 => 'Cameroon (+237)', + 1 => 'Canada (+1)', + 238 => 'Cape Verde Islands (+238)', + 1345 => 'Cayman Islands (+1345)', + 236 => 'Central African Republic (+236)', + 56 => 'Chile (+56)', + 86 => 'China (+86)', + 57 => 'Colombia (+57)', + 269 => 'Comoros (+269)', + 242 => 'Congo (+242)', + 682 => 'Cook Islands (+682)', + 506 => 'Costa Rica (+506)', + 385 => 'Croatia (+385)', + 53 => 'Cuba (+53)', + 90392 => 'Cyprus North (+90392)', + 357 => 'Cyprus South (+357)', + 42 => 'Czech Republic (+42)', + 45 => 'Denmark (+45)', + 253 => 'Djibouti (+253)', + 1809 => 'Dominica (+1809)', + 1809 => 'Dominican Republic (+1809)', + 593 => 'Ecuador (+593)', + 20 => 'Egypt (+20)', + 503 => 'El Salvador (+503)', + 240 => 'Equatorial Guinea (+240)', + 291 => 'Eritrea (+291)', + 372 => 'Estonia (+372)', + 251 => 'Ethiopia (+251)', + 500 => 'Falkland Islands (+500)', + 298 => 'Faroe Islands (+298)', + 679 => 'Fiji (+679)', + 358 => 'Finland (+358)', + 33 => 'France (+33)', + 594 => 'French Guiana (+594)', + 689 => 'French Polynesia (+689)', + 241 => 'Gabon (+241)', + 220 => 'Gambia (+220)', + 7880 => 'Georgia (+7880)', + 49 => 'Germany (+49)', + 233 => 'Ghana (+233)', + 350 => 'Gibraltar (+350)', + 30 => 'Greece (+30)', + 299 => 'Greenland (+299)', + 1473 => 'Grenada (+1473)', + 590 => 'Guadeloupe (+590)', + 671 => 'Guam (+671)', + 502 => 'Guatemala (+502)', + 224 => 'Guinea (+224)', + 245 => 'Guinea - Bissau (+245)', + 592 => 'Guyana (+592)', + 509 => 'Haiti (+509)', + 504 => 'Honduras (+504)', + 852 => 'Hong Kong (+852)', + 36 => 'Hungary (+36)', + 354 => 'Iceland (+354)', + 91 => 'India (+91)', + 62 => 'Indonesia (+62)', + 98 => 'Iran (+98)', + 964 => 'Iraq (+964)', + 353 => 'Ireland (+353)', + 972 => 'Israel (+972)', + 39 => 'Italy (+39)', + 1876 => 'Jamaica (+1876)', + 81 => 'Japan (+81)', + 962 => 'Jordan (+962)', + 7 => 'Kazakhstan (+7)', + 254 => 'Kenya (+254)', + 686 => 'Kiribati (+686)', + 850 => 'Korea North (+850)', + 82 => 'Korea South (+82)', + 965 => 'Kuwait (+965)', + 996 => 'Kyrgyzstan (+996)', + 856 => 'Laos (+856)', + 371 => 'Latvia (+371)', + 961 => 'Lebanon (+961)', + 266 => 'Lesotho (+266)', + 231 => 'Liberia (+231)', + 218 => 'Libya (+218)', + 417 => 'Liechtenstein (+417)', + 370 => 'Lithuania (+370)', + 352 => 'Luxembourg (+352)', + 853 => 'Macao (+853)', + 389 => 'Macedonia (+389)', + 261 => 'Madagascar (+261)', + 265 => 'Malawi (+265)', + 60 => 'Malaysia (+60)', + 960 => 'Maldives (+960)', + 223 => 'Mali (+223)', + 356 => 'Malta (+356)', + 692 => 'Marshall Islands (+692)', + 596 => 'Martinique (+596)', + 222 => 'Mauritania (+222)', + 269 => 'Mayotte (+269)', + 52 => 'Mexico (+52)', + 691 => 'Micronesia (+691)', + 373 => 'Moldova (+373)', + 377 => 'Monaco (+377)', + 976 => 'Mongolia (+976)', + 1664 => 'Montserrat (+1664)', + 212 => 'Morocco (+212)', + 258 => 'Mozambique (+258)', + 95 => 'Myanmar (+95)', + 264 => 'Namibia (+264)', + 674 => 'Nauru (+674)', + 977 => 'Nepal (+977)', + 31 => 'Netherlands (+31)', + 687 => 'New Caledonia (+687)', + 64 => 'New Zealand (+64)', + 505 => 'Nicaragua (+505)', + 227 => 'Niger (+227)', + 234 => 'Nigeria (+234)', + 683 => 'Niue (+683)', + 672 => 'Norfolk Islands (+672)', + 670 => 'Northern Marianas (+670)', + 47 => 'Norway (+47)', + 968 => 'Oman (+968)', + 680 => 'Palau (+680)', + 507 => 'Panama (+507)', + 675 => 'Papua New Guinea (+675)', + 595 => 'Paraguay (+595)', + 51 => 'Peru (+51)', + 63 => 'Philippines (+63)', + 48 => 'Poland (+48)', + 351 => 'Portugal (+351)', + 1787 => 'Puerto Rico (+1787)', + 974 => 'Qatar (+974)', + 262 => 'Reunion (+262)', + 40 => 'Romania (+40)', + 7 => 'Russia (+7)', + 250 => 'Rwanda (+250)', + 378 => 'San Marino (+378)', + 239 => 'Sao Tome & Principe (+239)', + 966 => 'Saudi Arabia (+966)', + 221 => 'Senegal (+221)', + 381 => 'Serbia (+381)', + 248 => 'Seychelles (+248)', + 232 => 'Sierra Leone (+232)', + 65 => 'Singapore (+65)', + 421 => 'Slovak Republic (+421)', + 386 => 'Slovenia (+386)', + 677 => 'Solomon Islands (+677)', + 252 => 'Somalia (+252)', + 27 => 'South Africa (+27)', + 34 => 'Spain (+34)', + 94 => 'Sri Lanka (+94)', + 290 => 'St. Helena (+290)', + 1869 => 'St. Kitts (+1869)', + 1758 => 'St. Lucia (+1758)', + 249 => 'Sudan (+249)', + 597 => 'Suriname (+597)', + 268 => 'Swaziland (+268)', + 46 => 'Sweden (+46)', + 41 => 'Switzerland (+41)', + 963 => 'Syria (+963)', + 886 => 'Taiwan (+886)', + 7 => 'Tajikstan (+7)', + 66 => 'Thailand (+66)', + 228 => 'Togo (+228)', + 676 => 'Tonga (+676)', + 1868 => 'Trinidad & Tobago (+1868)', + 216 => 'Tunisia (+216)', + 90 => 'Turkey (+90)', + 7 => 'Turkmenistan (+7)', + 993 => 'Turkmenistan (+993)', + 1649 => 'Turks & Caicos Islands (+1649)', + 688 => 'Tuvalu (+688)', + 256 => 'Uganda (+256)', + 380 => 'Ukraine (+380)', + 971 => 'United Arab Emirates (+971)', + 598 => 'Uruguay (+598)', + 7 => 'Uzbekistan (+7)', + 678 => 'Vanuatu (+678)', + 379 => 'Vatican City (+379)', + 58 => 'Venezuela (+58)', + 84 => 'Vietnam (+84)', + 84 => 'Virgin Islands - British (+1284)', + 84 => 'Virgin Islands - US (+1340)', + 681 => 'Wallis & Futuna (+681)', + 969 => 'Yemen (North)(+969)', + 967 => 'Yemen (South)(+967)', + 260 => 'Zambia (+260)', + 263 => 'Zimbabwe (+263)', + ]; + + return $ccodes[$code] ?? $ccodes; + } +} \ No newline at end of file diff --git a/app/src/Model/Table/AddressesTable.php b/app/src/Model/Table/AddressesTable.php index fa0f81f1..3a0d8018 100644 --- a/app/src/Model/Table/AddressesTable.php +++ b/app/src/Model/Table/AddressesTable.php @@ -59,6 +59,9 @@ class AddressesTable extends Table { 'postal' ] ]; + + // Default permitted Fields. Used for the Attribute Collection + private $permittedFields = ['locality', 'state', 'postal_code', 'country', 'street', 'room']; /** * Perform Cake Model initialization. @@ -262,4 +265,14 @@ public function validationDefault(Validator $validator): Validator { return $validator; } + + /** + * Get the hardcoded list of the Default Permitted Fields + * + * @since COmanage Registry v5.0.0 + * @return array List of permitted fields + */ + public function getPermittedFields(): array { + return $this->permittedFields; + } } \ No newline at end of file diff --git a/app/src/View/Helper/FieldHelper.php b/app/src/View/Helper/FieldHelper.php index 03749912..8fcf3ad6 100644 --- a/app/src/View/Helper/FieldHelper.php +++ b/app/src/View/Helper/FieldHelper.php @@ -212,6 +212,10 @@ public function calculateLiClasses(): string $classes .= 'fields-people-autocomplete '; } + // Each field should have a class like `fields-` + $field = $vv_field_arguments['fieldNameAlias'] ?? $fieldName ?? 'unknown'; + $classes .= " fields-$field"; + return $classes; } @@ -409,6 +413,7 @@ public function formField(string $fieldName, 'class' => 'form-check-input', ]), 'select' => $this->Form->select($fieldName, $fieldSelectOptions, $fieldArgs), + 'text' => $this->Form->textarea($fieldName, $fieldArgs), 'date' => $this->dateField(fieldName: $fieldName, dateType: DateTypeEnum::DateOnly, fieldArgs: $fieldArgs), 'datetime', 'timestamp' => $this->dateField(fieldName: $fieldName, fieldArgs: $fieldArgs), diff --git a/app/src/View/Helper/PetitionHelper.php b/app/src/View/Helper/PetitionHelper.php index eea417c3..2de9a636 100644 --- a/app/src/View/Helper/PetitionHelper.php +++ b/app/src/View/Helper/PetitionHelper.php @@ -34,6 +34,7 @@ use Cake\ORM\Table; use Cake\ORM\TableRegistry; use Cake\Utility\Inflector; +use Cake\Validation\Validator; use Cake\View\Helper; use CoreEnroller\Model\Table\EnrollmentAttributesTable; @@ -81,4 +82,17 @@ public function populateAutoViewVars(): void $this->getView()->set($vvar, $value); } } + + /** + * Get the table validation rules + * + * @param string $tableName + * + * @return Table + * @since COmanage Registry v5.0.0 + */ + public function getTable(string $tableName): Table + { + return TableRegistry::getTableLocator()->get($tableName); + } } \ No newline at end of file diff --git a/app/webroot/css/co-base.css b/app/webroot/css/co-base.css index 624bd665..a0ae64e9 100644 --- a/app/webroot/css/co-base.css +++ b/app/webroot/css/co-base.css @@ -1391,7 +1391,8 @@ ul.form-list li .field { margin: 0; padding: 0.75em; } -ul.form-list li .field:hover { +ul.form-list li .field:hover, +ul.form-list li fieldset:hover { background-color: var(--cmg-color-bg-001); } ul.form-list li.fields-submit {