Skip to content

Commit

Permalink
Merge pull request #21088 from totten/master-action-batch
Browse files Browse the repository at this point in the history
ActionSchedule - Pass real batches into TokenProcessor. Simplify CRM_Activity_Tokens.
  • Loading branch information
mattwire authored Aug 11, 2021
2 parents c76a1c3 + 9ae8e0f commit bb64ae5
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 35 deletions.
8 changes: 3 additions & 5 deletions CRM/Activity/Tokens.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,16 +84,15 @@ public function alterActionScheduleQuery(\Civi\ActionSchedule\Event\MailingQuery
// Multiple revisions of the activity.
// Q: Could we simplify & move the extra AND clauses into `where(...)`?
$e->query->param('casEntityJoinExpr', 'e.id = reminder.entity_id AND e.is_current_revision = 1 AND e.is_deleted = 0');
$e->query->select('e.id AS tokenContext_' . $this->getEntityContextSchema());
}

/**
* @inheritDoc
*/
public function prefetch(TokenValueEvent $e) {
// Find all the entity IDs
$entityIds
= $e->getTokenProcessor()->getContextValues('actionSearchResult', 'entityID')
+ $e->getTokenProcessor()->getContextValues($this->getEntityContextSchema());
$entityIds = $e->getTokenProcessor()->getContextValues($this->getEntityContextSchema());

if (!$entityIds) {
return NULL;
Expand Down Expand Up @@ -144,8 +143,7 @@ public function evaluateToken(TokenRow $row, $entity, $field, $prefetch = NULL)
'activity_id' => 'id',
];

// Get ActivityID either from actionSearchResult (for scheduled reminders) if exists
$activityId = $row->context['actionSearchResult']->entityID ?? $row->context[$this->getEntityContextSchema()];
$activityId = $row->context[$this->getEntityContextSchema()];

$activity = $prefetch['activity'][$activityId];

Expand Down
65 changes: 36 additions & 29 deletions CRM/Core/BAO/ActionSchedule.php
Original file line number Diff line number Diff line change
Expand Up @@ -267,44 +267,51 @@ public static function sendMailings($mappingID, $now) {
);

$multilingual = CRM_Core_I18n::isMultilingual();
$tokenProcessor = self::createTokenProcessor($actionSchedule, $mapping);
while ($dao->fetch()) {
$errors = [];
try {
$tokenProcessor = self::createTokenProcessor($actionSchedule, $mapping);
$row = $tokenProcessor->addRow()
->context('contactId', $dao->contactID)
->context('actionSearchResult', (object) $dao->toArray());

// switch language if necessary
if ($multilingual) {
$preferred_language = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $dao->contactID, 'preferred_language');
$row->context('locale', CRM_Core_BAO_ActionSchedule::pickLocale($actionSchedule->communication_language, $preferred_language));
$row = $tokenProcessor->addRow()
->context('contactId', $dao->contactID)
->context('actionSearchResult', (object) $dao->toArray());

// switch language if necessary
if ($multilingual) {
$preferred_language = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $dao->contactID, 'preferred_language');
$row->context('locale', CRM_Core_BAO_ActionSchedule::pickLocale($actionSchedule->communication_language, $preferred_language));
}

foreach ($dao->toArray() as $key => $value) {
if (preg_match('/^tokenContext_(.*)/', $key, $m)) {
if (!in_array($m[1], $tokenProcessor->context['schema'])) {
$tokenProcessor->context['schema'][] = $m[1];
}
$row->context($m[1], $value);
}
}
}

foreach ($tokenProcessor->evaluate()->getRows() as $tokenRow) {
// It's possible, eg, that sendReminderEmail fires Hook::alterMailParams() and that some listener use ts().
$swapLocale = empty($row->context['locale']) ? NULL : \CRM_Utils_AutoClean::swapLocale($row->context['locale']);
$tokenProcessor->evaluate();
foreach ($tokenProcessor->getRows() as $tokenRow) {
$dao = $tokenRow->context['actionSearchResult'];
$errors = [];

if ($actionSchedule->mode === 'SMS' || $actionSchedule->mode === 'User_Preference') {
CRM_Utils_Array::extend($errors, self::sendReminderSms($tokenRow, $actionSchedule, $dao->contactID));
}
// It's possible, eg, that sendReminderEmail fires Hook::alterMailParams() and that some listener use ts().
$swapLocale = empty($row->context['locale']) ? NULL : \CRM_Utils_AutoClean::swapLocale($row->context['locale']);

if ($actionSchedule->mode === 'Email' || $actionSchedule->mode === 'User_Preference') {
CRM_Utils_Array::extend($errors, self::sendReminderEmail($tokenRow, $actionSchedule, $dao->contactID));
}
// insert activity log record if needed
if ($actionSchedule->record_activity && empty($errors)) {
$caseID = empty($dao->case_id) ? NULL : $dao->case_id;
CRM_Core_BAO_ActionSchedule::createMailingActivity($tokenRow, $mapping, $dao->contactID, $dao->entityID, $caseID);
}
if ($actionSchedule->mode === 'SMS' || $actionSchedule->mode === 'User_Preference') {
CRM_Utils_Array::extend($errors, self::sendReminderSms($tokenRow, $actionSchedule, $dao->contactID));
}

unset($swapLocale);
}
if ($actionSchedule->mode === 'Email' || $actionSchedule->mode === 'User_Preference') {
CRM_Utils_Array::extend($errors, self::sendReminderEmail($tokenRow, $actionSchedule, $dao->contactID));
}
catch (\Civi\Token\TokenException $e) {
$errors['token_exception'] = $e->getMessage();
// insert activity log record if needed
if ($actionSchedule->record_activity && empty($errors)) {
$caseID = empty($dao->case_id) ? NULL : $dao->case_id;
CRM_Core_BAO_ActionSchedule::createMailingActivity($tokenRow, $mapping, $dao->contactID, $dao->entityID, $caseID);
}

unset($swapLocale);

// update action log record
$logParams = [
'id' => $dao->reminderID,
Expand Down
2 changes: 1 addition & 1 deletion Civi/Token/TokenProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ public function getRow($key) {
* Each row is presented with a fluent, OOP facade.
*/
public function getRows() {
return new TokenRowIterator($this, new \ArrayIterator($this->rowContexts));
return new TokenRowIterator($this, new \ArrayIterator($this->rowContexts ?: []));
}

/**
Expand Down

0 comments on commit bb64ae5

Please sign in to comment.