TokenProcessor
in package
The TokenProcessor is a template/token-engine. It is heavily influenced by traditional expectations of CiviMail, but it's adapted to an object-oriented, extensible design.
BACKGROUND
The CiviMail heritage gives the following expectations:
- Messages are often composed of multiple parts (e.g. HTML-part, text-part, and subject-part).
- Messages are often composed in batches for multiple recipients.
- Tokens are denoted as
{foo.bar}
. - Data should be loaded in an optimized fashion - fetch only the needed columns, and fetch them with one query (per-table).
The question of "optimized" data-loading is a key differentiator/complication. This requires some kind of communication/integration between the template-parser and data-loader.
USAGE
There are generally two perspectives on using TokenProcessor:
- Composing messages: You need to specify the template contents (eg
addMessage(...)
) and the recipients' key data (egaddRow(['contact_id' => 123])
). - Defining tokens/entities/data-loaders: You need to listen for TokenProcessor events; if any of your tokens/entities are used, then load the batch of data.
Each use-case is presented with examples in the Developer Guide:
Tags
Table of Contents
Properties
- $context : array<string|int, mixed>
- $rowContexts : array<string|int, mixed>
- DO NOT access field this directly. Use TokenRow. This is marked as public only to benefit TokenRow.
- $rowValues : array<string|int, mixed>
- DO NOT access field this directly. Use TokenRow. This is marked as public only to benefit TokenRow.
- $dispatcher : EventDispatcherInterface
- $listTokens : array<string|int, mixed>
- A list of available tokens formatted for display
- $messages : array<string|int, mixed>
- $next : mixed
- $tokens : array<string|int, mixed>
- A list of available tokens
Methods
- __construct() : mixed
- addMessage() : TokenProcessor
- Register a string for which we'll need to merge in tokens.
- addRow() : TokenRow
- Add a row of data.
- addRows() : array<string|int, TokenRow>
- Add several rows.
- addSchema() : TokenProcessor
- Add new elements to the field schema.
- addToken() : TokenProcessor
- evaluate() : mixed
- Compute and store token values.
- getContextValues() : array<string|int, mixed>
- Get a list of all unique values for a given context field, whether defined at the processor or row level.
- getMessage() : array<string|int, mixed>
- getMessageTokens() : array<string|int, mixed>
- Get a list of all tokens used in registered messages.
- getRow() : TokenRow
- Get a specific row (i.e. target or recipient).
- getRows() : Traversable<string|int, TokenRow>
- Get the list of rows (i.e. targets/recipients to generate).
- getTokens() : array<string|int, mixed>
- Get the list of available tokens.
- listTokens() : array<string|int, mixed>
- Get the list of available tokens, formatted for display
- render() : string
- Render a message.
- filterTokenValue() : string
- Given a token value, run it through any filters.
Properties
$context
public
array<string|int, mixed>
$context
Description of the context in which the tokens are being processed. Ex: Array('class'=>'CRM_Core_BAO_ActionSchedule', 'schedule' => $dao, 'mapping' => $dao). Ex: Array('class'=>'CRM_Mailing_BAO_MailingJob', 'mailing' => $dao).
For lack of a better place, here's a list of known/intended context values:
- controller: string, the class which is managing the mail-merge.
- smarty: bool, whether to enable smarty support.
- smartyTokenAlias: array, Define Smarty variables that are populated based on token-content. Ex: ['theInvoiceId' => 'contribution.invoice_id']
- contactId: int, the main person/org discussed in the message.
- contact: array, the main person/org discussed in the message. (Optional for performance tweaking; if omitted, will load automatically from contactId.)
- actionSchedule: DAO, the rule which triggered the mailing [for CRM_Core_BAO_ActionScheduler].
- locale: string, the name of a locale (eg 'fr_CA') to use for {ts} strings in the view.
- schema: array, a list of fields that will be provided for each row. This is automatically populated with any general context keys, but you may need to add extra keys for token-row data. ex: ['contactId', 'activityId'].
$rowContexts
DO NOT access field this directly. Use TokenRow. This is marked as public only to benefit TokenRow.
public
array<string|int, mixed>
$rowContexts
Array(int $pos => array $keyValues);
$rowValues
DO NOT access field this directly. Use TokenRow. This is marked as public only to benefit TokenRow.
public
array<string|int, mixed>
$rowValues
Ex: $rowValues[$rowPos][$format][$entity][$field] = 'something'; Ex: $rowValues[3]['text/plain']['contact']['display_name'] = 'something';
$dispatcher
protected
EventDispatcherInterface
$dispatcher
$listTokens
A list of available tokens formatted for display
protected
array<string|int, mixed>
$listTokens
= NULL
Array('{' . $dottedName . '}' => 'labelString')
$messages
protected
array<string|int, mixed>
$messages
Each message is an array with keys:
- string: Unprocessed message (eg "Hello, {display_name}.").
- format: Media type (eg "text/plain").
- tokens: List of tokens which are actually used in this message.
$next
protected
mixed
$next
= 0
$tokens
A list of available tokens
protected
array<string|int, mixed>
$tokens
= NULL
Array(string $dottedName => array('entity'=>string, 'field'=>string, 'label'=>string)).
Methods
__construct()
public
__construct(CiviEventDispatcher $dispatcher, array<string|int, mixed> $context) : mixed
Parameters
- $dispatcher : CiviEventDispatcher
- $context : array<string|int, mixed>
addMessage()
Register a string for which we'll need to merge in tokens.
public
addMessage(string $name, string $value, string $format) : TokenProcessor
Parameters
- $name : string
-
Ex: 'subject', 'body_html'.
- $value : string
-
Ex: '
Hello {contact.name}
'. - $format : string
-
Ex: 'text/html'.
Return values
TokenProcessoraddRow()
Add a row of data.
public
addRow([array<string|int, mixed>|null $context = NULL ]) : TokenRow
Parameters
- $context : array<string|int, mixed>|null = NULL
-
Optionally, initialize the context for this row. Ex: ['contact_id' => 123].
Return values
TokenRowaddRows()
Add several rows.
public
addRows(array<string|int, mixed> $contexts) : array<string|int, TokenRow>
Parameters
- $contexts : array<string|int, mixed>
-
List of rows to add. Ex: [['contact_id'=>123], ['contact_id'=>456]]
Return values
array<string|int, TokenRow> —List of row objects
addSchema()
Add new elements to the field schema.
public
addSchema(string|array<string|int, string> $fieldNames) : TokenProcessor
Parameters
- $fieldNames : string|array<string|int, string>
Return values
TokenProcessoraddToken()
public
addToken(array<string|int, mixed> $params) : TokenProcessor
Parameters
- $params : array<string|int, mixed>
-
Array with keys:
- entity: string, e.g. "profile".
- field: string, e.g. "viewUrl".
- label: string, e.g. "Default Profile URL (View Mode)".
Return values
TokenProcessorevaluate()
Compute and store token values.
public
evaluate() : mixed
getContextValues()
Get a list of all unique values for a given context field, whether defined at the processor or row level.
public
getContextValues(string $field[, string|null $subfield = NULL ]) : array<string|int, mixed>
Parameters
- $field : string
-
Ex: 'contactId'.
- $subfield : string|null = NULL
Return values
array<string|int, mixed> —Ex: [12, 34, 56].
getMessage()
public
getMessage(string $name) : array<string|int, mixed>
Parameters
- $name : string
Return values
array<string|int, mixed> —Keys:
- string: Unprocessed message (eg "Hello, {display_name}.").
- format: Media type (eg "text/plain").
getMessageTokens()
Get a list of all tokens used in registered messages.
public
getMessageTokens() : array<string|int, mixed>
Return values
array<string|int, mixed> —The list of activated tokens, indexed by object/entity. Array(string $entityName => string[] $fieldNames)
Ex: If a message says 'Hello {contact.first_name} {contact.last_name}!', then $result['contact'] would be ['first_name', 'last_name'].
getRow()
Get a specific row (i.e. target or recipient).
public
getRow(int $key) : TokenRow
Ex: echo $p->getRow(2)->context['contact_id']; Ex: $p->getRow(3)->token('profile', 'viewUrl', 'http://example.com/profile?cid=3');
Parameters
- $key : int
-
The row ID
Tags
Return values
TokenRow —The row is presented with a fluent, OOP facade.
getRows()
Get the list of rows (i.e. targets/recipients to generate).
public
getRows() : Traversable<string|int, TokenRow>
Tags
Return values
Traversable<string|int, TokenRow> —Each row is presented with a fluent, OOP facade.
getTokens()
Get the list of available tokens.
public
getTokens() : array<string|int, mixed>
Return values
array<string|int, mixed> —Ex: $tokens['event'] = ['location', 'start_date', 'end_date'].
listTokens()
Get the list of available tokens, formatted for display
public
listTokens() : array<string|int, mixed>
Return values
array<string|int, mixed> —Ex: $tokens['{token.name}'] = "Token label"
render()
Render a message.
public
render(string $name, TokenRow|int $row) : string
Parameters
- $name : string
-
The name previously registered with addMessage().
- $row : TokenRow|int
-
The object or ID for the row previously registered with addRow().
Return values
string —Fully rendered message, with tokens merged.
filterTokenValue()
Given a token value, run it through any filters.
private
filterTokenValue(mixed $value, array<string|int, mixed>|null $filter, TokenRow $row, string $messageFormat) : string
Parameters
- $value : mixed
-
Raw token value (e.g. from
$row->tokens['foo']['bar']
). - $filter : array<string|int, mixed>|null
- $row : TokenRow
-
The current target/row.
- $messageFormat : string
-
Ex: 'text/plain' or 'text/html'