Merge pull request #13023 from eileenmcnaughton/mailing_settings
[civicrm-core.git] / Civi / ActionSchedule / Mapping.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 5 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2018 |
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
28 namespace Civi\ActionSchedule;
29
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 *
57 * This "Mapping" implementation is a refactoring of the old
58 * hard-coded bits. Internally, it uses the concepts from
59 * "civicrm_action_mapping". The resulting code is more
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).
63 */
64 abstract class Mapping implements MappingInterface {
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 );
77
78 /**
79 * Create mapping.
80 *
81 * @param array $params
82 *
83 * @return static
84 */
85 public static function create($params) {
86 return new static($params);
87 }
88
89 /**
90 * Class constructor.
91 *
92 * @param array $params
93 */
94 public function __construct($params) {
95 foreach (self::$fields as $field) {
96 if (isset($params[$field])) {
97 $this->{$field} = $params[$field];
98 }
99 }
100 }
101
102 protected $id;
103
104 /**
105 * The basic entity to query (table name).
106 *
107 * @var string
108 * Ex: 'civicrm_activity', 'civicrm_event'.
109 */
110 protected $entity;
111
112 /**
113 * The basic entity to query (label).
114 *
115 * @var
116 * Ex: 'Activity', 'Event'
117 */
118 private $entity_label;
119
120 /**
121 * Level 1 filter -- the field/option-list to filter on.
122 *
123 * @var string
124 * Ex: 'activity_type', 'civicrm_event', 'event_template'.
125 */
126 private $entity_value;
127
128 /**
129 * Level 1 filter -- The field label.
130 *
131 * @var string
132 * Ex: 'Activity Type', 'Event Name', 'Event Template'.
133 */
134 private $entity_value_label;
135
136 /**
137 * Level 2 filter -- the field/option-list to filter on.
138 * @var string
139 * Ex: 'activity_status, 'civicrm_participant_status_type', 'auto_renew_options'.
140 */
141 private $entity_status;
142
143 /**
144 * Level 2 filter -- the field label.
145 * @var string
146 * Ex: 'Activity Status', 'Participant Status', 'Auto Rewnewal Options'.
147 */
148 private $entity_status_label;
149
150 /**
151 * Date filter -- the field name.
152 * @var string|NULL
153 * Ex: 'event_start_date'
154 */
155 private $entity_date_start;
156
157 /**
158 * Date filter -- the field name.
159 * @var string|NULL
160 * Ex: 'event_end_date'.
161 */
162 private $entity_date_end;
163
164 /**
165 * @return mixed
166 */
167 public function getId() {
168 return $this->id;
169 }
170
171 /**
172 * @return string
173 */
174 public function getEntity() {
175 return $this->entity;
176 }
177
178 /**
179 * Get a printable label for this mapping type.
180 *
181 * @return string
182 */
183 public function getLabel() {
184 return $this->entity_label;
185 }
186
187 /**
188 * Get a printable label to use a header on the 'value' filter.
189 *
190 * @return string
191 */
192 public function getValueHeader() {
193 return $this->entity_value_label;
194 }
195
196 /**
197 * Get a printable label to use a header on the 'status' filter.
198 *
199 * @return string
200 */
201 public function getStatusHeader() {
202 return $this->entity_status_label;
203 }
204
205 /**
206 * Get a list of value options.
207 *
208 * @return array
209 * Array(string $value => string $label).
210 * Ex: array(123 => 'Phone Call', 456 => 'Meeting').
211 */
212 public function getValueLabels() {
213 return self::getValueLabelMap($this->entity_value);
214 }
215
216 /**
217 * Get a list of status options.
218 *
219 * @param string|int $value
220 * The list of status options may be contingent upon the selected filter value.
221 * This is the selected filter value.
222 * @return array
223 * Array(string $value => string $label).
224 * Ex: Array(123 => 'Completed', 456 => 'Scheduled').
225 */
226 public function getStatusLabels($value) {
227 if ($this->entity_status === 'auto_renew_options') {
228 if ($value && \CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipType', $value, 'auto_renew')) {
229 return \CRM_Core_OptionGroup::values('auto_renew_options');
230 }
231 else {
232 return array();
233 }
234 }
235 return self::getValueLabelMap($this->entity_status);
236 }
237
238 /**
239 * Get a list of available date fields.
240 *
241 * @return array
242 * Array(string $fieldName => string $fieldLabel).
243 */
244 public function getDateFields() {
245 $dateFieldLabels = array();
246 if (!empty($this->entity_date_start)) {
247 $dateFieldLabels[$this->entity_date_start] = ucwords(str_replace('_', ' ', $this->entity_date_start));
248 }
249 if (!empty($this->entity_date_end)) {
250 $dateFieldLabels[$this->entity_date_end] = ucwords(str_replace('_', ' ', $this->entity_date_end));
251 }
252 return $dateFieldLabels;
253 }
254
255 /**
256 * Get a list of recipient types.
257 *
258 * Note: A single schedule may filter on *zero* or *one* recipient types.
259 * When an admin chooses a value, it's stored in $schedule->recipient.
260 *
261 * @return array
262 * array(string $value => string $label).
263 * Ex: array('assignee' => 'Activity Assignee').
264 */
265 public function getRecipientTypes() {
266 return array();
267 }
268
269 /**
270 * Get a list of recipients which match the given type.
271 *
272 * Note: A single schedule may filter on *multiple* recipients.
273 * When an admin chooses value(s), it's stored in $schedule->recipient_listing.
274 *
275 * @param string $recipientType
276 * Ex: 'participant_role'.
277 * @return array
278 * Array(mixed $name => string $label).
279 * Ex: array(1 => 'Attendee', 2 => 'Volunteer').
280 * @see getRecipientTypes
281 */
282 public function getRecipientListing($recipientType) {
283 return array();
284 }
285
286 protected static function getValueLabelMap($name) {
287 static $valueLabelMap = NULL;
288 if ($valueLabelMap === NULL) {
289 // CRM-20510: Include CiviCampaign activity types along with CiviCase IF component is enabled
290 $valueLabelMap['activity_type'] = \CRM_Core_PseudoConstant::activityType(TRUE, TRUE, FALSE, 'label', TRUE);
291 asort($valueLabelMap['activity_type']);
292
293 $valueLabelMap['activity_status'] = \CRM_Core_PseudoConstant::activityStatus();
294 $valueLabelMap['event_type'] = \CRM_Event_PseudoConstant::eventType();
295 $valueLabelMap['civicrm_event'] = \CRM_Event_PseudoConstant::event(NULL, FALSE, "( is_template IS NULL OR is_template != 1 )");
296 $valueLabelMap['civicrm_participant_status_type'] = \CRM_Event_PseudoConstant::participantStatus(NULL, NULL, 'label');
297 $valueLabelMap['event_template'] = \CRM_Event_PseudoConstant::eventTemplates();
298 $valueLabelMap['auto_renew_options'] = \CRM_Core_OptionGroup::values('auto_renew_options');
299 $valueLabelMap['contact_date_reminder_options'] = \CRM_Core_OptionGroup::values('contact_date_reminder_options');
300 $valueLabelMap['civicrm_membership_type'] = \CRM_Member_PseudoConstant::membershipType();
301
302 $allCustomFields = \CRM_Core_BAO_CustomField::getFields('');
303 $dateFields = array(
304 'birth_date' => ts('Birth Date'),
305 'created_date' => ts('Created Date'),
306 'modified_date' => ts('Modified Date'),
307 );
308 foreach ($allCustomFields as $fieldID => $field) {
309 if ($field['data_type'] == 'Date') {
310 $dateFields["custom_$fieldID"] = $field['label'];
311 }
312 }
313 $valueLabelMap['civicrm_contact'] = $dateFields;
314 }
315
316 return $valueLabelMap[$name];
317 }
318
319 /**
320 * Determine whether a schedule based on this mapping is sufficiently
321 * complete.
322 *
323 * @param \CRM_Core_DAO_ActionSchedule $schedule
324 * @return array
325 * Array (string $code => string $message).
326 * List of error messages.
327 */
328 public function validateSchedule($schedule) {
329 return array();
330 }
331
332 /**
333 * Generate a query to locate contacts who match the given
334 * schedule.
335 *
336 * @param \CRM_Core_DAO_ActionSchedule $schedule
337 * @param string $phase
338 * See, e.g., RecipientBuilder::PHASE_RELATION_FIRST.
339 * @param array $defaultParams
340 * @return \CRM_Utils_SQL_Select
341 */
342 public abstract function createQuery($schedule, $phase, $defaultParams);
343
344 }