fix for greeting token
[civicrm-core.git] / Civi / Token / AbstractTokenSubscriber.php
CommitLineData
46f5566c
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
3435af9a 4 | CiviCRM version 4.7 |
46f5566c 5 +--------------------------------------------------------------------+
3b8eef99 6 | Copyright CiviCRM LLC (c) 2004-2017 |
46f5566c
TO
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
26 */
27
28namespace Civi\Token;
29
f9ec2da6 30use Civi\ActionSchedule\Event\MailingQueryEvent;
46f5566c
TO
31use Civi\Token\Event\TokenRegisterEvent;
32use Civi\Token\Event\TokenValueEvent;
33use Symfony\Component\EventDispatcher\EventSubscriberInterface;
34
35/**
36 * Class AbstractTokenSubscriber
37 * @package Civi\Token
38 *
39 * AbstractTokenSubscriber is a base class which may be extended to
40 * implement tokens in a somewhat more concise fashion.
41 *
42 * To implement a new token handler based on this:
43 * 1. Create a subclass.
44 * 2. Override the constructor and set values for $entity and $tokenNames.
45 * 3. Implement the evaluateToken() method.
f9ec2da6
TO
46 * 4. Optionally, override others:
47 * + checkActive()
48 * + prefetch()
49 * + alterActionScheduleMailing()
50 * 5. Register the new class with the event-dispatcher.
46f5566c
TO
51 *
52 * Note: There's no obligation to use this base class. You could implement
53 * your own class anew -- just subscribe the proper events.
54 */
55abstract class AbstractTokenSubscriber implements EventSubscriberInterface {
56
57 public static function getSubscribedEvents() {
58 return array(
59 Events::TOKEN_REGISTER => 'registerTokens',
60 Events::TOKEN_EVALUATE => 'evaluateTokens',
f9ec2da6 61 \Civi\ActionSchedule\Events::MAILING_QUERY => 'alterActionScheduleQuery',
46f5566c
TO
62 );
63 }
64
65 /**
66 * @var string
67 * Ex: 'contact' or profile' or 'employer'
68 */
69 public $entity;
70
71 /**
72 * @var array
73 * Ex: array('viewUrl', 'editUrl').
74 */
75 public $tokenNames;
76
77 /**
78 * @param $entity
79 * @param array $tokenNames
80 * Array(string $fieldName => string $label).
81 */
82 public function __construct($entity, $tokenNames = array()) {
83 $this->entity = $entity;
84 $this->tokenNames = $tokenNames;
85 }
86
87 /**
88 * Determine whether this token-handler should be used with
89 * the given processor.
90 *
91 * To short-circuit token-processing in irrelevant contexts,
92 * override this.
93 *
94 * @param \Civi\Token\TokenProcessor $processor
95 * @return bool
96 */
97 public function checkActive(\Civi\Token\TokenProcessor $processor) {
98 return TRUE;
99 }
100
101 /**
102 * Register the declared tokens.
103 *
104 * @param TokenRegisterEvent $e
105 * The registration event. Add new tokens using register().
106 */
107 public function registerTokens(TokenRegisterEvent $e) {
108 if (!$this->checkActive($e->getTokenProcessor())) {
109 return;
110 }
111 foreach ($this->tokenNames as $name => $label) {
112 $e->register(array(
113 'entity' => $this->entity,
114 'field' => $name,
115 'label' => $label,
116 ));
117 }
118 }
119
f9ec2da6
TO
120 /**
121 * Alter the query which prepopulates mailing data
122 * for scheduled reminders.
123 *
124 * This is method is not always appropriate, but if you're specifically
125 * focused on scheduled reminders, it can be convenient.
126 *
127 * @param MailingQueryEvent $e
128 * The pending query which may be modified. See discussion on
129 * MailingQueryEvent::$query.
130 */
131 public function alterActionScheduleQuery(MailingQueryEvent $e) {
132 }
133
46f5566c
TO
134 /**
135 * Populate the token data.
136 *
137 * @param TokenValueEvent $e
138 * The event, which includes a list of rows and tokens.
139 */
140 public function evaluateTokens(TokenValueEvent $e) {
141 if (!$this->checkActive($e->getTokenProcessor())) {
142 return;
143 }
e0c75385
TO
144
145 $messageTokens = $e->getTokenProcessor()->getMessageTokens();
146 if (!isset($messageTokens[$this->entity])) {
147 return;
148 }
149
150 $activeTokens = array_intersect($messageTokens[$this->entity], array_keys($this->tokenNames));
a0fcf992 151 $extraTokens = array_diff($messageTokens[$this->entity], array_keys($this->tokenNames));
e0c75385 152
46f5566c 153 $prefetch = $this->prefetch($e);
e0c75385 154
46f5566c 155 foreach ($e->getRows() as $row) {
a0fcf992 156 $this->evaluateExtraToken($row, $this->entity, $extraTokens);
157 foreach ((array) $activeTokens as $field) {
46f5566c
TO
158 $this->evaluateToken($row, $this->entity, $field, $prefetch);
159 }
160 }
161 }
162
a0fcf992 163 /**
164 * Populate the custom field and other remaining entity token data.
165 *
1ae59975 166 * @param TokenRow $row
a0fcf992 167 * The record for which we want token values.
168 * @param string $entity
169 * The entity for which we want the token values
170 * @param array $tokens
1ae59975 171 * The array of tokens whose data need to be fetched
a0fcf992 172 */
173 public function evaluateExtraToken(TokenRow $row, $entity, $tokens) {
174 if (empty($tokens)) {
175 return;
176 }
177
178 $actionSearchResult = $row->context['actionSearchResult'];
179
180 try {
181 $result = civicrm_api3($entity, 'getsingle', array(
182 'id' => $actionSearchResult->entity_id,
183 'return' => $tokens,
184 ));
185 }
186 catch (CiviCRM_API3_Exception $e) {
187 return;
188 }
189
190 foreach ($tokens as $token) {
191 $row->tokens($entity, $token, \CRM_Utils_Array::value($token, $result, ''));
192 }
193 }
194
46f5566c
TO
195 /**
196 * To perform a bulk lookup before rendering tokens, override this
197 * function and return the prefetched data.
198 *
54957108 199 * @param \Civi\Token\Event\TokenValueEvent $e
200 *
46f5566c
TO
201 * @return mixed
202 */
203 public function prefetch(TokenValueEvent $e) {
204 return NULL;
205 }
206
207 /**
208 * Evaluate the content of a single token.
209 *
210 * @param TokenRow $row
211 * The record for which we want token values.
212 * @param string $entity
213 * The name of the token entity.
214 * @param string $field
215 * The name of the token field.
216 * @param mixed $prefetch
217 * Any data that was returned by the prefetch().
218 * @return mixed
219 */
220 public abstract function evaluateToken(TokenRow $row, $entity, $field, $prefetch = NULL);
221
222}