CRM-13244 - Split prepareMailingQuery() into entity-specific pieces.
[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',
76 'entity_recipient',
77 );
78
79 public static function create($params) {
80 return new static($params);
81 }
82
83 public function __construct($params) {
84 foreach (self::$fields as $field) {
85 if (isset($params[$field])) {
86 $this->{$field} = $params[$field];
87 }
88 }
89 }
90
9e1bf145 91 protected $id;
50a23755
TO
92
93 /**
94 * The basic entity to query (table name).
95 *
96 * @var string
97 * Ex: 'civicrm_activity', 'civicrm_event'.
98 */
9e1bf145 99 protected $entity;
50a23755
TO
100
101 /**
102 * The basic entity to query (label).
103 *
104 * @var
105 * Ex: 'Activity', 'Event'
106 */
9e1bf145 107 private $entity_label;
50a23755
TO
108
109 /**
110 * Level 1 filter -- the field/option-list to filter on.
111 *
112 * @var string
113 * Ex: 'activity_type', 'civicrm_event', 'event_template'.
114 */
77e16391 115 private $entity_value;
50a23755
TO
116
117 /**
118 * Level 1 filter -- The field label.
119 *
120 * @var string
121 * Ex: 'Activity Type', 'Event Name', 'Event Template'.
122 */
9e1bf145 123 private $entity_value_label;
50a23755
TO
124
125 /**
126 * Level 2 filter -- the field/option-list to filter on.
127 * @var string
128 * Ex: 'activity_status, 'civicrm_participant_status_type', 'auto_renew_options'.
129 */
9e1bf145 130 private $entity_status;
50a23755
TO
131
132 /**
133 * Level 2 filter -- the field label.
134 * @var string
135 * Ex: 'Activity Status', 'Participant Status', 'Auto Rewnewal Options'.
136 */
9e1bf145 137 private $entity_status_label;
50a23755
TO
138
139 /**
140 * Date filter -- the field name.
141 * @var string|NULL
142 * Ex: 'event_start_date'
143 */
9e1bf145 144 private $entity_date_start;
50a23755
TO
145
146 /**
147 * Date filter -- the field name.
148 * @var string|NULL
149 * Ex: 'event_end_date'.
150 */
9e1bf145 151 private $entity_date_end;
50a23755
TO
152
153 /**
154 * Contact selector -- The field/relationship/option-group name.
155 * @var string|NULL
156 * Ex: 'activity_contacts', 'event_contacts'.
157 */
9e1bf145
TO
158 protected $entity_recipient;
159
160 /**
161 * @return mixed
162 */
163 public function getId() {
164 return $this->id;
165 }
166
167 /**
168 * @return string
169 */
170 public function getEntity() {
171 return $this->entity;
172 }
173
174 /**
175 * Get a printable label for this mapping type.
176 *
177 * @return string
178 */
179 public function getLabel() {
180 return $this->entity_label;
181 }
182
183 /**
184 * Get a printable label to use a header on the 'value' filter.
185 *
186 * @return string
187 */
188 public function getValueHeader() {
189 return $this->entity_value_label;
190 }
191
192 /**
193 * Get a printable label to use a header on the 'status' filter.
194 *
195 * @return string
196 */
197 public function getStatusHeader() {
198 return $this->entity_status_label;
199 }
50a23755
TO
200
201 /**
202 * Get a list of value options.
203 *
204 * @return array
205 * Array(string $value => string $label).
206 * Ex: array(123 => 'Phone Call', 456 => 'Meeting').
207 */
208 public function getValueLabels() {
209 return self::getValueLabelMap($this->entity_value);
210 }
211
212 /**
213 * Get a list of status options.
214 *
215 * @param string|int $value
216 * The list of status options may be contingent upon the selected filter value.
217 * This is the selected filter value.
218 * @return array
219 * Array(string $value => string $label).
220 * Ex: Array(123 => 'Completed', 456 => 'Scheduled').
221 */
222 public function getStatusLabels($value) {
223 if ($this->entity_status === 'auto_renew_options') {
224 if ($value && \CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipType', $value, 'auto_renew')) {
225 return \CRM_Core_OptionGroup::values('auto_renew_options');
226 }
227 else {
228 return array();
229 }
230 }
231 return self::getValueLabelMap($this->entity_status);
232 }
233
234 /**
546a1ecc
TO
235 * Get a list of available date fields.
236 *
50a23755
TO
237 * @return array
238 * Array(string $fieldName => string $fieldLabel).
239 */
240 public function getDateFields() {
241 $dateFieldLabels = array();
242 if (!empty($this->entity_date_start)) {
243 $dateFieldLabels[$this->entity_date_start] = ucwords(str_replace('_', ' ', $this->entity_date_start));
244 }
245 if (!empty($this->entity_date_end)) {
246 $dateFieldLabels[$this->entity_date_end] = ucwords(str_replace('_', ' ', $this->entity_date_end));
247 }
248 return $dateFieldLabels;
249 }
250
546a1ecc
TO
251 /**
252 * Unsure. Not sure how it differs from getRecipientTypes... but it does...
253 *
254 * @param string $recipientType
255 * @return array
256 * Array(mixed $name => string $label).
257 * Ex: array(1 => 'Attendee', 2 => 'Volunteer').
258 */
77e16391
TO
259 public function getRecipientListing($recipientType) {
260 if (!$recipientType) {
261 return array();
262 }
263
264 $options = array();
265 switch ($this->entity) {
266 case 'civicrm_participant':
267 $eventContacts = \CRM_Core_OptionGroup::values('event_contacts', FALSE, FALSE, FALSE, NULL, 'name', TRUE, FALSE, 'name');
268 if (!empty($eventContacts[$recipientType]) && $eventContacts[$recipientType] == 'participant_role') {
269 $options = \CRM_Event_PseudoConstant::participantRole();
270 }
271 break;
272 }
273 return $options;
274 }
275
50a23755 276 /**
546a1ecc
TO
277 * Unsure. Not sure how it differs from getRecipientListing... but it does...
278 *
50a23755
TO
279 * @param bool|NULL $noThanksJustKidding
280 * This is ridiculous and should not exist.
281 * If true, don't do our main job.
282 * @return array
283 * array(string $value => string $label).
284 * Ex: array('assignee' => 'Activity Assignee').
285 */
286 public function getRecipientTypes($noThanksJustKidding = FALSE) {
287 $entityRecipientLabels = array();
288 switch ($this->entity_recipient) {
289 case 'activity_contacts':
290 $entityRecipientLabels = \CRM_Core_OptionGroup::values('activity_contacts');
291 break;
292
293 case 'event_contacts':
294 if (!$noThanksJustKidding) {
295 $entityRecipientLabels = \CRM_Core_OptionGroup::values('event_contacts', FALSE, FALSE, FALSE, NULL, 'label', TRUE, FALSE, 'name');
296 }
297 break;
298
299 default:
300 }
301 $entityRecipientLabels += array(
302 'manual' => ts('Choose Recipient(s)'),
303 'group' => ts('Select Group'),
304 );
305 return $entityRecipientLabels;
306 }
307
77e16391 308
50a23755
TO
309 protected static function getValueLabelMap($name) {
310 static $valueLabelMap = NULL;
311 if ($valueLabelMap === NULL) {
312 $valueLabelMap['activity_type'] = \CRM_Core_PseudoConstant::activityType(TRUE, TRUE);
313 asort($valueLabelMap['activity_type']);
314
315 $valueLabelMap['activity_status'] = \CRM_Core_PseudoConstant::activityStatus();
316 $valueLabelMap['event_type'] = \CRM_Event_PseudoConstant::eventType();
317 $valueLabelMap['civicrm_event'] = \CRM_Event_PseudoConstant::event(NULL, FALSE, "( is_template IS NULL OR is_template != 1 )");
318 $valueLabelMap['civicrm_participant_status_type'] = \CRM_Event_PseudoConstant::participantStatus(NULL, NULL, 'label');
319 $valueLabelMap['event_template'] = \CRM_Event_PseudoConstant::eventTemplates();
320 $valueLabelMap['auto_renew_options'] = \CRM_Core_OptionGroup::values('auto_renew_options');
321 $valueLabelMap['contact_date_reminder_options'] = \CRM_Core_OptionGroup::values('contact_date_reminder_options');
322 $valueLabelMap['civicrm_membership_type'] = \CRM_Member_PseudoConstant::membershipType();
323
324 $allCustomFields = \CRM_Core_BAO_CustomField::getFields('');
325 $dateFields = array(
326 'birth_date' => ts('Birth Date'),
327 'created_date' => ts('Created Date'),
328 'modified_date' => ts('Modified Date'),
329 );
330 foreach ($allCustomFields as $fieldID => $field) {
331 if ($field['data_type'] == 'Date') {
332 $dateFields["custom_$fieldID"] = $field['label'];
333 }
334 }
335 $valueLabelMap['civicrm_contact'] = $dateFields;
336 }
337
338 return $valueLabelMap[$name];
339 }
340
546a1ecc
TO
341 /**
342 * Generate a query to locate contacts who match the given
343 * schedule.
344 *
345 * @param \CRM_Core_DAO_ActionSchedule $schedule
346 * @param string $phase
347 * See, e.g., RecipientBuilder::PHASE_RELATION_FIRST.
efc40454 348 * @param array $defaultParams
546a1ecc
TO
349 * @return \CRM_Utils_SQL_Select
350 */
efc40454 351 public abstract function createQuery($schedule, $phase, $defaultParams);
546a1ecc 352
50a23755 353}