Skip to content

Commit

Permalink
Applied PR civicrm#9661
Browse files Browse the repository at this point in the history
  • Loading branch information
twomice committed Jan 16, 2017
1 parent e88ec7a commit 10bbd82
Show file tree
Hide file tree
Showing 9 changed files with 156 additions and 44 deletions.
18 changes: 12 additions & 6 deletions CRM/Activity/Tokens.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,15 @@ class CRM_Activity_Tokens extends \Civi\Token\AbstractTokenSubscriber {
* CRM_Activity_Tokens constructor.
*/
public function __construct() {
parent::__construct('activity', array(
'activity_id' => ts('Activity ID'),
'activity_type' => ts('Activity Type'),
'subject' => ts('Activity Subject'),
'details' => ts('Activity Details'),
'activity_date_time' => ts('Activity Date-Time'),
parent::__construct('activity', array_merge(
array(
'activity_id' => ts('Activity ID'),
'activity_type' => ts('Activity Type'),
'subject' => ts('Activity Subject'),
'details' => ts('Activity Details'),
'activity_date_time' => ts('Activity Date-Time'),
),
$this->getCustomTokens('Activity')
));
}

Expand Down Expand Up @@ -107,6 +110,9 @@ public function evaluateToken(\Civi\Token\TokenRow $row, $entity, $field, $prefe
elseif (isset($actionSearchResult->$field)) {
$row->tokens($entity, $field, $actionSearchResult->$field);
}
elseif ($cfID = \CRM_Core_BAO_CustomField::getKeyID($field)) {
$row->customToken($entity, $cfID, $actionSearchResult->entity_id);
}
else {
$row->tokens($entity, $field, '');
}
Expand Down
4 changes: 4 additions & 0 deletions CRM/Contribute/Tokens.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ public function __construct() {
$tokens['source'] = ts('Contribution Source');
$tokens['status'] = ts('Contribution Status');
$tokens['type'] = ts('Financial Type');
$tokens = array_merge($tokens, $this->getCustomTokens('Contribution'));
parent::__construct('contribution', $tokens);
}

Expand Down Expand Up @@ -135,6 +136,9 @@ public function evaluateToken(\Civi\Token\TokenRow $row, $entity, $field, $prefe
elseif (isset($aliasTokens[$field])) {
$row->dbToken($entity, $field, 'CRM_Contribute_BAO_Contribution', $aliasTokens[$field], $fieldValue);
}
elseif ($cfID = \CRM_Core_BAO_CustomField::getKeyID($field)) {
$row->customToken($entity, $cfID, $actionSearchResult->entity_id);
}
else {
$row->dbToken($entity, $field, 'CRM_Contribute_BAO_Contribution', $field, $fieldValue);
}
Expand Down
36 changes: 21 additions & 15 deletions CRM/Event/Tokens.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,24 @@ class CRM_Event_Tokens extends \Civi\Token\AbstractTokenSubscriber {
* Class constructor.
*/
public function __construct() {
parent::__construct('event', array(
'event_type' => ts('Event Type'),
'title' => ts('Event Title'),
'event_id' => ts('Event ID'),
'start_date' => ts('Event Start Date'),
'end_date' => ts('Event End Date'),
'summary' => ts('Event Summary'),
'description' => ts('Event Description'),
'location' => ts('Event Location'),
'info_url' => ts('Event Info URL'),
'registration_url' => ts('Event Registration URL'),
'fee_amount' => ts('Event Fee'),
'contact_email' => ts('Event Contact (Email)'),
'contact_phone' => ts('Event Contact (Phone)'),
'balance' => ts('Event Balance'),
parent::__construct('event', array_merge(
array(
'event_type' => ts('Event Type'),
'title' => ts('Event Title'),
'event_id' => ts('Event ID'),
'start_date' => ts('Event Start Date'),
'end_date' => ts('Event End Date'),
'summary' => ts('Event Summary'),
'description' => ts('Event Description'),
'location' => ts('Event Location'),
'info_url' => ts('Event Info URL'),
'registration_url' => ts('Event Registration URL'),
'fee_amount' => ts('Event Fee'),
'contact_email' => ts('Event Contact (Email)'),
'contact_phone' => ts('Event Contact (Phone)'),
'balance' => ts('Event Balance'),
),
$this->getCustomTokens('Event')
));
}

Expand Down Expand Up @@ -139,6 +142,9 @@ public function evaluateToken(\Civi\Token\TokenRow $row, $entity, $field, $prefe
elseif (isset($actionSearchResult->$field)) {
$row->tokens($entity, $field, $actionSearchResult->$field);
}
elseif ($cfID = \CRM_Core_BAO_CustomField::getKeyID($field)) {
$row->customToken($entity, $cfID, $actionSearchResult->entity_id);
}
else {
$row->tokens($entity, $field, '');
}
Expand Down
22 changes: 14 additions & 8 deletions CRM/Member/Tokens.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,17 @@ class CRM_Member_Tokens extends \Civi\Token\AbstractTokenSubscriber {
* Class constructor.
*/
public function __construct() {
parent::__construct('membership', array(
'fee' => ts('Membership Fee'),
'id' => ts('Membership ID'),
'join_date' => ts('Membership Join Date'),
'start_date' => ts('Membership Start Date'),
'end_date' => ts('Membership End Date'),
'status' => ts('Membership Status'),
'type' => ts('Membership Type'),
parent::__construct('membership', array_merge(
array(
'fee' => ts('Membership Fee'),
'id' => ts('Membership ID'),
'join_date' => ts('Membership Join Date'),
'start_date' => ts('Membership Start Date'),
'end_date' => ts('Membership End Date'),
'status' => ts('Membership Status'),
'type' => ts('Membership Type'),
),
$this->getCustomTokens('Membership')
));
}

Expand Down Expand Up @@ -95,6 +98,9 @@ public function evaluateToken(\Civi\Token\TokenRow $row, $entity, $field, $prefe
elseif (isset($actionSearchResult->$field)) {
$row->tokens($entity, $field, $actionSearchResult->$field);
}
elseif ($cfID = \CRM_Core_BAO_CustomField::getKeyID($field)) {
$row->customToken($entity, $cfID, $actionSearchResult->entity_id);
}
else {
$row->tokens($entity, $field, '');
}
Expand Down
4 changes: 4 additions & 0 deletions Civi/ActionSchedule/RecipientBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,8 @@ protected function buildAddlFirstPass() {
protected function buildRelRepeatPass() {
$query = $this->prepareQuery(self::PHASE_RELATION_REPEAT);
$startDateClauses = $this->prepareStartDateClauses();
dsm($query->toSQL(), '$query');
dsm($startDateClauses, '$startDateClauses');

// CRM-15376 - do not send our reminders if original criteria no longer applies
// the first part of the startDateClause array is the earliest the reminder can be sent. If the
Expand All @@ -291,6 +293,8 @@ protected function buildRelRepeatPass() {

// For unknown reasons, we manually insert each row. Why not change
// selectActionLogFields() to selectIntoActionLog() above?
dsm($repeatInsert, '$repeatInsert');
dsm(\CRM_Core_DAO::composeQuery($repeatInsert), 'sql');

$arrValues = \CRM_Core_DAO::executeQuery($repeatInsert)->fetchAll();
if ($arrValues) {
Expand Down
21 changes: 17 additions & 4 deletions Civi/Token/AbstractTokenSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,22 @@ public function registerTokens(TokenRegisterEvent $e) {
}
}

/**
* Get all custom field tokens of $entity
*
* @param string $entity
* @return array $customTokens
* return custom field tokens in array('custom_N' => 'label') format
*/
public function getCustomTokens($entity) {
$customTokens = array();
foreach (\CRM_Core_BAO_CustomField::getFields($entity) as $id => $info) {
$customTokens["custom_$id"] = $info['label'];
}

return $customTokens;
}

/**
* Alter the query which prepopulates mailing data
* for scheduled reminders.
Expand Down Expand Up @@ -148,14 +164,11 @@ public function evaluateTokens(TokenValueEvent $e) {
}

$activeTokens = array_intersect($messageTokens[$this->entity], array_keys($this->tokenNames));
if (empty($activeTokens)) {
return;
}

$prefetch = $this->prefetch($e);

foreach ($e->getRows() as $row) {
foreach ($activeTokens as $field) {
foreach ((array) $activeTokens as $field) {
$this->evaluateToken($row, $this->entity, $field, $prefetch);
}
}
Expand Down
17 changes: 14 additions & 3 deletions Civi/Token/TokenCompatSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,18 @@ public function onEvaluate(TokenValueEvent $e) {
// FIXME: Need to differentiate errors which kill the batch vs the individual row.
throw new TokenException("Failed to generate token data. Invalid contact ID: " . $row->context['contactId']);
}

//update value of custom field token
if (!empty($messageTokens['contact'])) {
foreach ($messageTokens['contact'] as $token) {
if (\CRM_Core_BAO_CustomField::getKeyID($token)) {
$contact[$token] = civicrm_api3('Contact', 'getvalue', array(
'return' => $token,
'id' => $contactId,
));
}
}
}
}
else {
$contact = $row->context['contact'];
Expand All @@ -76,7 +88,6 @@ public function onEvaluate(TokenValueEvent $e) {

// Note: This is a small contract change from the past; data should be missing
// less randomly.
//\CRM_Utils_Hook::tokenValues($contact, $row->context['contactId']);
\CRM_Utils_Hook::tokenValues($contactArray,
(array) $contactId,
empty($row->context['mailingJob']) ? NULL : $row->context['mailingJob']->id,
Expand Down Expand Up @@ -104,12 +115,12 @@ public function onRender(TokenRenderEvent $e) {
$e->string = \CRM_Utils_Token::replaceDomainTokens($e->string, \CRM_Core_BAO_Domain::getDomain(), $isHtml, $e->message['tokens'], $useSmarty);

if (!empty($e->context['contact'])) {
$e->string = \CRM_Utils_Token::replaceContactTokens($e->string, $e->context['contact'], $isHtml, $e->message['tokens'], FALSE, $useSmarty);
$e->string = \CRM_Utils_Token::replaceContactTokens($e->string, $e->context['contact'], $isHtml, $e->message['tokens'], TRUE, $useSmarty);

// FIXME: This may depend on $contact being merged with hook values.
$e->string = \CRM_Utils_Token::replaceHookTokens($e->string, $e->context['contact'], $e->context['hookTokenCategories'], $isHtml, $useSmarty);

\CRM_Utils_Token::replaceGreetingTokens($e->string, NULL, $e->context['contact']['contact_id'], NULL, $useSmarty);
\CRM_Utils_Token::replaceGreetingTokens($e->string, $e->context['contact'], $e->context['contact']['contact_id'], NULL, $useSmarty);
}

if ($useSmarty) {
Expand Down
23 changes: 23 additions & 0 deletions Civi/Token/TokenRow.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,29 @@ public function tokens($a = NULL, $b = NULL, $c = NULL) {
return $this;
}

/**
* Update the value of a custom field token.
*
* @param string $entity
* @param int $customFieldID
* @param int $entityID
* @return TokenRow
*/
public function customToken($entity, $customFieldID, $entityID) {
$customFieldName = "custom_" . $customFieldID;
$fieldValue = civicrm_api3($entity, 'getvalue', array(
'return' => $customFieldName,
'id' => $entityID,
));

// format the raw custom field value into proper display value
if ($fieldValue) {
$fieldValue = \CRM_Core_BAO_CustomField::displayValue($fieldValue, $customFieldID);
}

return $this->tokens($entity, $customFieldName, $fieldValue);
}

/**
* Update the value of a token. Apply formatting based on DB schema.
*
Expand Down
55 changes: 47 additions & 8 deletions tests/phpunit/CRM/Core/BAO/ActionScheduleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ public function setUp() {
'contact_type' => 'Individual',
'email' => 'test-member@example.com',
'gender_id' => 'Female',
'first_name' => 'Churmondleia',
'last_name' => 'Ōtākou',
);
$this->fixtures['contact_birthdate'] = array(
'is_deceased' => 0,
Expand Down Expand Up @@ -593,6 +595,28 @@ public function setUp() {
'subject' => 'subject send reminder every unit after membership_end_date',
);

$customGroup = $this->callAPISuccess('CustomGroup', 'create', array(
'title' => ts('Test Contact Custom group'),
'name' => 'test_contact_cg',
'extends' => 'Contact',
'domain_id' => CRM_Core_Config::domainID(),
'is_active' => 1,
'collapse_adv_display' => 0,
'collapse_display' => 0,
));
$customField = $this->callAPISuccess('CustomField', 'create', array(
'label' => 'Test Text',
'data_type' => 'String',
'html_type' => 'Text',
'custom_group_id' => $customGroup['id'],
));
$this->fixtures['contact_custom_token'] = array(
'id' => $customField['id'],
'token' => sprintf('{contact.custom_%s}', $customField['id']),
'name' => sprintf('custom_%s', $customField['id']),
'value' => 'text ' . substr(sha1(rand()), 0, 7),
);

$this->_setUp();
}

Expand All @@ -603,7 +627,6 @@ public function setUp() {
*/
public function tearDown() {
parent::tearDown();

$this->mut->clearMessages();
$this->mut->stop();
unset($this->mut);
Expand All @@ -615,36 +638,48 @@ public function tearDown() {
'civicrm_event',
'civicrm_email',
));
$this->callAPISuccess('CustomField', 'delete', array('id' => $this->fixtures['contact_custom_token']['id']));
$this->callAPISuccess('CustomGroup', 'delete', array(
'id' => CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomGroup', 'test_contact_cg', 'id', 'name'),
));
$this->_tearDown();
}

public function mailerExamples() {
$cases = array();

$manyTokensTmpl = implode(';;', array(
// Some tokens - short as subject has 128char limit in DB.
$someTokensTmpl = implode(';;', array(
'{contact.display_name}', // basic contact token
'{contact.gender}', // funny legacy contact token
'{contact.gender_id}', // funny legacy contact token
'{domain.name}', // domain token
'{activity.activity_type}', // action-scheduler token
));
// Further tokens can be tested in the body text/html.
$manyTokensTmpl = implode(';;', array(
$someTokensTmpl,
'{contact.email_greeting}',
$this->fixture['contact_custom_token']['token'],
));
// Note: The behavior of domain-tokens on a scheduled reminder is undefined. All we
// can really do is check that it has something.
$manyTokensExpected = 'test-member@example.com;;Female;;Female;;[a-zA-Z0-9 ]+;;Phone Call';
$someTokensExpected = 'Churmondleia Ōtākou;;Female;;Female;;[a-zA-Z0-9 ]+;;Phone Call';
$manyTokensExpected = sprintf('%s;;Dear Churmondleia;;%s', $someTokensExpected, $this->fixture['contact_custom_token']['value']);

// In this example, we use a lot of tokens cutting across multiple components..
// In this example, we use a lot of tokens cutting across multiple components.
$cases[0] = array(
// Schedule definition.
array(
'subject' => "subj $manyTokensTmpl",
'subject' => "subj $someTokensTmpl",
'body_html' => "html $manyTokensTmpl",
'body_text' => "text $manyTokensTmpl",
),
// Assertions (regex).
array(
'from_name' => "/^FIXME\$/",
'from_email' => "/^info@EXAMPLE.ORG\$/",
'subject' => "/^subj $manyTokensExpected\$/",
'subject' => "/^subj $someTokensExpected\$/",
'body_html' => "/^html $manyTokensExpected\$/",
'body_text' => "/^text $manyTokensExpected\$/",
),
Expand Down Expand Up @@ -717,7 +752,12 @@ public function testMailer($schedule, $patterns) {

$activity = $this->createTestObject('CRM_Activity_DAO_Activity', $this->fixtures['phonecall']);
$this->assertTrue(is_numeric($activity->id));
$contact = $this->callAPISuccess('contact', 'create', $this->fixtures['contact']);
$contact = $this->callAPISuccess('contact', 'create', array_merge(
$this->fixtures['contact'],
array(
$this->fixtures['contact_custom_token']['name'] => $this->fixtures['contact_custom_token']['value'],
)
));
$activity->save();

$source['contact_id'] = $contact['id'];
Expand Down Expand Up @@ -755,7 +795,6 @@ public function testMailer($schedule, $patterns) {
}
}
$this->mut->clearMessages();

}

public function testActivityDateTimeMatchNonRepeatableSchedule() {
Expand Down

0 comments on commit 10bbd82

Please sign in to comment.