Skip to content

Commit 9b8505e

Browse files
committed
(WIP) Add price fields to form definition
1 parent add6dfe commit 9b8505e

File tree

2 files changed

+132
-0
lines changed

2 files changed

+132
-0
lines changed

CRM/Remoteevent/RegistrationProfile.php

+129
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,107 @@ public function getLabel()
9696
*/
9797
abstract public function getFields($locale = null);
9898

99+
/**
100+
* @param array $event
101+
* @param string|null $locale
102+
*
103+
* @return array<string,array<string,mixed>>
104+
* @throws \CRM_Core_Exception
105+
*/
106+
public function getPriceFields(array $event, ?string $locale = NULL): array
107+
{
108+
$fields = [];
109+
110+
if (!(bool) $event['is_monetary']) {
111+
return $fields;
112+
}
113+
114+
$priceFields = \Civi\Api4\Event::get(FALSE)
115+
->addSelect('price_field.*')
116+
->addJoin(
117+
'PriceSetEntity AS price_set_entity',
118+
'INNER',
119+
['price_set_entity.entity_table', '=', '"civicrm_event"'],
120+
['price_set_entity.entity_id', '=', 'id']
121+
)
122+
->addJoin(
123+
'PriceSet AS price_set',
124+
'INNER',
125+
['price_set.id', '=', 'price_set_entity.price_set_id'],
126+
['price_set.is_active', '=', 1]
127+
)
128+
->addJoin(
129+
'PriceField AS price_field',
130+
'LEFT',
131+
['price_field.price_set_id', '=', 'price_set.id']
132+
)
133+
->addWhere('id', '=', $event['id'])
134+
->execute();
135+
136+
if (count($priceFields) === 0) {
137+
return $fields;
138+
}
139+
140+
$l10n = CRM_Remoteevent_Localisation::getLocalisation($locale);
141+
$fields['price'] = [
142+
'type' => 'fieldset',
143+
'name' => 'price',
144+
// TODO: Is the label correctly localised with the requested $locale?
145+
'label' => $event['fee_label'],
146+
];
147+
foreach ($priceFields as $priceField) {
148+
$priceFieldValues = \Civi\Api4\PriceFieldValue::get(FALSE)
149+
->addSelect('id', 'label', 'amount')
150+
->addWhere('price_field_id', '=', $priceField['price_field.id'])
151+
->execute()
152+
->indexBy('id');
153+
$field = [
154+
// TODO: Validate types.
155+
'type' => $priceField['price_field.html_type'],
156+
'name' => $priceField['price_field.name'],
157+
// TODO: Localize label with given $locale.
158+
'label' => $priceField['price_field.label'],
159+
'weight' => $priceField['price_field.weight'],
160+
'required' => (bool) $priceField['price_field.is_required'],
161+
'parent' => 'price',
162+
'options' => $priceFieldValues->column('label'),
163+
];
164+
165+
// Append price field value amounts in option labels.
166+
if ($priceField['price_field.is_display_amounts']) {
167+
array_walk($field['options'], function(&$label, $id, $context) {
168+
$label .= sprintf(
169+
' (%s)',
170+
CRM_Utils_Money::format(
171+
$context['priceFieldValues'][$id]['amount'],
172+
$context['event']['currency']
173+
)
174+
);
175+
}, ['priceFieldValues' => $priceFieldValues, 'event' => $event]);
176+
}
177+
178+
// Add prefixed help text.
179+
if (isset($priceField['price_field.help_pre'])) {
180+
// TODO: Localize with given $locale.
181+
$field['prefix'] = $priceField['price_field.help_pre'];
182+
$field['prefix_display'] = 'inline';
183+
}
184+
185+
// Add suffixed help text.
186+
if (isset($priceField['price_field.help_post'])) {
187+
// TODO: Localize with given $locale.
188+
$field['suffix'] = $priceField['price_field.help_post'];
189+
$field['suffix_display'] = 'inline';
190+
}
191+
192+
// TODO: Ids the price field name unique across all price fields for
193+
// this event?
194+
$fields['price_' . $priceField['price_field.name']] = $field;
195+
}
196+
197+
return $fields;
198+
}
199+
99200
public function getAdditionalParticipantsFields(array $event, ?int $maxParticipants = NULL, ?string $locale = NULL): array
100201
{
101202
$fields = [];
@@ -108,6 +209,7 @@ public function getAdditionalParticipantsFields(array $event, ?int $maxParticipa
108209
$event['event_remote_registration.remote_registration_additional_participants_profile']
109210
);
110211
$additional_fields = $additional_participants_profile->getFields($locale);
212+
$additional_fields += $additional_participants_profile->getPriceFields($event, $locale);
111213
$fields['additional_participants'] = [
112214
'type' => 'fieldset',
113215
'name' => 'additional_participants',
@@ -237,6 +339,32 @@ function(int $carry, string $item) {
237339
}
238340
}
239341
}
342+
343+
// Validate price fields.
344+
if ((bool) $event['is_monetary']) {
345+
foreach ($this->validatePriceFields($event, $data) as $field_name => $error) {
346+
$validationEvent->addValidationError($field_name, $error);
347+
}
348+
}
349+
}
350+
351+
/**
352+
* @param array $event
353+
* @param array $submission
354+
* @param \CRM_Remoteevent_Localisation $l10n
355+
*
356+
* @return array<string, string>
357+
* An array with field names as keys and corresponding localised error
358+
* messages as values.
359+
* @throws \CRM_Core_Exception
360+
*/
361+
protected function validatePriceFields(array $event, array $submission, CRM_Remoteevent_Localisation $l10n): array
362+
{
363+
$errors = [];
364+
foreach ($this->getPriceFields($event) as $priceField) {
365+
// TODO: Validate price field values.
366+
}
367+
return $errors;
240368
}
241369

242370
/**
@@ -362,6 +490,7 @@ public static function addProfileData($get_form_results)
362490
$locale = $get_form_results->getLocale();
363491
$fields = $profile->getFields($locale);
364492
if ('create' === $get_form_results->getParams()['context']) {
493+
$fields += $profile->getPriceFields($event, $locale);
365494
$fields += $profile->getAdditionalParticipantsFields($event, NULL, $locale);
366495
}
367496
$get_form_results->addFields($fields);

remoteevent.php

+3
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,9 @@ function remoteevent_civicrm_config(&$config)
150150
$dispatcher->addUniqueListener(
151151
RegistrationEvent::NAME,
152152
['CRM_Remoteevent_Registration', 'registerAdditionalParticipants'], CRM_Remoteevent_Registration::STAGE2_PARTICIPANT_CREATION);
153+
154+
// TODO: Process price fields.
155+
153156
$dispatcher->addUniqueListener(
154157
RegistrationEvent::NAME,
155158
['CRM_Remoteevent_EventSessions', 'synchroniseSessions'], CRM_Remoteevent_Registration::AFTER_PARTICIPANT_CREATION);

0 commit comments

Comments
 (0)