| 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 | } |