(dev/core#2258) CryptoToken - Change notation
[civicrm-core.git] / Civi / Token / AbstractTokenSubscriber.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
5 | |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
10 */
11
12 namespace Civi\Token;
13
14 use Civi\ActionSchedule\Event\MailingQueryEvent;
15 use Civi\Token\Event\TokenRegisterEvent;
16 use Civi\Token\Event\TokenValueEvent;
17 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
18
19 /**
20 * Class AbstractTokenSubscriber
21 * @package Civi\Token
22 *
23 * AbstractTokenSubscriber is a base class which may be extended to
24 * implement tokens in a somewhat more concise fashion.
25 *
26 * To implement a new token handler based on this:
27 * 1. Create a subclass.
28 * 2. Override the constructor and set values for $entity and $tokenNames.
29 * 3. Implement the evaluateToken() method.
30 * 4. Optionally, override others:
31 * + checkActive()
32 * + getActiveTokens()
33 * + prefetch()
34 * + alterActionScheduleMailing()
35 * 5. Register the new class with the event-dispatcher.
36 *
37 * Note: There's no obligation to use this base class. You could implement
38 * your own class anew -- just subscribe the proper events.
39 */
40 abstract class AbstractTokenSubscriber implements EventSubscriberInterface {
41
42 public static function getSubscribedEvents() {
43 return [
44 'civi.token.list' => 'registerTokens',
45 'civi.token.eval' => 'evaluateTokens',
46 'civi.actionSchedule.prepareMailingQuery' => 'alterActionScheduleQuery',
47 ];
48 }
49
50 /**
51 * @var string
52 * Ex: 'contact' or profile' or 'employer'
53 */
54 public $entity;
55
56 /**
57 * @var array
58 * List of tokens provided by this class
59 * Array(string $fieldName => string $label).
60 */
61 public $tokenNames;
62
63 /**
64 * @var array
65 * List of active tokens - tokens provided by this class and used in the message
66 * Array(string $tokenName);
67 */
68 public $activeTokens;
69
70 /**
71 * @param $entity
72 * @param array $tokenNames
73 * Array(string $tokenName => string $label).
74 */
75 public function __construct($entity, $tokenNames = []) {
76 $this->entity = $entity;
77 $this->tokenNames = $tokenNames;
78 }
79
80 /**
81 * Determine whether this token-handler should be used with
82 * the given processor.
83 *
84 * To short-circuit token-processing in irrelevant contexts,
85 * override this.
86 *
87 * @param \Civi\Token\TokenProcessor $processor
88 * @return bool
89 */
90 public function checkActive(\Civi\Token\TokenProcessor $processor) {
91 return TRUE;
92 }
93
94 /**
95 * Register the declared tokens.
96 *
97 * @param \Civi\Token\Event\TokenRegisterEvent $e
98 * The registration event. Add new tokens using register().
99 */
100 public function registerTokens(TokenRegisterEvent $e) {
101 if (!$this->checkActive($e->getTokenProcessor())) {
102 return;
103 }
104 foreach ($this->tokenNames as $name => $label) {
105 $e->register([
106 'entity' => $this->entity,
107 'field' => $name,
108 'label' => $label,
109 ]);
110 }
111 }
112
113 /**
114 * Alter the query which prepopulates mailing data
115 * for scheduled reminders.
116 *
117 * This is method is not always appropriate, but if you're specifically
118 * focused on scheduled reminders, it can be convenient.
119 *
120 * @param \Civi\ActionSchedule\Event\MailingQueryEvent $e
121 * The pending query which may be modified. See discussion on
122 * MailingQueryEvent::$query.
123 */
124 public function alterActionScheduleQuery(MailingQueryEvent $e) {
125 }
126
127 /**
128 * Populate the token data.
129 *
130 * @param \Civi\Token\Event\TokenValueEvent $e
131 * The event, which includes a list of rows and tokens.
132 */
133 public function evaluateTokens(TokenValueEvent $e) {
134 if (!$this->checkActive($e->getTokenProcessor())) {
135 return;
136 }
137
138 $this->activeTokens = $this->getActiveTokens($e);
139 if (!$this->activeTokens) {
140 return;
141 }
142 $prefetch = $this->prefetch($e);
143
144 foreach ($e->getRows() as $row) {
145 foreach ($this->activeTokens as $field) {
146 $this->evaluateToken($row, $this->entity, $field, $prefetch);
147 }
148 }
149 }
150
151 /**
152 * To handle variable tokens, override this function and return the active tokens.
153 *
154 * @param \Civi\Token\Event\TokenValueEvent $e
155 *
156 * @return mixed
157 */
158 public function getActiveTokens(TokenValueEvent $e) {
159 $messageTokens = $e->getTokenProcessor()->getMessageTokens();
160 if (!isset($messageTokens[$this->entity])) {
161 return FALSE;
162 }
163 return array_intersect($messageTokens[$this->entity], array_keys($this->tokenNames));
164 }
165
166 /**
167 * To perform a bulk lookup before rendering tokens, override this
168 * function and return the prefetched data.
169 *
170 * @param \Civi\Token\Event\TokenValueEvent $e
171 *
172 * @return mixed
173 */
174 public function prefetch(TokenValueEvent $e) {
175 return NULL;
176 }
177
178 /**
179 * Evaluate the content of a single token.
180 *
181 * @param TokenRow $row
182 * The record for which we want token values.
183 * @param string $entity
184 * The name of the token entity.
185 * @param string $field
186 * The name of the token field.
187 * @param mixed $prefetch
188 * Any data that was returned by the prefetch().
189 * @return mixed
190 */
191 abstract public function evaluateToken(TokenRow $row, $entity, $field, $prefetch = NULL);
192
193 }