Skip to content

Commit

Permalink
(WIP) Add price fields to form definition
Browse files Browse the repository at this point in the history
  • Loading branch information
jensschuppe committed May 13, 2024
1 parent 44dfa8d commit 2f1f9bd
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 0 deletions.
129 changes: 129 additions & 0 deletions CRM/Remoteevent/RegistrationProfile.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,107 @@ public function getLabel()
*/
abstract public function getFields($locale = null);

/**
* @param array $event
* @param string|null $locale
*
* @return array<string,array<string,mixed>>
* @throws \CRM_Core_Exception
*/
public function getPriceFields(array $event, ?string $locale = NULL): array
{
$fields = [];

if (!(bool) $event['is_monetary']) {
return $fields;
}

$priceFields = \Civi\Api4\Event::get(FALSE)
->addSelect('price_field.*')
->addJoin(
'PriceSetEntity AS price_set_entity',
'INNER',
['price_set_entity.entity_table', '=', '"civicrm_event"'],
['price_set_entity.entity_id', '=', 'id']
)
->addJoin(
'PriceSet AS price_set',
'INNER',
['price_set.id', '=', 'price_set_entity.price_set_id'],
['price_set.is_active', '=', 1]
)
->addJoin(
'PriceField AS price_field',
'LEFT',
['price_field.price_set_id', '=', 'price_set.id']
)
->addWhere('id', '=', $event['id'])
->execute();

if (count($priceFields) === 0) {
return $fields;
}

$l10n = CRM_Remoteevent_Localisation::getLocalisation($locale);
$fields['price'] = [
'type' => 'fieldset',
'name' => 'price',
// TODO: Is the label correctly localised with the requested $locale?
'label' => $event['fee_label'],
];
foreach ($priceFields as $priceField) {
$priceFieldValues = \Civi\Api4\PriceFieldValue::get(FALSE)
->addSelect('id', 'label', 'amount')
->addWhere('price_field_id', '=', $priceField['price_field.id'])
->execute()
->indexBy('id');
$field = [
// TODO: Validate types.
'type' => $priceField['price_field.html_type'],
'name' => $priceField['price_field.name'],
// TODO: Localize label with given $locale.
'label' => $priceField['price_field.label'],
'weight' => $priceField['price_field.weight'],
'required' => (bool) $priceField['price_field.is_required'],
'parent' => 'price',
'options' => $priceFieldValues->column('label'),
];

// Append price field value amounts in option labels.
if ($priceField['price_field.is_display_amounts']) {
array_walk($field['options'], function(&$label, $id, $context) {
$label .= sprintf(
' (%s)',
CRM_Utils_Money::format(
$context['priceFieldValues'][$id]['amount'],
$context['event']['currency']
)
);
}, ['priceFieldValues' => $priceFieldValues, 'event' => $event]);
}

// Add prefixed help text.
if (isset($priceField['price_field.help_pre'])) {
// TODO: Localize with given $locale.
$field['prefix'] = $priceField['price_field.help_pre'];
$field['prefix_display'] = 'inline';
}

// Add suffixed help text.
if (isset($priceField['price_field.help_post'])) {
// TODO: Localize with given $locale.
$field['suffix'] = $priceField['price_field.help_post'];
$field['suffix_display'] = 'inline';
}

// TODO: Ids the price field name unique across all price fields for
// this event?
$fields['price_' . $priceField['price_field.name']] = $field;
}

return $fields;
}

public function getAdditionalParticipantsFields(array $event, ?int $maxParticipants = NULL, ?string $locale = NULL): array
{
$fields = [];
Expand All @@ -108,6 +209,7 @@ public function getAdditionalParticipantsFields(array $event, ?int $maxParticipa
$event['event_remote_registration.remote_registration_additional_participants_profile']
);
$additional_fields = $additional_participants_profile->getFields($locale);
$additional_fields += $additional_participants_profile->getPriceFields($event, $locale);
$fields['additional_participants'] = [
'type' => 'fieldset',
'name' => 'additional_participants',
Expand Down Expand Up @@ -237,6 +339,32 @@ function(int $carry, string $item) {
}
}
}

// Validate price fields.
if ((bool) $event['is_monetary']) {
foreach ($this->validatePriceFields($event, $data) as $field_name => $error) {
$validationEvent->addValidationError($field_name, $error);
}
}
}

/**
* @param array $event
* @param array $submission
* @param \CRM_Remoteevent_Localisation $l10n
*
* @return array<string, string>
* An array with field names as keys and corresponding localised error
* messages as values.
* @throws \CRM_Core_Exception
*/
protected function validatePriceFields(array $event, array $submission, CRM_Remoteevent_Localisation $l10n): array
{
$errors = [];
foreach ($this->getPriceFields($event) as $priceField) {
// TODO: Validate price field values.
}
return $errors;
}

/**
Expand Down Expand Up @@ -362,6 +490,7 @@ public static function addProfileData($get_form_results)
$locale = $get_form_results->getLocale();
$fields = $profile->getFields($locale);
if ('create' === $get_form_results->getParams()['context']) {
$fields += $profile->getPriceFields($event, $locale);
$fields += $profile->getAdditionalParticipantsFields($event, NULL, $locale);
}
$get_form_results->addFields($fields);
Expand Down
3 changes: 3 additions & 0 deletions remoteevent.php
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ function remoteevent_civicrm_config(&$config)
$dispatcher->addUniqueListener(
RegistrationEvent::NAME,
['CRM_Remoteevent_Registration', 'registerAdditionalParticipants'], CRM_Remoteevent_Registration::STAGE2_PARTICIPANT_CREATION);

// TODO: Process price fields.

$dispatcher->addUniqueListener(
RegistrationEvent::NAME,
['CRM_Remoteevent_EventSessions', 'synchroniseSessions'], CRM_Remoteevent_Registration::AFTER_PARTICIPANT_CREATION);
Expand Down

0 comments on commit 2f1f9bd

Please sign in to comment.