CRM-13422 - Form/ScheduleReminders - Allow role filters on custom mappings
[civicrm-core.git] / Civi / ActionSchedule / Mapping.php
CommitLineData
50a23755 1<?php
546a1ecc
TO
2/*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.6 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2015 |
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
50a23755
TO
28namespace Civi\ActionSchedule;
29
546a1ecc
TO
30/**
31 * Class Mapping
32 * @package Civi\ActionSchedule
33 *
34 * This is the initial implementation of MappingInterface; it was
35 * constructed by cutting out swaths from CRM_Core_BAO_ActionSchedule.
36 * New implementers should consider implementing MappingInterface on
37 * their own.
38 *
39 * Background: The original designers of ActionMappings intended that
40 * one could create and configure new mappings through the database.
41 * To, e.g., define the filtering options for CiviEvent, you
42 * would insert a record in "civicrm_action_mapping" with fields like
43 * "entity" (a table name, eg "civicrm_event"), "entity_value" (an
44 * option-group name, eg "event_types").
45 *
46 * Unfortunately, the metadata in "civicrm_action_mapping" proved
47 * inadequate and was not updated to cope. Instead, a number
48 * of work-arounds for specific entities were hard-coded into
49 * the core action-scheduling code. Ultimately, to add a new
50 * mapping type, one needed to run around and patch a dozen
51 * places.
52 *
53 * The new MappingInterface makes no pretense of database-driven
54 * configuration. The dozen places have been consolidated and
55 * replaced with functions in MappingInterface.
56 *
9e1bf145 57 * This "Mapping" implementation is a refactoring of the old
546a1ecc
TO
58 * hard-coded bits. Internally, it uses the concepts from
59 * "civicrm_action_mapping". The resulting code is more
9e1bf145
TO
60 * convoluted than a clean implementation of MappingInterface, but
61 * it strictly matches the old behavior (based on logging/comparing
62 * the queries produced through ActionScheduleTest).
546a1ecc
TO
63 */
64abstract class Mapping implements MappingInterface {
50a23755
TO
65
66 private static $fields = array(
67 'id',
68 'entity',
69 'entity_label',
70 'entity_value',
71 'entity_value_label',
72 'entity_status',
73 'entity_status_label',
74 'entity_date_start',
75 'entity_date_end',
50a23755
TO
76 );
77
78 public static function create($params) {
79 return new static($params);
80 }
81
82 public function __construct($params) {
83 foreach (self::$fields as $field) {
84 if (isset($params[$field])) {
85 $this->{$field} = $params[$field];
86 }
87 }
88 }
89
9e1bf145 90 protected $id;
50a23755
TO
91
92 /**
93 * The basic entity to query (table name).
94 *
95 * @var string
96 * Ex: 'civicrm_activity', 'civicrm_event'.
97 */
9e1bf145 98 protected $entity;
50a23755
TO
99
100 /**
101 * The basic entity to query (label).
102 *
103 * @var
104 * Ex: 'Activity', 'Event'
105 */
9e1bf145 106 private $entity_label;
50a23755
TO
107
108 /**
109 * Level 1 filter -- the field/option-list to filter on.
110 *
111 * @var string
112 * Ex: 'activity_type', 'civicrm_event', 'event_template'.
113 */
77e16391 114 private $entity_value;
50a23755
TO
115
116 /**
117 * Level 1 filter -- The field label.
118 *
119 * @var string
120 * Ex: 'Activity Type', 'Event Name', 'Event Template'.
121 */
9e1bf145 122 private $entity_value_label;
50a23755
TO
123
124 /**
125 * Level 2 filter -- the field/option-list to filter on.
126 * @var string
127 * Ex: 'activity_status, 'civicrm_participant_status_type', 'auto_renew_options'.
128 */
9e1bf145 129 private $entity_status;
50a23755
TO
130
131 /**
132 * Level 2 filter -- the field label.
133 * @var string
134 * Ex: 'Activity Status', 'Participant Status', 'Auto Rewnewal Options'.
135 */
9e1bf145 136 private $entity_status_label;
50a23755
TO
137
138 /**
139 * Date filter -- the field name.
140 * @var string|NULL
141 * Ex: 'event_start_date'
142 */
9e1bf145 143 private $entity_date_start;
50a23755
TO
144
145 /**
146 * Date filter -- the field name.
147 * @var string|NULL
148 * Ex: 'event_end_date'.
149 */
9e1bf145 150 private $entity_date_end;
50a23755 151
9e1bf145
TO
152 /**
153 * @return mixed
154 */
155 public function getId() {
156 return $this->id;
157 }
158
159 /**
160 * @return string
161 */
162 public function getEntity() {
163 return $this->entity;
164 }
165
166 /**
167 * Get a printable label for this mapping type.
168 *
169 * @return string
170 */
171 public function getLabel() {
172 return $this->entity_label;
173 }
174
175 /**
176 * Get a printable label to use a header on the 'value' filter.
177 *
178 * @return string
179 */
180 public function getValueHeader() {
181 return $this->entity_value_label;
182 }
183
184 /**
185 * Get a printable label to use a header on the 'status' filter.
186 *
187 * @return string
188 */
189 public function getStatusHeader() {
190 return $this->entity_status_label;
191 }
50a23755
TO
192
193 /**
194 * Get a list of value options.
195 *
196 * @return array
197 * Array(string $value => string $label).
198 * Ex: array(123 => 'Phone Call', 456 => 'Meeting').
199 */
200 public function getValueLabels() {
201 return self::getValueLabelMap($this->entity_value);
202 }
203
204 /**
205 * Get a list of status options.
206 *
207 * @param string|int $value
208 * The list of status options may be contingent upon the selected filter value.
209 * This is the selected filter value.
210 * @return array
211 * Array(string $value => string $label).
212 * Ex: Array(123 => 'Completed', 456 => 'Scheduled').
213 */
214 public function getStatusLabels($value) {
215 if ($this->entity_status === 'auto_renew_options') {
216 if ($value && \CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipType', $value, 'auto_renew')) {
217 return \CRM_Core_OptionGroup::values('auto_renew_options');
218 }
219 else {
220 return array();
221 }
222 }
223 return self::getValueLabelMap($this->entity_status);
224 }
225
226 /**
546a1ecc
TO
227 * Get a list of available date fields.
228 *
50a23755
TO
229 * @return array
230 * Array(string $fieldName => string $fieldLabel).
231 */
232 public function getDateFields() {
233 $dateFieldLabels = array();
234 if (!empty($this->entity_date_start)) {
235 $dateFieldLabels[$this->entity_date_start] = ucwords(str_replace('_', ' ', $this->entity_date_start));
236 }
237 if (!empty($this->entity_date_end)) {
238 $dateFieldLabels[$this->entity_date_end] = ucwords(str_replace('_', ' ', $this->entity_date_end));
239 }
240 return $dateFieldLabels;
241 }
242
546a1ecc 243 /**
9d97a648
TO
244 * Get a list of recipients which match the given type.
245 *
246 * Note: A single schedule may target *multiple* recipients.
546a1ecc
TO
247 *
248 * @param string $recipientType
9d97a648 249 * Ex: 'participant_role'.
546a1ecc
TO
250 * @return array
251 * Array(mixed $name => string $label).
252 * Ex: array(1 => 'Attendee', 2 => 'Volunteer').
9d97a648 253 * @see getRecipientTypes
546a1ecc 254 */
77e16391
TO
255 public function getRecipientListing($recipientType) {
256 if (!$recipientType) {
257 return array();
258 }
259
260 $options = array();
673c1c81
TO
261 if ($this->entity === 'civicrm_participant' && $recipientType === 'participant_role') {
262 $options = \CRM_Event_PseudoConstant::participantRole();
77e16391
TO
263 }
264 return $options;
265 }
266
50a23755 267 /**
9d97a648
TO
268 * Get a list of recipient types.
269 *
270 * Note: A single schedule may target at most *one* recipient type.
546a1ecc 271 *
50a23755
TO
272 * @return array
273 * array(string $value => string $label).
274 * Ex: array('assignee' => 'Activity Assignee').
275 */
9d97a648 276 public function getRecipientTypes() {
50a23755 277 $entityRecipientLabels = array();
e7712eae
TO
278 switch ($this->entity) {
279 case 'civicrm_activity':
50a23755
TO
280 $entityRecipientLabels = \CRM_Core_OptionGroup::values('activity_contacts');
281 break;
282
e7712eae 283 case 'civicrm_participant':
9d97a648 284 $entityRecipientLabels = \CRM_Core_OptionGroup::values('event_contacts', FALSE, FALSE, FALSE, NULL, 'label', TRUE, FALSE, 'name');
50a23755
TO
285 break;
286
287 default:
288 }
50a23755
TO
289 return $entityRecipientLabels;
290 }
291
77e16391 292
50a23755
TO
293 protected static function getValueLabelMap($name) {
294 static $valueLabelMap = NULL;
295 if ($valueLabelMap === NULL) {
296 $valueLabelMap['activity_type'] = \CRM_Core_PseudoConstant::activityType(TRUE, TRUE);
297 asort($valueLabelMap['activity_type']);
298
299 $valueLabelMap['activity_status'] = \CRM_Core_PseudoConstant::activityStatus();
300 $valueLabelMap['event_type'] = \CRM_Event_PseudoConstant::eventType();
301 $valueLabelMap['civicrm_event'] = \CRM_Event_PseudoConstant::event(NULL, FALSE, "( is_template IS NULL OR is_template != 1 )");
302 $valueLabelMap['civicrm_participant_status_type'] = \CRM_Event_PseudoConstant::participantStatus(NULL, NULL, 'label');
303 $valueLabelMap['event_template'] = \CRM_Event_PseudoConstant::eventTemplates();
304 $valueLabelMap['auto_renew_options'] = \CRM_Core_OptionGroup::values('auto_renew_options');
305 $valueLabelMap['contact_date_reminder_options'] = \CRM_Core_OptionGroup::values('contact_date_reminder_options');
306 $valueLabelMap['civicrm_membership_type'] = \CRM_Member_PseudoConstant::membershipType();
307
308 $allCustomFields = \CRM_Core_BAO_CustomField::getFields('');
309 $dateFields = array(
310 'birth_date' => ts('Birth Date'),
311 'created_date' => ts('Created Date'),
312 'modified_date' => ts('Modified Date'),
313 );
314 foreach ($allCustomFields as $fieldID => $field) {
315 if ($field['data_type'] == 'Date') {
316 $dateFields["custom_$fieldID"] = $field['label'];
317 }
318 }
319 $valueLabelMap['civicrm_contact'] = $dateFields;
320 }
321
322 return $valueLabelMap[$name];
323 }
324
7f0141d8
TO
325 /**
326 * Determine whether a schedule based on this mapping is sufficiently
327 * complete.
328 *
329 * @param \CRM_Core_DAO_ActionSchedule $schedule
330 * @return array
331 * Array (string $code => string $message).
332 * List of error messages.
333 */
334 public function validateSchedule($schedule) {
335 return array();
336 }
337
546a1ecc
TO
338 /**
339 * Generate a query to locate contacts who match the given
340 * schedule.
341 *
342 * @param \CRM_Core_DAO_ActionSchedule $schedule
343 * @param string $phase
344 * See, e.g., RecipientBuilder::PHASE_RELATION_FIRST.
efc40454 345 * @param array $defaultParams
546a1ecc
TO
346 * @return \CRM_Utils_SQL_Select
347 */
efc40454 348 public abstract function createQuery($schedule, $phase, $defaultParams);
546a1ecc 349
50a23755 350}