forked from civicrm/org.civicrm.civicase
-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1012 from compucorp/FOSFA-283-customfield-tokens
FOSFA-283: Resolve issue with case tokens not resolved via webform
- Loading branch information
Showing
5 changed files
with
126 additions
and
199 deletions.
There are no files selected for viewing
135 changes: 48 additions & 87 deletions
135
CRM/Civicase/Hook/Tokens/AddCaseCustomFieldsTokenValues.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,113 +1,74 @@ | ||
<?php | ||
|
||
use CRM_Civicase_Hook_Tokens_Helper_CaseTokenValues as CaseTokenValuesHelper; | ||
use Civi\Token\Event\TokenValueEvent; | ||
|
||
/** | ||
* Class for adding case custom fields token values. | ||
*/ | ||
class CRM_Civicase_Hook_Tokens_AddCaseCustomFieldsTokenValues { | ||
|
||
/** | ||
* Case Id. | ||
* Evaluate custom fields and case role tokens. | ||
* | ||
* @var int|null | ||
* Case Id. | ||
* @param \Civi\Token\Event\TokenValueEvent $e | ||
* TokenValue Event. | ||
*/ | ||
private $caseId; | ||
public static function evaluateCaseCustomFieldsTokens(TokenValueEvent $e) { | ||
$context = $e->getTokenProcessor()->context; | ||
$caseTokenValuesHelper = new CRM_Civicase_Hook_Tokens_Helper_CaseTokenValues(); | ||
$customTokens = $e->getTokenProcessor()->getMessageTokens()['case_cf'] ?? []; | ||
$caseRoleTokens = $e->getTokenProcessor()->getMessageTokens()['case_roles'] ?? []; | ||
$caseRoleValues = []; | ||
|
||
/** | ||
* Case Token Values helper. | ||
* | ||
* @var \CRM_Civicase_Hook_Tokens_Helper_CaseTokenValues | ||
* Case Custom field helper. | ||
*/ | ||
private $caseTokenValuesHelper; | ||
if (array_key_exists('schema', $context) && in_array('caseId', $context['schema'])) { | ||
foreach ($e->getRows() as $row) { | ||
if (!empty($row->context['caseId'])) { | ||
$caseId = $row->context['caseId']; | ||
$contactId = $row->context['contactId']; | ||
$customValues = $caseTokenValuesHelper->getCustomFieldValues($caseId, $customTokens); | ||
|
||
/** | ||
* Sets required class properties. | ||
* | ||
* @param \CRM_Civicase_Hook_Tokens_Helper_CaseTokenValues $caseTokenValuesHelper | ||
* Case token values helper. | ||
*/ | ||
public function __construct(CaseTokenValuesHelper $caseTokenValuesHelper) { | ||
$this->caseTokenValuesHelper = $caseTokenValuesHelper; | ||
} | ||
// Replace custom field tokens with their values. | ||
foreach ($customTokens as $token) { | ||
$value = $caseTokenValuesHelper->getTokenReplacementValue($token, $customValues); | ||
$row->format('text/plain')->tokens('case_cf', $token, $value); | ||
$row->format('text/html')->tokens('case_cf', $token, $value); | ||
} | ||
|
||
/** | ||
* Sets case custom field token values. | ||
* | ||
* @param array $values | ||
* Token values. | ||
* @param array $cids | ||
* Contact ids. | ||
* @param int $job | ||
* Job id. | ||
* @param array $tokens | ||
* Available tokens. | ||
* @param string $context | ||
* Context name. | ||
*/ | ||
public function run(array &$values, array $cids, $job, array $tokens, $context) { | ||
$this->caseId = $this->caseTokenValuesHelper->getCaseId($values); | ||
if (!$this->shouldRun($tokens)) { | ||
return; | ||
} | ||
// If the token is being resolved through a webform-triggered | ||
// activity, the case role token extension might fail | ||
// to resolve the case role tokens | ||
// due to its inability to locate the case ID. | ||
// To address this, we manually reevaluate the token value here | ||
// by extracting the case ID from the token event. | ||
if (!self::isWebform()) { | ||
continue; | ||
} | ||
|
||
$this->setCaseCustomFieldTokenValues($values, $cids, $tokens); | ||
} | ||
if (function_exists('casetokens_civicrm_tokenvalues') && !empty($caseRoleTokens)) { | ||
Civi::$statics['casetokens']['case_id'] = $row->context['caseId']; | ||
casetokens_civicrm_tokenvalues($caseRoleValues, [$contactId], NULL, ['case_roles' => $caseRoleTokens]); | ||
} | ||
|
||
/** | ||
* Sets case custom field values. | ||
* | ||
* Normally we would not do this but there is an issue of a mysql max table | ||
* join error on a site with a lot of case custom fields enabled. | ||
* To fix that this class CRM_Civicase_Event_Listener_CaseCustomFields was | ||
* created to prevent the loading of custom fields for cases without the | ||
* specific custom fields being passed. However, when replacing tokens for | ||
* sent emails, Civi expects the Case.get call to also return the case custom | ||
* fields with the other case parameters when no return value is specified. | ||
* | ||
* This function replaces the case custom fields token values as civi is | ||
* not able to do the values replacement because of the custom change we made | ||
* to avoid the 61 max table join error. | ||
* | ||
* @param array $values | ||
* Token values. | ||
* @param array $cids | ||
* Contact ids. | ||
* @param array $tokens | ||
* Available tokens. | ||
*/ | ||
private function setCaseCustomFieldTokenValues(array &$values, array $cids, array $tokens) { | ||
$customValues = $this->caseTokenValuesHelper->getCustomFieldValues($this->caseId, $tokens['case_cf']); | ||
if (empty($customValues)) { | ||
return; | ||
} | ||
unset($customValues['id']); | ||
// Replace case role tokens with their values. | ||
if (!empty($caseRoleValues)) { | ||
foreach ($caseRoleTokens as $token) { | ||
$row->format('text/plain')->tokens('case_roles', $token, $caseRoleValues[$contactId]['case_roles.' . $token] ?? ''); | ||
$row->format('text/html')->tokens('case_roles', $token, $caseRoleValues[$contactId]['case_roles.' . $token] ?? ''); | ||
} | ||
|
||
// We need to prepend the token category 'case_cf' to the custom field key | ||
// so it can be evaluated for the case_cf category when token is replaced. | ||
$customValuesNew = []; | ||
foreach ($customValues as $key => $customValue) { | ||
$customValuesNew['case_cf.' . $key] = $this->caseTokenValuesHelper->getTokenReplacementValue($key, $customValues); | ||
} | ||
} | ||
} | ||
} | ||
|
||
foreach ($cids as $cid) { | ||
$values[$cid] = array_merge($values[$cid], $customValuesNew); | ||
} | ||
|
||
} | ||
|
||
/** | ||
* Decides whether the hook should run or not. | ||
* | ||
* @param array $tokens | ||
* Available tokens. | ||
* | ||
* @return bool | ||
* Whether this hook should run or not. | ||
* Detects the token activity is triggered by webform. | ||
*/ | ||
private function shouldRun(array $tokens) { | ||
return !empty($this->caseId) && !empty($tokens['case_cf']); | ||
private static function isWebform() { | ||
return isset($_POST['form_id']) && stripos($_POST['form_id'], 'webform_client_form_') !== FALSE; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
<?php | ||
|
||
/** | ||
* Provides contacts custom fields. | ||
*/ | ||
class CRM_Civicase_Service_CaseCustomFieldsProvider { | ||
|
||
/** | ||
* Provides contacts custom fields. | ||
* | ||
* @return array | ||
* List of custom fields that extends contacts. | ||
*/ | ||
public function get() { | ||
$fields = []; | ||
$customFields = $this->getCustomFields(); | ||
if (!empty($customFields['values'])) { | ||
foreach ($customFields['values'] as $id => $item) { | ||
$fields['custom_' . $id] = $item['name']; | ||
} | ||
} | ||
|
||
return $fields; | ||
} | ||
|
||
/** | ||
* Provides contacts custom fields. | ||
* | ||
* @return array | ||
* List of custom fields that extends contacts. | ||
*/ | ||
public function getCustomFields() { | ||
$customFields = []; | ||
try { | ||
$customFields = civicrm_api3('CustomField', 'get', [ | ||
'custom_group_id.extends' => [ | ||
'IN' => ['Case'], | ||
], | ||
'options' => ['limit' => 0], | ||
]); | ||
} | ||
catch (Throwable $ex) { | ||
} | ||
|
||
return $customFields; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
108 changes: 0 additions & 108 deletions
108
tests/phpunit/CRM/Civicase/Hook/Tokens/AddCaseCustomFieldsTokenValuesTest.php
This file was deleted.
Oops, something went wrong.