Create a custom token.¶
This step-by-step guide describes how to create a custom token. The example token is the reversed sort name of a contact. It can me used like this {contact.reversename}. So if the contact's name is Ben Userthe token will show neB ,resU.
To create such a token you have to execute the following steps. * Create the code to compute the token. * Create a class where you can put the code. This class wil have some special properties. It will act as an CiviCRM service. * Let the class react on two predefined token events. * Code how these events are processed. * Combine everything in an extension.
Compute the token¶
The token needs two functions. First to reverse a string. This can be programmed as follows:
private function reverse($name) : string {
if(empty($name)) {
return '';
} else {
return $this->reverse(substr($name, 1)).$name[0];
}
}
Now it has to be combined with a function that gets the sort name of a contact using the id.
private function reversename($contactId): string {
$contact = \Civi\Api4\Contact::get(FALSE)
->addSelect('sort_name')
->addWhere('id', '=', $contactId)
->execute()
->single();
return $this->reverse($contact['sort_name']);
}
Create a CiviCRM service¶
CiviCRM has construction called a service. It is described in Services Chapter . Here an AutoSubscriber is used that registers itself automatically. Below you see the class definition.
use Civi\Core\Service\AutoSubscriber;
class Service extends AutoSubscriber {
}
scan-classes@1.0.0 is added to the mixins in the info.xml, like this.
<mixins>
<mixin>scan-classes@1.0.0</mixin>
</mixins>
React on a event.¶
Extending the AutoSubscriber class instructs the class to react on predefined Symfon event. The function with the prescribed name getSubscribedEvents caters for this.
public static function getSubscribedEvents() {
return ['civi.token.list' => 'register',
'civi.token.eval' => 'value'];
}
civi.token.list is submitted when CiviCRM has to display all the possible tokens with there description. In the class needs now a function register that adds this token to the list. The second function value is mappend to the civi.token.eval event, that is called when the value of the token is computed.
Show the token definition¶
The following function registers the token.
public function register(TokenRegisterEvent $e){
$e->entity('contact')->register('reversename', E::ts('Reverse the sortname'));
}
entity('contacts') defines a new contact token, and the ->register part determines the name of the token and adds the description.
Compute the value of the token¶
The value of a token is requested by submitting a TokenValueEvent . The following function value does the job with the help of the earlier defined reversename function.
public function value(TokenValueEvent $e) {
foreach ($e->getRows() as $row) {
/* @var TokenRow $row */
$row->format('text/html');
if($row->context['contactId']) {
$row->tokens('contact', 'reversename', $this->reversename($row->context['contactId']));
}
}
}
Below some explanantion:
- The different rows in the loop are the different types of text that can be processed for one token. Mostly this is an email that can be formatted in html format or test format. The
format('test/html')works for both. - The
context['contactId']contains the contact id if one is known. For an email that will be the contact id of the receiver. - The
context['contactId']can be empty, so check this before doing the calculation.
Combine everything in an extension.¶
The only thing that has to be done is to add the just created class to an extension. There is no need for extra hooks or other classes. You can download the complete extension at https://lab.civicrm.org/kainuk/reversenametoken