Skip to content
Snippets Groups Projects
Commit 873bfeb5 authored by Eileen McNaughton's avatar Eileen McNaughton
Browse files

#2834 Use event tokens for participant badges

Overview
----------------------------------------
Convert the rest of event badge token replacement to use
the token processor

Before
----------------------------------------
Testing and conversion had been done for contact
and participant tokens within the event badges - but
for the event tokens tests had been added but
the conversion was pending solving date formatting

After
----------------------------------------
Event badges use the token processor for event tokens

At this point all token processing in core for
participant or event tokens is done in the token
processor & attention can switch to cleaning that up

Technical Details
----------------------------------------
The challenge switching over event tokens was that badges used
a custom date format and we needed to figure out how to support
that first.

This also standardises the event.event_id token to participant.event_id
and updates it in the db for scheduled reminders (badges were using
'event.id' format & reminders the event.event_id format).

There are still some tokens on the scheduled reminders to
standarsise and a loading challenge to fix - but this
concludes the badge portion of fixing up event tokens

Note that the tokenConsistencyTest is the main test cover
for event tokens and it turns out we are not quite there
on the dates based on https://github.com/civicrm/civicrm-core/pull/21584
parent 358dde97
No related branches found
No related tags found
No related merge requests found
......@@ -88,10 +88,6 @@ class CRM_Badge_BAO_Badge {
$value = '';
if ($element) {
$value = $row[$element];
// hack to fix date field display format
if (in_array($element, ['event_start_date', 'event_end_date'], TRUE)) {
$value = CRM_Utils_Date::customFormat($value, "%B %E%f");
}
}
$formattedRow['token'][$key] = [
......@@ -404,40 +400,33 @@ class CRM_Badge_BAO_Badge {
public static function buildBadges(&$params, &$form) {
// get name badge layout info
$layoutInfo = CRM_Badge_BAO_Layout::buildLayout($params);
$tokenProcessor = new TokenProcessor(\Civi::dispatcher(), ['schema' => ['participantId'], 'smarty' => FALSE]);
$tokenProcessor = new TokenProcessor(\Civi::dispatcher(), ['schema' => ['participantId', 'eventId'], 'smarty' => FALSE]);
// split/get actual field names from token and individual contact image URLs
$returnProperties = $processorTokens = [];
$processorTokens = [];
if (!empty($layoutInfo['data']['token'])) {
foreach ($layoutInfo['data']['token'] as $index => $value) {
if ($value) {
$token = CRM_Utils_Token::getTokens($value);
if (strpos($value, '{event.') === 0) {
$element = $token['event'][0];
//FIX ME - we need to standardize event token names
if (substr($element, 0, 6) != 'event_') {
// legacy style.
$element = 'event_' . $element;
$returnProperties[$element] = 1;
// add actual field name to row element
$layoutInfo['data']['rowElements'][$index] = $element;
}
}
else {
$tokenName = str_replace(['}', '{contact.', '{participant.'], '', $value);
$tokenProcessor->addMessage($tokenName, $value, 'text/plain');
$processorTokens[] = $tokenName;
$layoutInfo['data']['rowElements'][$index] = $tokenName;
}
$tokenName = str_replace(['}', '{contact.', '{participant.', '{event.'], '', $value);
$tokenProcessor->addMessage($tokenName, $value, 'text/plain');
$processorTokens[] = $tokenName;
$layoutInfo['data']['rowElements'][$index] = $tokenName;
}
}
}
// add additional required fields for query execution
$additionalFields = ['participant_id', 'event_id', 'contact_id'];
foreach ($additionalFields as $field) {
$returnProperties[$field] = 1;
}
$returnProperties = [
'participant_id' => 1,
'event_id' => 1,
'contact_id' => 1,
];
$sortOrder = $form->get(CRM_Utils_Sort::SORT_ORDER);
if ($sortOrder) {
$sortField = explode(' ', $sortOrder)[0];
// Add to select so aliaising is handled.
$returnProperties[trim(str_replace('`', ' ', $sortField))] = 1;
$sortOrder = " ORDER BY $sortOrder";
}
if ($form->_single) {
$queryParams = NULL;
}
......@@ -457,25 +446,13 @@ class CRM_Badge_BAO_Badge {
$where .= " AND {$form->_componentClause}";
}
$sortOrder = NULL;
if ($form->get(CRM_Utils_Sort::SORT_ORDER)) {
$sortOrder = $form->get(CRM_Utils_Sort::SORT_ORDER);
if (!empty($sortOrder)) {
$sortOrder = " ORDER BY $sortOrder";
}
}
$queryString = "$select $from $where $having $sortOrder";
$dao = CRM_Core_DAO::executeQuery($queryString);
$rows = [];
while ($dao->fetch()) {
$tokenProcessor->addRow(['contactId' => $dao->contact_id, 'participantId' => $dao->participant_id]);
$rows[$dao->participant_id] = [];
foreach ($returnProperties as $key => $dontCare) {
// we are now only resolving the 4 event tokens here.
$rows[$dao->participant_id][$key] = $dao->$key ?? NULL;
}
$tokenProcessor->addRow(['contactId' => $dao->contact_id, 'participantId' => $dao->participant_id, 'eventId' => $dao->event_id]);
}
$tokenProcessor->evaluate();
foreach ($tokenProcessor->getRows() as $row) {
......
......@@ -49,13 +49,17 @@ class CRM_Badge_Form_Layout extends CRM_Admin_Form {
$this->add('text', 'description', ts('Description'),
CRM_Core_DAO::getAttribute('CRM_Core_DAO_PrintLabel', 'title'));
// get the tokens
// get the tokens - at the point of rendering the token processor is used so
// the only reason for this cut-down set of tokens is UI on this
// screen and / or historical.
$contactTokens = CRM_Core_SelectValues::contactTokens();
$eventTokens = [
'{event.event_id}' => ts('Event ID'),
'{event.title}' => ts('Event Title'),
'{event.start_date}' => ts('Event Start Date'),
'{event.end_date}' => ts('Event End Date'),
// This layout selection is day + month eg October 27th
// obviously someone felt year was not logical for dates.
'{event.start_date|crmDate:"%B %E%f"}' => ts('Event Start Date'),
'{event.end_date|crmDate:"%B %E%f"}' => ts('Event End Date'),
];
$participantTokens = CRM_Core_SelectValues::participantTokens();
......
......@@ -11,6 +11,7 @@
*/
use Civi\ActionSchedule\Event\MailingQueryEvent;
use Civi\Api4\Event;
/**
* Class CRM_Event_Tokens
......@@ -101,30 +102,24 @@ LEFT JOIN civicrm_phone phone ON phone.id = lb.phone_id
*/
public function evaluateToken(\Civi\Token\TokenRow $row, $entity, $field, $prefetch = NULL) {
$actionSearchResult = $row->context['actionSearchResult'];
if ($field == 'location') {
$loc = [];
$stateProvince = \CRM_Core_PseudoConstant::stateProvince();
$loc['street_address'] = $actionSearchResult->street_address;
$loc['city'] = $actionSearchResult->city;
$loc['state_province'] = $stateProvince[$actionSearchResult->state_province_id] ?? NULL;
$loc['postal_code'] = $actionSearchResult->postal_code;
//$entityTokenParams[$tokenEntity][$field] = \CRM_Utils_Address::format($loc);
$row->tokens($entity, $field, \CRM_Utils_Address::format($loc));
}
elseif ($field == 'info_url') {
$row
->tokens($entity, $field, \CRM_Utils_System::url('civicrm/event/info', 'reset=1&id=' . $actionSearchResult->event_id, TRUE, NULL, FALSE));
$eventID = $row->context['eventId'] ?? $actionSearchResult->event_id;
if (array_key_exists($field, $this->getEventTokenValues($eventID))) {
foreach ($this->getEventTokenValues($eventID)[$field] as $format => $value) {
$row->format($format)->tokens($entity, $field, $value);
}
return;
}
elseif ($field == 'registration_url') {
$row
->tokens($entity, $field, \CRM_Utils_System::url('civicrm/event/register', 'reset=1&id=' . $actionSearchResult->event_id, TRUE, NULL, FALSE));
if ($field === 'event_id') {
// @todo - migrate this to 'id'
$row->tokens($entity, $field, $eventID);
}
elseif (in_array($field, ['start_date', 'end_date'])) {
$row->tokens($entity, $field, \CRM_Utils_Date::customFormat($actionSearchResult->$field));
elseif ($field === 'event_type') {
// temporary - @todo db update to event_type_id:label
$row->tokens($entity, $field, $this->getEventTokenValues($eventID)['event_type_id:label']['text/html']);
}
elseif ($field == 'balance') {
if ($actionSearchResult->entityTable == 'civicrm_contact') {
elseif ($field === 'balance') {
if ($actionSearchResult->entityTable === 'civicrm_contact') {
$balancePay = 'N/A';
}
elseif (!empty($actionSearchResult->entityID)) {
......@@ -134,18 +129,80 @@ LEFT JOIN civicrm_phone phone ON phone.id = lb.phone_id
}
$row->tokens($entity, $field, $balancePay);
}
elseif ($field == 'fee_amount') {
elseif ($field === 'fee_amount') {
$row->tokens($entity, $field, \CRM_Utils_Money::format($actionSearchResult->$field));
}
elseif (isset($actionSearchResult->$field)) {
$row->tokens($entity, $field, $actionSearchResult->$field);
}
elseif ($cfID = \CRM_Core_BAO_CustomField::getKeyID($field)) {
elseif ($cfID = CRM_Core_BAO_CustomField::getKeyID($field)) {
$row->customToken($entity, $cfID, $actionSearchResult->event_id);
}
else {
$row->tokens($entity, $field, '');
parent::evaluateToken($row, $entity, $field, $prefetch);
}
}
/**
* Get the tokens available for the event.
*
* Cache by event as it's l
*
* @param int|null $eventID
*
* @return array
*
* @throws \API_Exception|\CRM_Core_Exception
*
* @internal
*/
protected function getEventTokenValues(int $eventID = NULL): array {
$cacheKey = __CLASS__ . 'event_tokens' . $eventID . '_' . CRM_Core_I18n::getLocale();
if (!Civi::cache('metadata')->has($cacheKey)) {
$event = Event::get(FALSE)->addWhere('id', '=', $eventID)
->setSelect([
'event_type_id',
'title',
'id',
'start_date',
'end_date',
'summary',
'description',
'loc_block_id',
'loc_block_id.address_id.street_address',
'loc_block_id.address_id.city',
'loc_block_id.address_id.state_province_id:label',
'loc_block_id.address_id.postal_code',
'loc_block_id.email_id.email',
'loc_block_id.phone_id.phone',
'custom.*',
])
->execute()->first();
$tokens['location']['text/plain'] = \CRM_Utils_Address::format([
'street_address' => $event['loc_block_id.address_id.street_address'],
'city' => $event['loc_block_id.address_id.city'],
'state_province' => $event['loc_block_id.address_id.state_province_id:label'],
'postal_code' => $event['loc_block_id.address_id.postal_code'],
]);
$tokens['info_url']['text/html'] = \CRM_Utils_System::url('civicrm/event/info', 'reset=1&id=' . $eventID, TRUE, NULL, FALSE);
$tokens['registration_url']['text/html'] = \CRM_Utils_System::url('civicrm/event/register', 'reset=1&id=' . $eventID, TRUE, NULL, FALSE);
$tokens['start_date']['text/html'] = !empty($event['start_date']) ? new DateTime($event['start_date']) : '';
$tokens['end_date']['text/html'] = !empty($event['end_date']) ? new DateTime($event['end_date']) : '';
$tokens['event_type_id:label']['text/html'] = CRM_Core_PseudoConstant::getLabel('CRM_Event_BAO_Event', 'event_type_id', $event['event_type_id']);
$tokens['contact_phone']['text/html'] = $event['loc_block_id.phone_id.phone'];
$tokens['contact_email']['text/html'] = $event['loc_block_id.email_id.email'];
foreach (array_keys($this->getAllTokens()) as $field) {
if (!isset($tokens[$field]) && isset($event[$field])) {
if ($this->isCustomField($field)) {
$tokens[$field]['text/html'] = CRM_Core_BAO_CustomField::displayValue($event[$field], str_replace('custom_', '', $field));
}
else {
$tokens[$field]['text/html'] = $event[$field];
}
}
}
Civi::cache('metadata')->set($cacheKey, $tokens);
}
return Civi::cache('metadata')->get($cacheKey);
}
}
......@@ -25,7 +25,7 @@ class CRM_Upgrade_Incremental_php_FiveFortyThree extends CRM_Upgrade_Incremental
* a version number, e.g. '4.4.alpha1', '4.4.beta3', '4.4.0'.
* @param null $currentVer
*/
public function setPreUpgradeMessage(&$preUpgradeMessage, $rev, $currentVer = NULL) {
public function setPreUpgradeMessage(&$preUpgradeMessage, $rev, $currentVer = NULL): void {
// Example: Generate a pre-upgrade message.
if ($rev === '5.43.alpha1' && !empty(CRM_Core_Component::getEnabledComponents()['CiviCase'])) {
$preUpgradeMessage .= '<p>' . ts('Minor changes have been made to how the tokens to render case.is_deleted, case.created_date and case.modified_date. See https://docs.civicrm.org/sysadmin/en/latest/upgrade/version-specific/ for more') . '</p>';
......@@ -43,7 +43,7 @@ class CRM_Upgrade_Incremental_php_FiveFortyThree extends CRM_Upgrade_Incremental
* @param string $rev
* an intermediate version; note that setPostUpgradeMessage is called repeatedly with different $revs.
*/
public function setPostUpgradeMessage(&$postUpgradeMessage, $rev) {
public function setPostUpgradeMessage(&$postUpgradeMessage, $rev): void {
// Example: Generate a post-upgrade message.
// if ($rev == '5.12.34') {
// $postUpgradeMessage .= '<br /><br />' . ts("By default, CiviCRM now disables the ability to import directly from SQL. To use this feature, you must explicitly grant permission 'import SQL datasource'.");
......@@ -57,7 +57,7 @@ class CRM_Upgrade_Incremental_php_FiveFortyThree extends CRM_Upgrade_Incremental
*/
public function upgrade_5_43_alpha1(string $rev): void {
$this->addTask(ts('Upgrade DB to %1: SQL', [1 => $rev]), 'runSql', $rev);
$this->addTask('Fix DB Collation if needed on the relatonship cache table', 'fixRelationshipCacheTableCollation');
$this->addTask('Fix DB Collation if needed on the relationship cache table', 'fixRelationshipCacheTableCollation');
$this->addTask('Make mapping field foreign key cascade delete', 'alterMappingFK');
$this->addTask('Replace legacy displayName smarty token in Online contribution workflow template',
'updateMessageToken', 'contribution_online_receipt', '$displayName', 'contact.display_name', $rev
......@@ -111,7 +111,15 @@ class CRM_Upgrade_Incremental_php_FiveFortyThree extends CRM_Upgrade_Incremental
'updateMessageToken', '', 'contribution.contribution_status', 'contribution.contribution_status_id:label', $rev
);
$this->addTask('Update campaign token in saved message templates',
'updateMessageToken', '', 'contribution.campaign', 'contribution.campaign_id:label', $rev
'updateMessageToken', '', 'contribution.campaign', 'contribution.campaign_id:label', $rev);
$this->addTask('Update start date token in event badges',
'updatePrintLabelToken', 'event.start_date', 'event.start_date|crmDate:"%B %E%f', $rev
);
$this->addTask('Update end date token in event badges',
'updatePrintLabelToken', 'event.end_date', 'event.end_date|crmDate:"%B %E%f', $rev
);
$this->addTask('Update event id token in event badges',
'updatePrintLabelToken', 'event.event_id', 'participant.event_id', $rev
);
}
......
Source diff could not be displayed: it is too large. Options to address this: view the blob.
......@@ -30,7 +30,7 @@ class CRM_Event_Form_Task_BadgeTest extends CiviUnitTestCase {
$badgeLayout = PrintLabel::get()->addSelect('data')->execute()->first();
$values = [
'data' => array_merge($badgeLayout['data'], ['token' => [], 'font_name' => [''], 'font_size' => [], 'text_alignment' => []]),
'data' => array_merge((array) $badgeLayout['data'], ['token' => [], 'font_name' => [''], 'font_size' => [], 'text_alignment' => []]),
];
foreach (array_keys($this->getAvailableTokens()) as $id => $token) {
$index = $id + 1;
......@@ -88,7 +88,7 @@ class CRM_Event_Form_Task_BadgeTest extends CiviUnitTestCase {
'{event.title}' => 'Annual CiviCRM meet',
'{contact.display_name}' => 'Mr. Anthony Anderson II',
'{contact.current_employer}' => 'Default Organization',
'{event.start_date}' => 'October 21st',
'{event.start_date|crmDate:"%B %E%f"}' => 'October 21st',
'{participant.status_id}' => 2,
'{participant.role_id}' => 1,
'{participant.register_date}' => 'February 19th, 2007',
......@@ -99,8 +99,8 @@ class CRM_Event_Form_Task_BadgeTest extends CiviUnitTestCase {
'{participant.transferred_to_contact_id}' => NULL,
'{participant.role_id:label}' => 'Attendee',
'{participant.fee_label}' => NULL,
'{event.end_date}' => 'October 23rd',
'{event.id}' => 1,
'{event.end_date|crmDate:"%B %E%f"}' => 'October 23rd',
'{participant.event_id}' => 1,
];
}
......
......@@ -460,8 +460,8 @@ Check';
return '
1
Annual CiviCRM meet
October 21st, 2008 12:00 AM
October 23rd, 2008 12:00 AM
October 21st, 2008
October 23rd, 2008
Conference
If you have any CiviCRM related issues or want to track where CiviCRM is heading, Sign up now
event@example.com
......@@ -471,8 +471,8 @@ event description
Emerald City, Maine 90210
$ 50.00
' . CRM_Utils_System::url('civicrm/event/info', NULL, TRUE) . '&amp;reset=1&amp;id=1
' . CRM_Utils_System::url('civicrm/event/register', NULL, TRUE) . '&amp;reset=1&amp;id=1
' . CRM_Utils_System::url('civicrm/event/info', NULL, TRUE) . '&reset=1&id=1
' . CRM_Utils_System::url('civicrm/event/register', NULL, TRUE) . '&reset=1&id=1
my field';
}
......
......@@ -34,7 +34,7 @@ INSERT INTO `civicrm_dashboard`
-- event badge
INSERT INTO civicrm_print_label (title, name, description, label_format_name, label_type_id, is_default, is_reserved, is_active, data)
VALUES
('Annual Conference Hanging Badge (Avery 5395)', 'Annual_Conference_Hanging_Badge', 'For our annual conference', 'Avery 5395', 1, 1, 1, 1, '{literal}{"title":"Annual Conference Hanging Badge (Avery 5395)","label_format_name":"Avery 5395","description":"For our annual conference","token":{"1":"{event.title}","2":"{contact.display_name}","3":"{contact.current_employer}","4":"{event.start_date}"},"font_name":{"1":"dejavusans","2":"dejavusans","3":"dejavusans","4":"dejavusans"},"font_size":{"1":"9","2":"20","3":"15","4":"9"},"font_style":{"1":"","2":"","3":"","4":""},"text_alignment":{"1":"L","2":"C","3":"C","4":"R"},"barcode_type":"barcode","barcode_alignment":"R","image_1":"","image_2":"","is_default":"1","is_active":"1","is_reserved":"1","_qf_default":"Layout:next","_qf_Layout_refresh":"Save and Preview"}{/literal}');
('Annual Conference Hanging Badge (Avery 5395)', 'Annual_Conference_Hanging_Badge', 'For our annual conference', 'Avery 5395', 1, 1, 1, 1, '{literal}{"title":"Annual Conference Hanging Badge (Avery 5395)","label_format_name":"Avery 5395","description":"For our annual conference","token":{"1":"{event.title}","2":"{contact.display_name}","3":"{contact.current_employer}","4":"{event.start_date|crmDate:\"%B %E%f\"}"},"font_name":{"1":"dejavusans","2":"dejavusans","3":"dejavusans","4":"dejavusans"},"font_size":{"1":"9","2":"20","3":"15","4":"9"},"font_style":{"1":"","2":"","3":"","4":""},"text_alignment":{"1":"L","2":"C","3":"C","4":"R"},"barcode_type":"barcode","barcode_alignment":"R","image_1":"","image_2":"","is_default":"1","is_active":"1","is_reserved":"1","_qf_default":"Layout:next","_qf_Layout_refresh":"Save and Preview"}{/literal}');
-- navigation
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment