Update Unit test styling to cover the future coder version
[civicrm-core.git] / tests / phpunit / CRM / Core / BAO / ActionScheduleTest.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
2fe49090 4 | CiviCRM version 5 |
6a488035 5 +--------------------------------------------------------------------+
6b83d5bd 6 | Copyright CiviCRM LLC (c) 2004-2019 |
6a488035
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 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035 27
e9479dcf
EM
28/**
29 * Class CRM_Core_BAO_ActionScheduleTest
2a21d018 30 * @group ActionSchedule
acb109b7 31 * @group headless
2a21d018
TO
32 *
33 * There are additional tests for some specific entities in other classes:
34 * @see CRM_Activity_ActionMappingTest
35 * @see CRM_Contribute_ActionMapping_ByTypeTest
e9479dcf 36 */
6a488035 37class CRM_Core_BAO_ActionScheduleTest extends CiviUnitTestCase {
63e9c3fd 38
6a488035 39 /**
f8c3594b 40 * @var CiviMailUtils
6a488035 41 */
567b2076 42 public $mut;
cee19268 43
00be9182 44 public function setUp() {
6a488035
TO
45 parent::setUp();
46
6c6e6187 47 $this->mut = new CiviMailUtils($this, TRUE);
6a488035 48
57507ae6 49 $this->fixtures['rolling_membership'] = array(
6a488035
TO
50 'membership_type_id' => array(
51 'period_type' => 'rolling',
52 'duration_unit' => 'month',
53 'duration_interval' => '3',
54 'is_active' => 1,
55 ),
56 'join_date' => '20120315',
57 'start_date' => '20120315',
58 'end_date' => '20120615',
b29be8c2 59 'is_override' => 0,
6a488035 60 );
4b1efa1d 61
63e9c3fd 62 $this->fixtures['rolling_membership_past'] = array(
4b1efa1d 63 'membership_type_id' => array(
64 'period_type' => 'rolling',
65 'duration_unit' => 'month',
66 'duration_interval' => '3',
67 'is_active' => 1,
68 ),
69 'join_date' => '20100310',
70 'start_date' => '20100310',
71 'end_date' => '20100610',
72 'is_override' => 'NULL',
73 );
d3eae6ea
TO
74 $this->fixtures['participant'] = array(
75 'event_id' => array(
76 'is_active' => 1,
77 'is_template' => 0,
78 'title' => 'Example Event',
79 'start_date' => '20120315',
80 'end_date' => '20120615',
81 ),
39b959db
SL
82 // Attendee.
83 'role_id' => '1',
84 // No-show.
85 'status_id' => '8',
d3eae6ea 86 );
fe265b4e 87
db7de9c1 88 $this->fixtures['phonecall'] = array(
6a488035
TO
89 'status_id' => 1,
90 'activity_type_id' => 2,
91 'activity_date_time' => '20120615100000',
92 'is_current_revision' => 1,
93 'is_deleted' => 0,
94 );
db7de9c1 95 $this->fixtures['contact'] = array(
b29be8c2 96 'is_deceased' => 0,
6a488035
TO
97 'contact_type' => 'Individual',
98 'email' => 'test-member@example.com',
43ceab3f 99 'gender_id' => 'Female',
bba4f3f6
CB
100 'first_name' => 'Churmondleia',
101 'last_name' => 'Ōtākou',
6a488035 102 );
db7de9c1 103 $this->fixtures['contact_birthdate'] = array(
43030baf
AH
104 'is_deceased' => 0,
105 'contact_type' => 'Individual',
106 'email' => 'test-bday@example.com',
107 'birth_date' => '20050707',
108 );
db7de9c1 109 $this->fixtures['sched_activity_1day'] = array(
6a488035
TO
110 'name' => 'One_Day_Phone_Call_Notice',
111 'title' => 'One Day Phone Call Notice',
84a3e359 112 'limit_to' => '1',
6a488035 113 'absolute_date' => NULL,
d19632b1
JP
114 'body_html' => '<p>1-Day (non-repeating) (for {activity.subject})</p>',
115 'body_text' => '1-Day (non-repeating) (for {activity.subject})',
6a488035
TO
116 'end_action' => NULL,
117 'end_date' => NULL,
118 'end_frequency_interval' => NULL,
119 'end_frequency_unit' => NULL,
120 'entity_status' => '1',
121 'entity_value' => '2',
122 'group_id' => NULL,
123 'is_active' => '1',
124 'is_repeat' => '0',
125 'mapping_id' => '1',
126 'msg_template_id' => NULL,
127 'recipient' => '2',
128 'recipient_listing' => NULL,
129 'recipient_manual' => NULL,
d19632b1 130 'record_activity' => 1,
6a488035
TO
131 'repetition_frequency_interval' => NULL,
132 'repetition_frequency_unit' => NULL,
133 'start_action_condition' => 'before',
134 'start_action_date' => 'activity_date_time',
135 'start_action_offset' => '1',
136 'start_action_unit' => 'day',
f8c3594b 137 'subject' => '1-Day (non-repeating) (about {activity.activity_type})',
6a488035
TO
138 );
139 $this->fixtures['sched_activity_1day_r'] = array(
140 'name' => 'One_Day_Phone_Call_Notice_R',
141 'title' => 'One Day Phone Call Notice R',
84a3e359 142 'limit_to' => 1,
6a488035
TO
143 'absolute_date' => NULL,
144 'body_html' => '<p>1-Day (repeating)</p>',
145 'body_text' => '1-Day (repeating)',
146 'end_action' => 'after',
147 'end_date' => 'activity_date_time',
148 'end_frequency_interval' => '2',
149 'end_frequency_unit' => 'day',
150 'entity_status' => '1',
151 'entity_value' => '2',
152 'group_id' => NULL,
153 'is_active' => '1',
154 'is_repeat' => '1',
155 'mapping_id' => '1',
156 'msg_template_id' => NULL,
157 'recipient' => '2',
158 'recipient_listing' => NULL,
159 'recipient_manual' => NULL,
160 'record_activity' => NULL,
161 'repetition_frequency_interval' => '6',
162 'repetition_frequency_unit' => 'hour',
163 'start_action_condition' => 'before',
164 'start_action_date' => 'activity_date_time',
165 'start_action_offset' => '1',
166 'start_action_unit' => 'day',
f8c3594b 167 'subject' => '1-Day (repeating) (about {activity.activity_type})',
6a488035 168 );
dc6c330d 169 $this->fixtures['sched_activity_1day_r_on_abs_date'] = array(
170 'name' => 'One_Day_Phone_Call_Notice_R',
171 'title' => 'One Day Phone Call Notice R',
172 'limit_to' => 1,
173 'absolute_date' => CRM_Utils_Date::processDate('20120614100000'),
174 'body_html' => '<p>1-Day (repeating)</p>',
175 'body_text' => '1-Day (repeating)',
176 'entity_status' => '1',
177 'entity_value' => '2',
178 'group_id' => NULL,
179 'is_active' => '1',
180 'is_repeat' => '1',
181 'mapping_id' => '1',
182 'msg_template_id' => NULL,
183 'recipient' => '2',
184 'recipient_listing' => NULL,
185 'recipient_manual' => NULL,
186 'record_activity' => NULL,
187 'repetition_frequency_interval' => '6',
188 'repetition_frequency_unit' => 'hour',
189 'end_action' => 'after',
190 'end_date' => 'activity_date_time',
191 'end_frequency_interval' => '2',
192 'end_frequency_unit' => 'day',
193 'start_action_condition' => '',
194 'start_action_date' => '',
195 'start_action_offset' => '',
196 'start_action_unit' => '',
197 'subject' => '1-Day (repeating) (about {activity.activity_type})',
198 );
567b2076 199 $this->fixtures['sched_membership_join_2week'] = array(
6a488035
TO
200 'name' => 'sched_membership_join_2week',
201 'title' => 'sched_membership_join_2week',
202 'absolute_date' => '',
203 'body_html' => '<p>body sched_membership_join_2week</p>',
204 'body_text' => 'body sched_membership_join_2week',
205 'end_action' => '',
206 'end_date' => '',
207 'end_frequency_interval' => '',
208 'end_frequency_unit' => '',
209 'entity_status' => '',
210 'entity_value' => '',
211 'group_id' => '',
212 'is_active' => 1,
213 'is_repeat' => '0',
214 'mapping_id' => 4,
215 'msg_template_id' => '',
216 'recipient' => '',
217 'recipient_listing' => '',
218 'recipient_manual' => '',
219 'record_activity' => 1,
220 'repetition_frequency_interval' => '',
221 'repetition_frequency_unit' => '',
222 'start_action_condition' => 'after',
223 'start_action_date' => 'membership_join_date',
224 'start_action_offset' => '2',
225 'start_action_unit' => 'week',
f8c3594b 226 'subject' => 'subject sched_membership_join_2week (joined {membership.join_date})',
6a488035 227 );
bb3ba83e
AH
228 $this->fixtures['sched_membership_start_1week'] = array(
229 'name' => 'sched_membership_start_1week',
230 'title' => 'sched_membership_start_1week',
231 'absolute_date' => '',
232 'body_html' => '<p>body sched_membership_start_1week</p>',
233 'body_text' => 'body sched_membership_start_1week',
234 'end_action' => '',
235 'end_date' => '',
236 'end_frequency_interval' => '',
237 'end_frequency_unit' => '',
238 'entity_status' => '',
239 'entity_value' => '',
240 'group_id' => '',
241 'is_active' => 1,
242 'is_repeat' => '0',
243 'mapping_id' => 4,
244 'msg_template_id' => '',
245 'recipient' => '',
246 'recipient_listing' => '',
247 'recipient_manual' => '',
248 'record_activity' => 1,
249 'repetition_frequency_interval' => '',
250 'repetition_frequency_unit' => '',
251 'start_action_condition' => 'after',
252 'start_action_date' => 'membership_start_date',
253 'start_action_offset' => '1',
254 'start_action_unit' => 'week',
255 'subject' => 'subject sched_membership_start_1week (joined {membership.start_date})',
256 );
567b2076 257 $this->fixtures['sched_membership_end_2week'] = array(
6a488035
TO
258 'name' => 'sched_membership_end_2week',
259 'title' => 'sched_membership_end_2week',
260 'absolute_date' => '',
261 'body_html' => '<p>body sched_membership_end_2week</p>',
262 'body_text' => 'body sched_membership_end_2week',
263 'end_action' => '',
264 'end_date' => '',
265 'end_frequency_interval' => '',
266 'end_frequency_unit' => '',
267 'entity_status' => '',
268 'entity_value' => '',
269 'group_id' => '',
270 'is_active' => 1,
271 'is_repeat' => '0',
272 'mapping_id' => 4,
273 'msg_template_id' => '',
274 'recipient' => '',
275 'recipient_listing' => '',
276 'recipient_manual' => '',
277 'record_activity' => 1,
278 'repetition_frequency_interval' => '',
279 'repetition_frequency_unit' => '',
280 'start_action_condition' => 'before',
281 'start_action_date' => 'membership_end_date',
282 'start_action_offset' => '2',
283 'start_action_unit' => 'week',
284 'subject' => 'subject sched_membership_end_2week',
285 );
cbcb7579 286 $this->fixtures['sched_on_membership_end_date'] = array(
d2868251 287 'name' => 'sched_on_membership_end_date',
288 'title' => 'sched_on_membership_end_date',
289 'body_html' => '<p>Your membership expired today</p>',
290 'body_text' => 'Your membership expired today',
291 'is_active' => 1,
292 'mapping_id' => 4,
293 'record_activity' => 1,
294 'start_action_condition' => 'after',
295 'start_action_date' => 'membership_end_date',
296 'start_action_offset' => '0',
297 'start_action_unit' => 'hour',
298 'subject' => 'subject send reminder on membership_end_date',
299 );
cbcb7579 300 $this->fixtures['sched_after_1day_membership_end_date'] = array(
d2868251 301 'name' => 'sched_after_1day_membership_end_date',
302 'title' => 'sched_after_1day_membership_end_date',
303 'body_html' => '<p>Your membership expired yesterday</p>',
304 'body_text' => 'Your membership expired yesterday',
305 'is_active' => 1,
306 'mapping_id' => 4,
307 'record_activity' => 1,
308 'start_action_condition' => 'after',
309 'start_action_date' => 'membership_end_date',
310 'start_action_offset' => '1',
311 'start_action_unit' => 'day',
312 'subject' => 'subject send reminder on membership_end_date',
313 );
4b1efa1d 314
567b2076 315 $this->fixtures['sched_membership_end_2month'] = array(
4b1efa1d 316 'name' => 'sched_membership_end_2month',
317 'title' => 'sched_membership_end_2month',
318 'absolute_date' => '',
319 'body_html' => '<p>body sched_membership_end_2month</p>',
320 'body_text' => 'body sched_membership_end_2month',
321 'end_action' => '',
322 'end_date' => '',
323 'end_frequency_interval' => '',
324 'end_frequency_unit' => '',
325 'entity_status' => '',
326 'entity_value' => '',
327 'group_id' => '',
328 'is_active' => 1,
329 'is_repeat' => '0',
330 'mapping_id' => 4,
331 'msg_template_id' => '',
332 'recipient' => '',
333 'recipient_listing' => '',
334 'recipient_manual' => '',
335 'record_activity' => 1,
336 'repetition_frequency_interval' => '',
337 'repetition_frequency_unit' => '',
338 'start_action_condition' => 'after',
339 'start_action_date' => 'membership_end_date',
340 'start_action_offset' => '2',
341 'start_action_unit' => 'month',
342 'subject' => 'subject sched_membership_end_2month',
343 );
344
567b2076 345 $this->fixtures['sched_contact_bday_yesterday'] = array(
43030baf
AH
346 'name' => 'sched_contact_bday_yesterday',
347 'title' => 'sched_contact_bday_yesterday',
348 'absolute_date' => '',
349 'body_html' => '<p>you look like you were born yesterday!</p>',
350 'body_text' => 'you look like you were born yesterday!',
351 'end_action' => '',
352 'end_date' => '',
353 'end_frequency_interval' => '',
354 'end_frequency_unit' => '',
355 'entity_status' => 1,
356 'entity_value' => 'birth_date',
357 'group_id' => '',
358 'is_active' => 1,
359 'is_repeat' => '0',
360 'mapping_id' => 6,
361 'msg_template_id' => '',
362 'recipient' => '',
363 'recipient_listing' => '',
364 'recipient_manual' => '',
365 'record_activity' => 1,
366 'repetition_frequency_interval' => '',
367 'repetition_frequency_unit' => '',
368 'start_action_condition' => 'after',
369 'start_action_date' => 'date_field',
370 'start_action_offset' => '1',
371 'start_action_unit' => 'day',
372 'subject' => 'subject sched_contact_bday_yesterday',
373 );
374
567b2076 375 $this->fixtures['sched_contact_bday_anniv'] = array(
43030baf
AH
376 'name' => 'sched_contact_bday_anniv',
377 'title' => 'sched_contact_bday_anniv',
378 'absolute_date' => '',
379 'body_html' => '<p>happy birthday!</p>',
380 'body_text' => 'happy birthday!',
381 'end_action' => '',
382 'end_date' => '',
383 'end_frequency_interval' => '',
384 'end_frequency_unit' => '',
385 'entity_status' => 2,
386 'entity_value' => 'birth_date',
387 'group_id' => '',
388 'is_active' => 1,
389 'is_repeat' => '0',
390 'mapping_id' => 6,
391 'msg_template_id' => '',
392 'recipient' => '',
393 'recipient_listing' => '',
394 'recipient_manual' => '',
395 'record_activity' => 1,
396 'repetition_frequency_interval' => '',
397 'repetition_frequency_unit' => '',
398 'start_action_condition' => 'before',
399 'start_action_date' => 'date_field',
400 'start_action_offset' => '1',
401 'start_action_unit' => 'day',
402 'subject' => 'subject sched_contact_bday_anniv',
403 );
404
567b2076 405 $this->fixtures['sched_contact_grad_tomorrow'] = array(
43030baf
AH
406 'name' => 'sched_contact_grad_tomorrow',
407 'title' => 'sched_contact_grad_tomorrow',
408 'absolute_date' => '',
409 'body_html' => '<p>congratulations on your graduation!</p>',
410 'body_text' => 'congratulations on your graduation!',
411 'end_action' => '',
412 'end_date' => '',
413 'end_frequency_interval' => '',
414 'end_frequency_unit' => '',
415 'entity_status' => 1,
416 'group_id' => '',
417 'is_active' => 1,
418 'is_repeat' => '0',
419 'mapping_id' => 6,
420 'msg_template_id' => '',
421 'recipient' => '',
422 'recipient_listing' => '',
423 'recipient_manual' => '',
424 'record_activity' => 1,
425 'repetition_frequency_interval' => '',
426 'repetition_frequency_unit' => '',
427 'start_action_condition' => 'before',
428 'start_action_date' => 'date_field',
429 'start_action_offset' => '1',
430 'start_action_unit' => 'day',
431 'subject' => 'subject sched_contact_grad_tomorrow',
432 );
433
567b2076 434 $this->fixtures['sched_contact_grad_anniv'] = array(
43030baf
AH
435 'name' => 'sched_contact_grad_anniv',
436 'title' => 'sched_contact_grad_anniv',
437 'absolute_date' => '',
438 'body_html' => '<p>dear alum, please send us money.</p>',
439 'body_text' => 'dear alum, please send us money.',
440 'end_action' => '',
441 'end_date' => '',
442 'end_frequency_interval' => '',
443 'end_frequency_unit' => '',
444 'entity_status' => 2,
445 'group_id' => '',
446 'is_active' => 1,
447 'is_repeat' => '0',
448 'mapping_id' => 6,
449 'msg_template_id' => '',
450 'recipient' => '',
451 'recipient_listing' => '',
452 'recipient_manual' => '',
453 'record_activity' => 1,
454 'repetition_frequency_interval' => '',
455 'repetition_frequency_unit' => '',
456 'start_action_condition' => 'after',
457 'start_action_date' => 'date_field',
458 'start_action_offset' => '1',
459 'start_action_unit' => 'week',
460 'subject' => 'subject sched_contact_grad_anniv',
461 );
4aff0253
AH
462
463 $this->fixtures['sched_contact_created_yesterday'] = array(
464 'name' => 'sched_contact_created_yesterday',
465 'title' => 'sched_contact_created_yesterday',
466 'absolute_date' => '',
467 'body_html' => '<p>Your contact was created yesterday</p>',
468 'body_text' => 'Your contact was created yesterday!',
469 'end_action' => '',
470 'end_date' => '',
471 'end_frequency_interval' => '',
472 'end_frequency_unit' => '',
473 'entity_status' => 1,
474 'entity_value' => 'created_date',
475 'group_id' => '',
476 'is_active' => 1,
477 'is_repeat' => '0',
478 'mapping_id' => 6,
479 'msg_template_id' => '',
480 'recipient' => '',
481 'recipient_listing' => '',
482 'recipient_manual' => '',
483 'record_activity' => 1,
484 'repetition_frequency_interval' => '',
485 'repetition_frequency_unit' => '',
486 'start_action_condition' => 'after',
487 'start_action_date' => 'date_field',
488 'start_action_offset' => '1',
489 'start_action_unit' => 'day',
490 'subject' => 'subject sched_contact_created_yesterday',
491 );
492
493 $this->fixtures['sched_contact_mod_anniv'] = array(
494 'name' => 'sched_contact_mod_anniv',
495 'title' => 'sched_contact_mod_anniv',
496 'absolute_date' => '',
497 'body_html' => '<p>You last updated your data last year</p>',
498 'body_text' => 'Go update your stuff!',
499 'end_action' => '',
500 'end_date' => '',
501 'end_frequency_interval' => '',
502 'end_frequency_unit' => '',
503 'entity_status' => 2,
504 'entity_value' => 'modified_date',
505 'group_id' => '',
506 'is_active' => 1,
507 'is_repeat' => '0',
508 'mapping_id' => 6,
509 'msg_template_id' => '',
510 'recipient' => '',
511 'recipient_listing' => '',
512 'recipient_manual' => '',
513 'record_activity' => 1,
514 'repetition_frequency_interval' => '',
515 'repetition_frequency_unit' => '',
516 'start_action_condition' => 'before',
517 'start_action_date' => 'date_field',
518 'start_action_offset' => '1',
519 'start_action_unit' => 'day',
520 'subject' => 'subject sched_contact_mod_anniv',
521 );
522
d3eae6ea
TO
523 $this->fixtures['sched_eventtype_start_1week_before'] = array(
524 'name' => 'sched_eventtype_start_1week_before',
525 'title' => 'sched_eventtype_start_1week_before',
526 'absolute_date' => '',
527 'body_html' => '<p>body sched_eventtype_start_1week_before ({event.title})</p>',
528 'body_text' => 'body sched_eventtype_start_1week_before ({event.title})',
529 'end_action' => '',
530 'end_date' => '',
531 'end_frequency_interval' => '',
532 'end_frequency_unit' => '',
39b959db
SL
533 // participant status id
534 'entity_status' => '',
535 // event type id
536 'entity_value' => '',
d3eae6ea
TO
537 'group_id' => '',
538 'is_active' => 1,
539 'is_repeat' => '0',
39b959db
SL
540 // event type
541 'mapping_id' => 2,
d3eae6ea
TO
542 'msg_template_id' => '',
543 'recipient' => '',
544 'recipient_listing' => '',
545 'recipient_manual' => '',
546 'record_activity' => 1,
547 'repetition_frequency_interval' => '',
548 'repetition_frequency_unit' => '',
549 'start_action_condition' => 'before',
550 'start_action_date' => 'event_start_date',
551 'start_action_offset' => '1',
552 'start_action_unit' => 'week',
553 'subject' => 'subject sched_eventtype_start_1week_before ({event.title})',
554 );
555 $this->fixtures['sched_eventtype_end_2month_repeat_twice_2_weeks'] = array(
556 'name' => 'sched_eventtype_end_2month_repeat_twice_2_weeks',
557 'title' => 'sched_eventtype_end_2month_repeat_twice_2_weeks',
558 'absolute_date' => '',
559 'body_html' => '<p>body sched_eventtype_end_2month_repeat_twice_2_weeks {event.title}</p>',
560 'body_text' => 'body sched_eventtype_end_2month_repeat_twice_2_weeks {event.title}',
561 'end_action' => 'after',
562 'end_date' => 'event_end_date',
563 'end_frequency_interval' => '3',
564 'end_frequency_unit' => 'month',
39b959db
SL
565 // participant status id
566 'entity_status' => '',
567 // event type id
568 'entity_value' => '',
d3eae6ea
TO
569 'group_id' => '',
570 'is_active' => 1,
571 'is_repeat' => '1',
39b959db
SL
572 // event type
573 'mapping_id' => 2,
d3eae6ea
TO
574 'msg_template_id' => '',
575 'recipient' => '',
576 'recipient_listing' => '',
577 'recipient_manual' => '',
578 'record_activity' => 1,
579 'repetition_frequency_interval' => '2',
580 'repetition_frequency_unit' => 'week',
581 'start_action_condition' => 'after',
582 'start_action_date' => 'event_end_date',
583 'start_action_offset' => '2',
584 'start_action_unit' => 'month',
585 'subject' => 'subject sched_eventtype_end_2month_repeat_twice_2_weeks {event.title}',
586 );
587
567b2076 588 $this->fixtures['sched_membership_end_2month_repeat_twice_4_weeks'] = array(
861d11c4
DG
589 'name' => 'sched_membership_end_2month',
590 'title' => 'sched_membership_end_2month',
591 'absolute_date' => '',
592 'body_html' => '<p>body sched_membership_end_2month</p>',
593 'body_text' => 'body sched_membership_end_2month',
594 'end_action' => '',
5c4d6559 595 'end_date' => 'membership_end_date',
861d11c4
DG
596 'end_frequency_interval' => '4',
597 'end_frequency_unit' => 'month',
598 'entity_status' => '',
599 'entity_value' => '',
600 'group_id' => '',
601 'is_active' => 1,
602 'is_repeat' => '1',
603 'mapping_id' => 4,
604 'msg_template_id' => '',
605 'recipient' => '',
606 'recipient_listing' => '',
607 'recipient_manual' => '',
608 'record_activity' => 1,
609 'repetition_frequency_interval' => '4',
610 'repetition_frequency_unit' => 'week',
611 'start_action_condition' => 'after',
612 'start_action_date' => 'membership_end_date',
613 'start_action_offset' => '2',
614 'start_action_unit' => 'month',
615 'subject' => 'subject sched_membership_end_2month',
616 );
567b2076 617 $this->fixtures['sched_membership_end_limit_to_none'] = array(
baa85770
EM
618 'name' => 'limit to none',
619 'title' => 'limit to none',
620 'absolute_date' => '',
621 'body_html' => '<p>body sched_membership_end_2month</p>',
622 'body_text' => 'body sched_membership_end_2month',
623 'end_action' => '',
624 'end_date' => '',
625 'end_frequency_interval' => '4',
626 'end_frequency_unit' => 'month',
627 'entity_status' => '',
628 'entity_value' => '',
629 'limit_to' => 0,
630 'group_id' => '',
631 'is_active' => 1,
632 'is_repeat' => '1',
633 'mapping_id' => 4,
634 'msg_template_id' => '',
635 'recipient' => '',
636 'recipient_listing' => '',
637 'recipient_manual' => '',
638 'record_activity' => 1,
639 'repetition_frequency_interval' => '4',
640 'repetition_frequency_unit' => 'week',
641 'start_action_condition' => 'after',
642 'start_action_date' => 'membership_end_date',
643 'start_action_offset' => '2',
644 'start_action_unit' => 'month',
645 'subject' => 'limit to none',
646 );
52f09320
PH
647 $this->fixtures['sched_on_membership_end_date_repeat_interval'] = array(
648 'name' => 'sched_on_membership_end_date',
649 'title' => 'sched_on_membership_end_date',
650 'body_html' => '<p>Your membership expired 1 unit ago</p>',
651 'body_text' => 'Your membership expired 1 unit ago',
652 'end_frequency_interval' => 10,
653 'end_frequency_unit' => 'year',
654 'is_active' => 1,
655 'is_repeat' => TRUE,
656 'mapping_id' => 4,
657 'record_activity' => 1,
658 'start_action_condition' => 'after',
659 'start_action_date' => 'membership_end_date',
660 'start_action_offset' => '0',
661 'start_action_unit' => 'hour',
662 'subject' => 'subject send reminder every unit after membership_end_date',
663 );
664
2273ddcb 665 $customGroup = $this->callAPISuccess('CustomGroup', 'create', array(
666 'title' => ts('Test Contact Custom group'),
667 'name' => 'test_contact_cg',
668 'extends' => 'Contact',
669 'domain_id' => CRM_Core_Config::domainID(),
670 'is_active' => 1,
671 'collapse_adv_display' => 0,
672 'collapse_display' => 0,
673 ));
674 $customField = $this->callAPISuccess('CustomField', 'create', array(
675 'label' => 'Test Text',
676 'data_type' => 'String',
677 'html_type' => 'Text',
678 'custom_group_id' => $customGroup['id'],
679 ));
680 $this->fixtures['contact_custom_token'] = array(
681 'id' => $customField['id'],
682 'token' => sprintf('{contact.custom_%s}', $customField['id']),
683 'name' => sprintf('custom_%s', $customField['id']),
684 'value' => 'text ' . substr(sha1(rand()), 0, 7),
685 );
686
6a488035 687 $this->_setUp();
6a488035
TO
688 }
689
690 /**
691 * Tears down the fixture, for example, closes a network connection.
92c99a4a 692 *
6a488035 693 * This method is called after a test is executed.
6a488035 694 */
00be9182 695 public function tearDown() {
6a488035 696 parent::tearDown();
6a488035
TO
697 $this->mut->clearMessages();
698 $this->mut->stop();
699 unset($this->mut);
92c99a4a
EM
700 $this->quickCleanup(array(
701 'civicrm_action_schedule',
702 'civicrm_action_log',
703 'civicrm_membership',
d3eae6ea
TO
704 'civicrm_participant',
705 'civicrm_event',
92c99a4a
EM
706 'civicrm_email',
707 ));
2273ddcb 708 $this->callAPISuccess('CustomField', 'delete', array('id' => $this->fixtures['contact_custom_token']['id']));
709 $this->callAPISuccess('CustomGroup', 'delete', array(
710 'id' => CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomGroup', 'test_contact_cg', 'id', 'name'),
711 ));
6a488035
TO
712 $this->_tearDown();
713 }
714
43ceab3f
TO
715 public function mailerExamples() {
716 $cases = array();
717
bba4f3f6
CB
718 // Some tokens - short as subject has 128char limit in DB.
719 $someTokensTmpl = implode(';;', array(
39b959db
SL
720 // basic contact token
721 '{contact.display_name}',
722 // funny legacy contact token
723 '{contact.gender}',
724 // funny legacy contact token
725 '{contact.gender_id}',
726 // domain token
727 '{domain.name}',
728 // action-scheduler token
729 '{activity.activity_type}',
43ceab3f 730 ));
bba4f3f6
CB
731 // Further tokens can be tested in the body text/html.
732 $manyTokensTmpl = implode(';;', array(
733 $someTokensTmpl,
734 '{contact.email_greeting}',
2273ddcb 735 $this->fixture['contact_custom_token']['token'],
bba4f3f6 736 ));
ccdf6bd5
TO
737 // Note: The behavior of domain-tokens on a scheduled reminder is undefined. All we
738 // can really do is check that it has something.
bba4f3f6 739 $someTokensExpected = 'Churmondleia Ōtākou;;Female;;Female;;[a-zA-Z0-9 ]+;;Phone Call';
2273ddcb 740 $manyTokensExpected = sprintf('%s;;Dear Churmondleia;;%s', $someTokensExpected, $this->fixture['contact_custom_token']['value']);
43ceab3f 741
bba4f3f6 742 // In this example, we use a lot of tokens cutting across multiple components.
43ceab3f
TO
743 $cases[0] = array(
744 // Schedule definition.
745 array(
bba4f3f6 746 'subject' => "subj $someTokensTmpl",
43ceab3f
TO
747 'body_html' => "html $manyTokensTmpl",
748 'body_text' => "text $manyTokensTmpl",
749 ),
750 // Assertions (regex).
751 array(
752 'from_name' => "/^FIXME\$/",
753 'from_email' => "/^info@EXAMPLE.ORG\$/",
bba4f3f6 754 'subject' => "/^subj $someTokensExpected\$/",
43ceab3f
TO
755 'body_html' => "/^html $manyTokensExpected\$/",
756 'body_text' => "/^text $manyTokensExpected\$/",
757 ),
758 );
759
760 // In this example, we customize the from address.
761 $cases[1] = array(
762 // Schedule definition.
763 array(
764 'from_name' => 'Bob',
765 'from_email' => 'bob@example.org',
766 ),
767 // Assertions (regex).
768 array(
769 'from_name' => "/^Bob\$/",
770 'from_email' => "/^bob@example.org\$/",
771 ),
772 );
773
774 // In this example, we autoconvert HTML to text
775 $cases[2] = array(
776 // Schedule definition.
777 array(
778 'body_html' => '<p>Hello &amp; stuff.</p>',
779 'body_text' => '',
780 ),
781 // Assertions (regex).
782 array(
783 'body_html' => '/^' . preg_quote('<p>Hello &amp; stuff.</p>', '/') . '/',
784 'body_text' => '/^' . preg_quote('Hello & stuff.', '/') . '/',
785 ),
786 );
787
788 // In this example, we autoconvert HTML to text
789 $cases[3] = array(
790 // Schedule definition.
791 array(
792 'body_html' => '',
793 'body_text' => 'Hello world',
794 ),
795 // Assertions (regex).
796 array(
797 'body_html' => '/^--UNDEFINED--$/',
798 'body_text' => '/^Hello world$/',
799 ),
800 );
801
802 return $cases;
803 }
804
805 /**
806 * This generates a single mailing through the scheduled-reminder
807 * system (using an activity-reminder as a baseline) and
808 * checks that the resulting message satisfies various
809 * regular expressions.
810 *
811 * @param array $schedule
812 * Values to set/override in the schedule.
813 * Ex: array('subject' => 'Hello, {contact.first_name}!').
814 * @param array $patterns
815 * A list of regexes to compare with the actual email.
816 * Ex: array('subject' => '/^Hello, Alice!/').
817 * Keys: subject, body_text, body_html, from_name, from_email.
818 * @dataProvider mailerExamples
819 */
820 public function testMailer($schedule, $patterns) {
821 $actionSchedule = array_merge($this->fixtures['sched_activity_1day'], $schedule);
822 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
823 $this->assertTrue(is_numeric($actionScheduleDao->id));
824
825 $activity = $this->createTestObject('CRM_Activity_DAO_Activity', $this->fixtures['phonecall']);
826 $this->assertTrue(is_numeric($activity->id));
2273ddcb 827 $contact = $this->callAPISuccess('contact', 'create', array_merge(
828 $this->fixtures['contact'],
829 array(
830 $this->fixtures['contact_custom_token']['name'] => $this->fixtures['contact_custom_token']['value'],
831 )
832 ));
43ceab3f
TO
833 $activity->save();
834
835 $source['contact_id'] = $contact['id'];
836 $source['activity_id'] = $activity->id;
837 $source['record_type_id'] = 2;
838 $activityContact = $this->createTestObject('CRM_Activity_DAO_ActivityContact', $source);
839 $activityContact->save();
840
841 CRM_Utils_Time::setTime('2012-06-14 15:00:00');
842 $this->callAPISuccess('job', 'send_reminder', array());
843 $this->mut->assertRecipients(array(array('test-member@example.com')));
844 foreach ($this->mut->getAllMessages('ezc') as $message) {
845 /** @var ezcMail $message */
846
847 $messageArray = array();
848 $messageArray['subject'] = $message->subject;
849 $messageArray['from_name'] = $message->from->name;
850 $messageArray['from_email'] = $message->from->email;
851 $messageArray['body_text'] = '--UNDEFINED--';
852 $messageArray['body_html'] = '--UNDEFINED--';
853
854 foreach ($message->fetchParts() as $part) {
855 /** @var ezcMailText ezcMailText */
856 if ($part instanceof ezcMailText && $part->subType == 'html') {
857 $messageArray['body_html'] = $part->text;
858 }
859 if ($part instanceof ezcMailText && $part->subType == 'plain') {
860 $messageArray['body_text'] = $part->text;
861 }
862 }
863
864 foreach ($patterns as $field => $pattern) {
865 $this->assertRegExp($pattern, $messageArray[$field],
866 "Check that '$field'' matches regex. " . print_r(array('expected' => $patterns, 'actual' => $messageArray), 1));
867 }
868 }
869 $this->mut->clearMessages();
43ceab3f
TO
870 }
871
92c99a4a 872 public function testActivityDateTimeMatchNonRepeatableSchedule() {
cee19268 873 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($this->fixtures['sched_activity_1day']);
6a488035
TO
874 $this->assertTrue(is_numeric($actionScheduleDao->id));
875
876 $activity = $this->createTestObject('CRM_Activity_DAO_Activity', $this->fixtures['phonecall']);
6a488035 877 $this->assertTrue(is_numeric($activity->id));
6c6e6187 878 $contact = $this->callAPISuccess('contact', 'create', $this->fixtures['contact']);
d19632b1 879 $activity->subject = "Test subject for Phonecall";
6a488035
TO
880 $activity->save();
881
4f20f356 882 $source['contact_id'] = $contact['id'];
883 $source['activity_id'] = $activity->id;
884 $source['record_type_id'] = 2;
885 $activityContact = $this->createTestObject('CRM_Activity_DAO_ActivityContact', $source);
886 $activityContact->save();
887
6a488035 888 $this->assertCronRuns(array(
567b2076
EM
889 array(
890 // Before the 24-hour mark, no email
6a488035
TO
891 'time' => '2012-06-14 04:00:00',
892 'recipients' => array(),
f8c3594b 893 'subjects' => array(),
6a488035 894 ),
567b2076
EM
895 array(
896 // After the 24-hour mark, an email
6a488035
TO
897 'time' => '2012-06-14 15:00:00',
898 'recipients' => array(array('test-member@example.com')),
f8c3594b 899 'subjects' => array('1-Day (non-repeating) (about Phone Call)'),
6a488035 900 ),
567b2076
EM
901 array(
902 // Run cron again; message already sent
6a488035
TO
903 'time' => '',
904 'recipients' => array(),
905 ),
906 ));
d19632b1
JP
907 $activityTypes = CRM_Core_PseudoConstant::activityType(TRUE, FALSE, FALSE, 'name');
908 $activityDAO = new CRM_Activity_DAO_Activity();
909 $activityDAO->source_record_id = $activity->id;
910 $activityDAO->activity_type_id = array_search('Reminder Sent', $activityTypes);
911 $activityDAO->find();
912 while ($activityDAO->fetch()) {
913 $this->assertContains($activity->subject, $activityDAO->details);
914 }
6a488035
TO
915 }
916
92c99a4a 917 public function testActivityDateTimeMatchRepeatableSchedule() {
cee19268 918 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($this->fixtures['sched_activity_1day_r']);
6a488035
TO
919 $this->assertTrue(is_numeric($actionScheduleDao->id));
920
921 $activity = $this->createTestObject('CRM_Activity_DAO_Activity', $this->fixtures['phonecall']);
922 $this->assertTrue(is_numeric($activity->id));
6c6e6187 923 $contact = $this->callAPISuccess('contact', 'create', $this->fixtures['contact']);
6a488035
TO
924 $activity->save();
925
4f20f356 926 $source['contact_id'] = $contact['id'];
927 $source['activity_id'] = $activity->id;
6c6e6187 928 $source['record_type_id'] = 2;
4f20f356 929 $activityContact = $this->createTestObject('CRM_Activity_DAO_ActivityContact', $source);
930 $activityContact->save();
931
6a488035 932 $this->assertCronRuns(array(
567b2076
EM
933 array(
934 // Before the 24-hour mark, no email
6a488035
TO
935 'time' => '012-06-14 04:00:00',
936 'recipients' => array(),
f8c3594b 937 'subjects' => array(),
6a488035 938 ),
567b2076
EM
939 array(
940 // After the 24-hour mark, an email
6a488035
TO
941 'time' => '2012-06-14 15:00:00',
942 'recipients' => array(array('test-member@example.com')),
f8c3594b 943 'subjects' => array('1-Day (repeating) (about Phone Call)'),
6a488035 944 ),
567b2076
EM
945 array(
946 // Run cron 4 hours later; first message already sent
6a488035
TO
947 'time' => '2012-06-14 20:00:00',
948 'recipients' => array(),
f8c3594b 949 'subjects' => array(),
6a488035 950 ),
567b2076
EM
951 array(
952 // Run cron 6 hours later; send second message.
6a488035
TO
953 'time' => '2012-06-14 21:00:01',
954 'recipients' => array(array('test-member@example.com')),
f8c3594b 955 'subjects' => array('1-Day (repeating) (about Phone Call)'),
6a488035
TO
956 ),
957 ));
958 }
959
dc6c330d 960 public function testActivityDateTimeMatchRepeatableScheduleOnAbsDate() {
961 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($this->fixtures['sched_activity_1day_r_on_abs_date']);
962 $this->assertTrue(is_numeric($actionScheduleDao->id));
963
964 $activity = $this->createTestObject('CRM_Activity_DAO_Activity', $this->fixtures['phonecall']);
965 $this->assertTrue(is_numeric($activity->id));
966 $contact = $this->callAPISuccess('contact', 'create', $this->fixtures['contact']);
967 $activity->save();
968
969 $source['contact_id'] = $contact['id'];
970 $source['activity_id'] = $activity->id;
971 $source['record_type_id'] = 2;
972 $activityContact = $this->createTestObject('CRM_Activity_DAO_ActivityContact', $source);
973 $activityContact->save();
974
975 $this->assertCronRuns(array(
976 array(
977 // Before the 24-hour mark, no email
978 'time' => '2012-06-13 04:00:00',
979 'recipients' => array(),
980 'subjects' => array(),
981 ),
982 array(
983 // On absolute date set on 2012-06-14
984 'time' => '2012-06-14 00:00:00',
985 'recipients' => array(array('test-member@example.com')),
986 'subjects' => array('1-Day (repeating) (about Phone Call)'),
987 ),
988 array(
989 // Run cron 4 hours later; first message already sent
990 'time' => '2012-06-14 04:00:00',
991 'recipients' => array(),
992 'subjects' => array(),
993 ),
994 array(
995 // Run cron 6 hours later; send second message.
996 'time' => '2012-06-14 06:00:01',
997 'recipients' => array(array('test-member@example.com')),
998 'subjects' => array('1-Day (repeating) (about Phone Call)'),
999 ),
1000 ));
1001 }
1002
6a488035
TO
1003 /**
1004 * For contacts/activities which don't match the schedule filter,
1005 * an email should *not* be sent.
1006 */
1007 // TODO // function testActivityDateTime_NonMatch() { }
1008
1009 /**
76ea51c7 1010 * For contacts/members which match schedule based on join/start date,
6a488035
TO
1011 * an email should be sent.
1012 */
76ea51c7 1013 public function testMembershipDateMatch() {
bb3ba83e
AH
1014 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 1)));
1015 $this->assertTrue(is_numeric($membership->id));
1016 $result = $this->callAPISuccess('Email', 'create', array(
1017 'contact_id' => $membership->contact_id,
1018 'email' => 'test-member@example.com',
1019 'location_type_id' => 1,
1020 'is_primary' => 1,
1021 ));
6a488035 1022
bb3ba83e
AH
1023 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
1024 $actionSchedule = $this->fixtures['sched_membership_join_2week'];
1025 $actionSchedule['entity_value'] = $membership->membership_type_id;
1026 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1027 $this->assertTrue(is_numeric($actionScheduleDao->id));
6a488035 1028
bb3ba83e
AH
1029 // start_date=2012-03-15 ; schedule is 2 weeks after join_date
1030 $this->assertCronRuns(array(
1031 array(
1032 // Before the 2-week mark, no email.
1033 'time' => '2012-03-28 01:00:00',
1034 'recipients' => array(),
1035 'subjects' => array(),
1036 ),
1037 array(
1038 // After the 2-week mark, send an email.
1039 'time' => '2012-03-29 01:00:00',
1040 'recipients' => array(array('test-member@example.com')),
1041 'subjects' => array('subject sched_membership_join_2week (joined March 15th, 2012)'),
1042 ),
1043 ));
1044
1045 $actionSchedule = $this->fixtures['sched_membership_start_1week'];
1046 $actionSchedule['entity_value'] = $membership->membership_type_id;
1047 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1048 $this->assertTrue(is_numeric($actionScheduleDao->id));
1049
1050 // start_date=2012-03-15 ; schedule is 1 weeks after start_date
1051 $this->assertCronRuns(array(
1052 array(
1053 // Before the 2-week mark, no email.
1054 'time' => '2012-03-21 01:00:00',
1055 'recipients' => array(),
1056 'subjects' => array(),
1057 ),
1058 array(
1059 // After the 2-week mark, send an email.
1060 'time' => '2012-03-22 01:00:00',
1061 'recipients' => array(array('test-member@example.com')),
1062 'subjects' => array('subject sched_membership_start_1week (joined March 15th, 2012)'),
1063 ),
1064 ));
6a488035
TO
1065 }
1066
cc949606 1067 /**
1068 * CRM-21675: Support parent and smart group in 'Limit to' field
1069 */
1070 public function testScheduleReminderWithParentGroup() {
1071 // Contact A with birth-date at '07-07-2005' and gender - Male, later got added in smart group
1072 $contactID1 = $this->individualCreate(array('birth_date' => '20050707', 'gender_id' => 1, 'email' => 'abc@test.com'));
1073 // Contact B with birth-date at '07-07-2005', later got added in regular group
1074 $contactID2 = $this->individualCreate(array('birth_date' => '20050707', 'email' => 'def@test.com'), 1);
1075 // Contact C with birth-date at '07-07-2005', but not included in any group
1076 $contactID3 = $this->individualCreate(array('birth_date' => '20050707', 'email' => 'ghi@test.com'), 2);
1077
1078 // create regular group and add Contact B to it
1079 $groupID = $this->groupCreate();
1080 $this->callAPISuccess('GroupContact', 'Create', array(
1081 'group_id' => $groupID,
1082 'contact_id' => $contactID2,
1083 ));
1084
1085 // create smart group which will contain all Male contacts
1086 $smartGroupParams = array('formValues' => array('gender_id' => 1));
1087 $smartGroupID = $this->smartGroupCreate(
1088 $smartGroupParams,
1089 array(
1090 'name' => 'new_smart_group',
1091 'title' => 'New Smart Group',
1092 'parents' => array($groupID => 1),
1093 )
1094 );
1095
1096 $actionScheduleParams = array(
1097 'name' => 'sched_contact_bday_yesterday',
1098 'title' => 'sched_contact_bday_yesterday',
1099 'absolute_date' => '',
1100 'body_html' => '<p>you look like you were born yesterday!</p>',
1101 'body_text' => 'you look like you were born yesterday!',
1102 'end_action' => '',
1103 'end_date' => '',
1104 'end_frequency_interval' => '',
1105 'end_frequency_unit' => '',
1106 'entity_status' => 1,
1107 'entity_value' => 'birth_date',
1108 'limit_to' => 1,
1109 'group_id' => $groupID,
1110 'is_active' => 1,
1111 'is_repeat' => '0',
1112 'mapping_id' => 6,
1113 'msg_template_id' => '',
1114 'recipient' => '2',
1115 'recipient_listing' => '',
1116 'recipient_manual' => '',
1117 'record_activity' => 1,
1118 'repetition_frequency_interval' => '',
1119 'repetition_frequency_unit' => '',
1120 'start_action_condition' => 'after',
1121 'start_action_date' => 'date_field',
1122 'start_action_offset' => '1',
1123 'start_action_unit' => 'day',
1124 'subject' => 'subject sched_contact_bday_yesterday',
1125 );
1126
1127 // Create schedule reminder where parent group ($groupID) is selectd to limit recipients,
1128 // which contain a individual contact - $contactID2 and is parent to smart group.
1129 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionScheduleParams);
1130 $this->assertTrue(is_numeric($actionScheduleDao->id));
1131 $this->assertCronRuns(array(
1132 array(
1133 // On the birthday, no email.
1134 'time' => '2005-07-07 01:00:00',
1135 'recipients' => array(),
1136 ),
1137 array(
1138 // The next day, send an email.
1139 'time' => '2005-07-08 20:00:00',
1140 'recipients' => array(
1141 array(
1142 'def@test.com',
1143 ),
1144 array(
1145 'abc@test.com',
1146 ),
1147 ),
1148 ),
1149 ));
1150 $this->groupDelete($smartGroupID);
1151 $this->groupDelete($groupID);
1152 }
1153
6a488035 1154 /**
442cf836
EM
1155 * Test end date email sent.
1156 *
6a488035
TO
1157 * For contacts/members which match schedule based on join date,
1158 * an email should be sent.
1159 */
92c99a4a 1160 public function testMembershipJoinDateNonMatch() {
6a488035
TO
1161 $membership = $this->createTestObject('CRM_Member_DAO_Membership', $this->fixtures['rolling_membership']);
1162 $this->assertTrue(is_numeric($membership->id));
bf308d29 1163 $result = $this->callAPISuccess('Email', 'create', array(
6a488035
TO
1164 'contact_id' => $membership->contact_id,
1165 'location_type_id' => 1,
1166 'email' => 'test-member@example.com',
6a488035 1167 ));
fe265b4e 1168
6a488035
TO
1169 // Add an alternative membership type, and only send messages for that type
1170 $extraMembershipType = $this->createTestObject('CRM_Member_DAO_MembershipType', array());
1171 $this->assertTrue(is_numeric($extraMembershipType->id));
cee19268 1172 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($this->fixtures['sched_membership_join_2week']);
6a488035
TO
1173 $this->assertTrue(is_numeric($actionScheduleDao->id));
1174 $actionScheduleDao->entity_value = $extraMembershipType->id;
1175 $actionScheduleDao->save();
1176
1177 // start_date=2012-03-15 ; schedule is 2 weeks after start_date
1178 $this->assertCronRuns(array(
567b2076
EM
1179 array(
1180 // After the 2-week mark, don't send email because we have different membership type.
6a488035
TO
1181 'time' => '2012-03-29 01:00:00',
1182 'recipients' => array(),
1183 ),
1184 ));
1185 }
1186
861d11c4 1187 /**
442cf836 1188 * Test that the first and SECOND notifications are sent out.
861d11c4 1189 */
92c99a4a 1190 public function testMembershipEndDateRepeat() {
861d11c4
DG
1191 // creates membership with end_date = 20120615
1192 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
1193 $result = $this->callAPISuccess('Email', 'create', array(
1194 'contact_id' => $membership->contact_id,
1195 'email' => 'test-member@example.com',
1196 ));
1197 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
1198
1199 $actionSchedule = $this->fixtures['sched_membership_end_2month_repeat_twice_4_weeks'];
1200 $actionSchedule['entity_value'] = $membership->membership_type_id;
1201 $this->callAPISuccess('action_schedule', 'create', $actionSchedule);
1202
1203 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1204 $this->assertCronRuns(array(
567b2076
EM
1205 array(
1206 // After the 2-week mark, send an email.
861d11c4
DG
1207 'time' => '2012-08-15 01:00:00',
1208 'recipients' => array(array('test-member@example.com')),
1209 ),
567b2076
EM
1210 array(
1211 // After the 2-week mark, send an email.
861d11c4
DG
1212 'time' => '2012-09-12 01:00:00',
1213 'recipients' => array(array('test-member@example.com')),
1214 ),
1215 ));
1216 }
1217
1218 /**
442cf836
EM
1219 * Test behaviour when date changes.
1220 *
861d11c4
DG
1221 * Test that the first notification is sent but the second is NOT sent if the end date changes in
1222 * between
1223 * see CRM-15376
1224 */
92c99a4a 1225 public function testMembershipEndDateRepeatChangedEndDate_CRM_15376() {
861d11c4
DG
1226 // creates membership with end_date = 20120615
1227 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
1228 $this->callAPISuccess('Email', 'create', array(
1229 'contact_id' => $membership->contact_id,
1230 'email' => 'test-member@example.com',
1231 ));
1232 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
1233
1234 $actionSchedule = $this->fixtures['sched_membership_end_2month_repeat_twice_4_weeks'];
1235 $actionSchedule['entity_value'] = $membership->membership_type_id;
1236 $this->callAPISuccess('action_schedule', 'create', $actionSchedule);
1237 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1238 $this->assertCronRuns(array(
567b2076
EM
1239 array(
1240 // After the 2-week mark, send an email.
861d11c4
DG
1241 'time' => '2012-08-15 01:00:00',
1242 'recipients' => array(array('test-member@example.com')),
1243 ),
1244 ));
1245
442cf836 1246 // Extend membership - reminder should NOT go out.
861d11c4
DG
1247 $this->callAPISuccess('membership', 'create', array('id' => $membership->id, 'end_date' => '2014-01-01'));
1248 $this->assertCronRuns(array(
442cf836
EM
1249 array(
1250 // After the 2-week mark, send an email.
861d11c4
DG
1251 'time' => '2012-09-12 01:00:00',
1252 'recipients' => array(),
1253 ),
1254 ));
1255 }
1256
6a488035 1257 /**
442cf836
EM
1258 * Test membership end date email sends.
1259 *
6a488035
TO
1260 * For contacts/members which match schedule based on end date,
1261 * an email should be sent.
1262 */
92c99a4a 1263 public function testMembershipEndDateMatch() {
6a488035 1264 // creates membership with end_date = 20120615
b29be8c2 1265 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
6a488035 1266 $this->assertTrue(is_numeric($membership->id));
bf308d29 1267 $this->callAPISuccess('Email', 'create', array(
6a488035
TO
1268 'contact_id' => $membership->contact_id,
1269 'email' => 'test-member@example.com',
92915c55 1270 ));
bf308d29 1271 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
6a488035
TO
1272
1273 $actionSchedule = $this->fixtures['sched_membership_end_2week'];
1274 $actionSchedule['entity_value'] = $membership->membership_type_id;
cee19268 1275 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
6a488035
TO
1276 $this->assertTrue(is_numeric($actionScheduleDao->id));
1277
1278 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1279 $this->assertCronRuns(array(
442cf836
EM
1280 array(
1281 // Before the 2-week mark, no email.
6a488035 1282 'time' => '2012-05-31 01:00:00',
442cf836
EM
1283 // 'time' => '2012-06-01 01:00:00',
1284 // FIXME: Is this the right boundary?
6a488035
TO
1285 'recipients' => array(),
1286 ),
442cf836
EM
1287 array(
1288 // After the 2-week mark, send an email.
6a488035
TO
1289 'time' => '2012-06-01 01:00:00',
1290 'recipients' => array(array('test-member@example.com')),
1291 ),
1292 ));
d2868251 1293
1294 // Now suppose user has renewed for rolling membership after 3 months, so upcoming assertion is written
1295 // to ensure that new reminder is sent 2 week before the new end_date i.e. '2012-09-15'
1296 $membership->end_date = '2012-09-15';
1297 $membership->save();
1298
1299 //change the email id of chosen membership contact to assert
1300 //recipient of not the previously sent mail but the new one
1301 $result = $this->callAPISuccess('Email', 'create', array(
1302 'is_primary' => 1,
1303 'contact_id' => $membership->contact_id,
cbcb7579 1304 'email' => 'member2@example.com',
d2868251 1305 ));
1306 $this->assertAPISuccess($result);
1307
1308 // end_date=2012-09-15 ; schedule is 2 weeks before end_date
1309 $this->assertCronRuns(array(
cbcb7579
TO
1310 array(
1311 // Before the 2-week mark, no email
d2868251 1312 'time' => '2012-08-31 01:00:00',
1313 'recipients' => array(),
cbcb7579
TO
1314 ),
1315 //array( // After the 2-week mark, send an email
1316 //'time' => '2012-09-01 01:00:00',
1317 //'recipients' => array(array('member2@example.com')),
1318 //),
d2868251 1319 ));
6a488035
TO
1320 }
1321
4b1efa1d 1322 /**
442cf836
EM
1323 * Test membership end date email.
1324 *
6c6e6187
TO
1325 * For contacts/members which match schedule based on end date,
1326 * an email should be sent.
1327 */
92c99a4a 1328 public function testMembershipEndDateNoMatch() {
4b1efa1d 1329 // creates membership with end_date = 20120615
5c4d6559 1330 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 3)));
4b1efa1d 1331 $this->assertTrue(is_numeric($membership->id));
6c6e6187 1332 $result = $this->callAPISuccess('Email', 'create', array(
4b1efa1d 1333 'contact_id' => $membership->contact_id,
1334 'email' => 'test-member@example.com',
4b1efa1d 1335 ));
bf308d29 1336 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
4b1efa1d 1337
1338 $actionSchedule = $this->fixtures['sched_membership_end_2month'];
1339 $actionSchedule['entity_value'] = $membership->membership_type_id;
cee19268 1340 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
4b1efa1d 1341 $this->assertTrue(is_numeric($actionScheduleDao->id));
1342
1343 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1344 $this->assertCronRuns(array(
442cf836
EM
1345 array(
1346 // Before the 2-week mark, no email.
4b1efa1d 1347 'time' => '2012-05-31 01:00:00',
442cf836
EM
1348 // 'time' => '2012-06-01 01:00:00',
1349 // FIXME: Is this the right boundary?
4b1efa1d 1350 'recipients' => array(),
1351 ),
442cf836
EM
1352 array(
1353 // After the 2-week mark, send an email.
4b1efa1d 1354 'time' => '2013-05-01 01:00:00',
1355 'recipients' => array(),
1356 ),
1357 ));
1358 }
1359
92c99a4a 1360 public function testContactBirthDateNoAnniv() {
bf308d29 1361 $contact = $this->callAPISuccess('Contact', 'create', $this->fixtures['contact_birthdate']);
43030baf
AH
1362 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
1363 $actionSchedule = $this->fixtures['sched_contact_bday_yesterday'];
1364 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1365 $this->assertTrue(is_numeric($actionScheduleDao->id));
1366 $this->assertCronRuns(array(
442cf836
EM
1367 array(
1368 // On the birthday, no email.
43030baf
AH
1369 'time' => '2005-07-07 01:00:00',
1370 'recipients' => array(),
1371 ),
442cf836
EM
1372 array(
1373 // The next day, send an email.
43030baf
AH
1374 'time' => '2005-07-08 20:00:00',
1375 'recipients' => array(array('test-bday@example.com')),
1376 ),
1377 ));
1378 }
1379
92c99a4a 1380 public function testContactBirthDateAnniversary() {
6c6e6187 1381 $contact = $this->callAPISuccess('Contact', 'create', $this->fixtures['contact_birthdate']);
43030baf
AH
1382 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
1383 $actionSchedule = $this->fixtures['sched_contact_bday_anniv'];
1384 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1385 $this->assertTrue(is_numeric($actionScheduleDao->id));
1386 $this->assertCronRuns(array(
92c99a4a
EM
1387 array(
1388 // On some random day, no email.
43030baf
AH
1389 'time' => '2014-03-07 01:00:00',
1390 'recipients' => array(),
1391 ),
92c99a4a
EM
1392 array(
1393 // On the eve of their 9th birthday, send an email.
43030baf
AH
1394 'time' => '2014-07-06 20:00:00',
1395 'recipients' => array(array('test-bday@example.com')),
1396 ),
1397 ));
1398 }
4b1efa1d 1399
92c99a4a 1400 public function testContactCustomDateNoAnniv() {
43030baf
AH
1401 $group = array(
1402 'title' => 'Test_Group',
1403 'name' => 'test_group',
1404 'extends' => array('Individual'),
1405 'style' => 'Inline',
6c6e6187 1406 'is_multiple' => FALSE,
43030baf 1407 'is_active' => 1,
43030baf 1408 );
bf308d29 1409 $createGroup = $this->callAPISuccess('custom_group', 'create', $group);
43030baf 1410 $field = array(
43030baf
AH
1411 'label' => 'Graduation',
1412 'data_type' => 'Date',
1413 'html_type' => 'Select Date',
1414 'custom_group_id' => $createGroup['id'],
1415 );
bf308d29 1416 $createField = $this->callAPISuccess('custom_field', 'create', $field);
43030baf
AH
1417 $contactParams = $this->fixtures['contact'];
1418 $contactParams["custom_{$createField['id']}"] = '2013-12-16';
bf308d29 1419 $contact = $this->callAPISuccess('Contact', 'create', $contactParams);
43030baf
AH
1420 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
1421 $actionSchedule = $this->fixtures['sched_contact_grad_tomorrow'];
1422 $actionSchedule['entity_value'] = "custom_{$createField['id']}";
1423 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1424 $this->assertTrue(is_numeric($actionScheduleDao->id));
1425 $this->assertCronRuns(array(
92c99a4a
EM
1426 array(
1427 // On some random day, no email.
43030baf
AH
1428 'time' => '2014-03-07 01:00:00',
1429 'recipients' => array(),
1430 ),
92c99a4a
EM
1431 array(
1432 // On the eve of their graduation, send an email.
43030baf
AH
1433 'time' => '2013-12-15 20:00:00',
1434 'recipients' => array(array('test-member@example.com')),
1435 ),
1436 ));
6c6e6187 1437 $this->callAPISuccess('custom_group', 'delete', array('id' => $createGroup['id']));
43030baf 1438 }
92915c55 1439
4aff0253
AH
1440 public function testContactCreatedNoAnniv() {
1441 $contact = $this->callAPISuccess('Contact', 'create', $this->fixtures['contact_birthdate']);
1442 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
1443 $actionSchedule = $this->fixtures['sched_contact_created_yesterday'];
1444 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1445 $this->assertTrue(is_numeric($actionScheduleDao->id));
1446 $this->assertCronRuns(array(
1447 array(
1448 // On the date created, no email.
1449 'time' => $contact['values'][$contact['id']]['created_date'],
1450 'recipients' => array(),
1451 ),
1452 array(
1453 // The next day, send an email.
1454 'time' => date('Y-m-d H:i:s', strtotime($contact['values'][$contact['id']]['created_date'] . ' +1 day')),
1455 'recipients' => array(array('test-bday@example.com')),
1456 ),
1457 ));
1458 }
1459
1460 public function testContactModifiedAnniversary() {
1461 $contact = $this->callAPISuccess('Contact', 'create', $this->fixtures['contact_birthdate']);
1462 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
688bd604 1463 $modifiedDate = $this->callAPISuccess('Contact', 'getvalue', array('id' => $contact['id'], 'return' => 'modified_date'));
4aff0253
AH
1464 $actionSchedule = $this->fixtures['sched_contact_mod_anniv'];
1465 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1466 $this->assertTrue(is_numeric($actionScheduleDao->id));
1467 $this->assertCronRuns(array(
1468 array(
1469 // On some random day, no email.
a9ac9f6c 1470 'time' => date('Y-m-d H:i:s', strtotime($contact['values'][$contact['id']]['modified_date'] . ' -60 days')),
4aff0253
AH
1471 'recipients' => array(),
1472 ),
1473 array(
1474 // On the eve of 3 years after they were modified, send an email.
688bd604 1475 'time' => date('Y-m-d H:i:s', strtotime($modifiedDate . ' +3 years -1 day')),
4aff0253
AH
1476 'recipients' => array(array('test-bday@example.com')),
1477 ),
1478 ));
1479 }
1480
baa85770 1481 /**
92c99a4a 1482 * Check that limit_to + an empty recipients doesn't sent to multiple contacts.
baa85770 1483 */
00be9182 1484 public function testMembershipLimitToNone() {
baa85770
EM
1485 // creates membership with end_date = 20120615
1486 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
1487
1488 $this->assertTrue(is_numeric($membership->id));
1489 $result = $this->callAPISuccess('Email', 'create', array(
1490 'contact_id' => $membership->contact_id,
1491 'email' => 'member@example.com',
1492 ));
1493 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
1494 $this->callAPISuccess('contact', 'create', array('email' => 'b@c.com', 'contact_type' => 'Individual'));
1495
1496 $this->assertAPISuccess($result);
1497
1498 $actionSchedule = $this->fixtures['sched_membership_end_limit_to_none'];
1499 $actionSchedule['entity_value'] = $membership->membership_type_id;
1500 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1501 $this->assertTrue(is_numeric($actionScheduleDao->id));
1502
1503 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1504 $this->assertCronRuns(array(
92c99a4a
EM
1505 array(
1506 // Before the 2-week mark, no email.
baa85770
EM
1507 'time' => '2012-05-31 01:00:00',
1508 // 'time' => '2012-06-01 01:00:00', // FIXME: Is this the right boundary?
1509 'recipients' => array(),
1510 ),
1511 ));
1512 }
1513
cbcb7579 1514 public function testMembership_referenceDate() {
5c4d6559 1515 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
1516
1517 $this->assertTrue(is_numeric($membership->id));
1518 $result = $this->callAPISuccess('Email', 'create', array(
1519 'contact_id' => $membership->contact_id,
1520 'email' => 'member@example.com',
1521 ));
1522
1523 $result = $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
1524 $this->assertAPISuccess($result);
1525
1526 $actionSchedule = $this->fixtures['sched_membership_join_2week'];
1527 $actionSchedule['entity_value'] = $membership->membership_type_id;
1528 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1529 $this->assertTrue(is_numeric($actionScheduleDao->id));
1530
1531 // start_date=2012-03-15 ; schedule is 2 weeks after start_date
1532 $this->assertCronRuns(array(
cbcb7579
TO
1533 array(
1534 // After the 2-week mark, send an email
5c4d6559 1535 'time' => '2012-03-29 01:00:00',
1536 'recipients' => array(array('member@example.com')),
9c0fe051 1537 ),
cbcb7579
TO
1538 array(
1539 // After the 2-week 1day mark, don't send an email
9c0fe051 1540 'time' => '2012-03-30 01:00:00',
1541 'recipients' => array(),
1542 ),
5c4d6559 1543 ));
1544
1545 //check if reference date is set to membership's join date
1546 //as per the action_start_date chosen for current schedule reminder
1547 $this->assertEquals('2012-03-15',
1548 CRM_Core_DAO::getFieldValue('CRM_Core_DAO_ActionLog', $membership->contact_id, 'reference_date', 'contact_id')
1549 );
1550
e7c6a902 1551 //change current membership join date that may signifies as membership renewal activity
5c4d6559 1552 $membership->join_date = '2012-03-29';
1553 $membership->save();
1554
5c4d6559 1555 $this->assertCronRuns(array(
cbcb7579
TO
1556 array(
1557 // After the 13 days of the changed join date 2012-03-29, don't send an email
9c0fe051 1558 'time' => '2012-04-11 01:00:00',
cbcb7579
TO
1559 'recipients' => array(),
1560 ),
1561 array(
1562 // After the 2-week of the changed join date 2012-03-29, send an email
5c4d6559 1563 'time' => '2012-04-12 01:00:00',
cbcb7579 1564 'recipients' => array(array('member@example.com')),
5c4d6559 1565 ),
1566 ));
7d48c97b 1567 $this->assertCronRuns(array(
1568 array(
1569 // It should not re-send on the same day
1570 'time' => '2012-04-12 01:00:00',
f8da3b93 1571 'recipients' => array(),
7d48c97b 1572 ),
1573 ));
5c4d6559 1574 }
baa85770 1575
d2868251 1576 public function testMembershipOnMultipleReminder() {
1577 $membership = $this->createTestObject('CRM_Member_DAO_Membership', array_merge($this->fixtures['rolling_membership'], array('status_id' => 2)));
d2868251 1578
1579 $this->assertTrue(is_numeric($membership->id));
1580 $result = $this->callAPISuccess('Email', 'create', array(
1581 'contact_id' => $membership->contact_id,
1582 'email' => 'member@example.com',
1583 ));
cbcb7579 1584 $result = $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $membership->contact_id)));
d2868251 1585 $this->assertAPISuccess($result);
1586
39b959db
SL
1587 // Send email 2 weeks before end_date
1588 $actionScheduleBefore = $this->fixtures['sched_membership_end_2week'];
1589 // Send email on end_date/expiry date
1590 $actionScheduleOn = $this->fixtures['sched_on_membership_end_date'];
1591 // Send email 1 day after end_date/grace period
1592 $actionScheduleAfter = $this->fixtures['sched_after_1day_membership_end_date'];
d2868251 1593 $actionScheduleBefore['entity_value'] = $actionScheduleOn['entity_value'] = $actionScheduleAfter['entity_value'] = $membership->membership_type_id;
1594 foreach (array('actionScheduleBefore', 'actionScheduleOn', 'actionScheduleAfter') as $value) {
1595 $$value = CRM_Core_BAO_ActionSchedule::add($$value);
1596 $this->assertTrue(is_numeric($$value->id));
1597 }
1598
1599 $this->assertCronRuns(
1600 array(
cbcb7579
TO
1601 array(
1602 // 1day 2weeks before membership end date(MED), don't send mail
d2868251 1603 'time' => '2012-05-31 01:00:00',
1604 'recipients' => array(),
1605 ),
cbcb7579
TO
1606 array(
1607 // 2 weeks before MED, send an email
d2868251 1608 'time' => '2012-06-01 01:00:00',
1609 'recipients' => array(array('member@example.com')),
1610 ),
cbcb7579
TO
1611 array(
1612 // 1day before MED, don't send mail
d2868251 1613 'time' => '2012-06-14 01:00:00',
1614 'recipients' => array(),
1615 ),
cbcb7579
TO
1616 array(
1617 // On MED, send an email
d2868251 1618 'time' => '2012-06-15 00:00:00',
1619 'recipients' => array(array('member@example.com')),
1620 ),
cbcb7579
TO
1621 array(
1622 // After 1day of MED, send an email
d2868251 1623 'time' => '2012-06-16 01:00:00',
1624 'recipients' => array(array('member@example.com')),
1625 ),
cbcb7579
TO
1626 array(
1627 // After 1day 1min of MED, don't send an email
d2868251 1628 'time' => '2012-06-17 00:01:00',
1629 'recipients' => array(),
1630 ),
cbcb7579
TO
1631 )
1632 );
d2868251 1633
1634 // Assert the timestamp as of when the emails of respective three reminders as configured
1635 // 2 weeks before, on and 1 day after MED, are sent
f42ab010
TO
1636 $this->assertApproxEquals(
1637 strtotime('2012-06-01 01:00:00'),
1638 strtotime(CRM_Core_DAO::getFieldValue('CRM_Core_DAO_ActionLog', $actionScheduleBefore->id, 'action_date_time', 'action_schedule_id', TRUE)),
39b959db
SL
1639 // Variation in test execution time.
1640 3
f42ab010
TO
1641 );
1642 $this->assertApproxEquals(
1643 strtotime('2012-06-15 00:00:00'),
1644 strtotime(CRM_Core_DAO::getFieldValue('CRM_Core_DAO_ActionLog', $actionScheduleOn->id, 'action_date_time', 'action_schedule_id', TRUE)),
39b959db
SL
1645 // Variation in test execution time.
1646 3
f42ab010
TO
1647 );
1648 $this->assertApproxEquals(
1649 strtotime('2012-06-16 01:00:00'),
1650 strtotime(CRM_Core_DAO::getFieldValue('CRM_Core_DAO_ActionLog', $actionScheduleAfter->id, 'action_date_time', 'action_schedule_id', TRUE)),
39b959db
SL
1651 // Variation in test execution time.
1652 3
f42ab010 1653 );
d2868251 1654
e7c6a902 1655 //extend MED to 2 weeks after the current MED (that may signifies as membership renewal activity)
d2868251 1656 // and lets assert as of when the new set of reminders will be sent against their respective Schedule Reminders(SR)
9c0fe051 1657 $membership->end_date = '2012-06-20';
d2868251 1658 $membership->save();
d2868251 1659
9c0fe051 1660 $result = $this->callAPISuccess('Contact', 'get', array('id' => $membership->contact_id));
d2868251 1661 $this->assertCronRuns(
1662 array(
cbcb7579
TO
1663 array(
1664 // 1day 2weeks before membership end date(MED), don't send mail
9c0fe051 1665 'time' => '2012-06-05 01:00:00',
d2868251 1666 'recipients' => array(),
1667 ),
cbcb7579
TO
1668 array(
1669 // 2 weeks before MED, send an email
9c0fe051 1670 'time' => '2012-06-06 01:00:00',
1671 'recipients' => array(array('member@example.com')),
d2868251 1672 ),
cbcb7579
TO
1673 array(
1674 // 1day before MED, don't send mail
9c0fe051 1675 'time' => '2012-06-19 01:00:00',
d2868251 1676 'recipients' => array(),
1677 ),
cbcb7579
TO
1678 array(
1679 // On MED, send an email
9c0fe051 1680 'time' => '2012-06-20 00:00:00',
d2868251 1681 'recipients' => array(array('member@example.com')),
1682 ),
cbcb7579
TO
1683 array(
1684 // After 1day of MED, send an email
9c0fe051 1685 'time' => '2012-06-21 01:00:00',
d2868251 1686 'recipients' => array(array('member@example.com')),
1687 ),
cbcb7579
TO
1688 array(
1689 // After 1day 1min of MED, don't send an email
9c0fe051 1690 'time' => '2012-07-21 00:01:00',
d2868251 1691 'recipients' => array(),
1692 ),
d2868251 1693 ));
1694 }
1695
1696 public function testContactCustomDate_Anniv() {
43030baf
AH
1697 $group = array(
1698 'title' => 'Test_Group now',
1699 'name' => 'test_group_now',
1700 'extends' => array('Individual'),
1701 'style' => 'Inline',
6c6e6187 1702 'is_multiple' => FALSE,
43030baf 1703 'is_active' => 1,
43030baf 1704 );
bf308d29 1705 $createGroup = $this->callAPISuccess('custom_group', 'create', $group);
43030baf 1706 $field = array(
43030baf
AH
1707 'label' => 'Graduation',
1708 'data_type' => 'Date',
1709 'html_type' => 'Select Date',
1710 'custom_group_id' => $createGroup['id'],
1711 );
bf308d29
EM
1712 $createField = $this->callAPISuccess('custom_field', 'create', $field);
1713
43030baf
AH
1714 $contactParams = $this->fixtures['contact'];
1715 $contactParams["custom_{$createField['id']}"] = '2013-12-16';
bf308d29 1716 $contact = $this->callAPISuccess('Contact', 'create', $contactParams);
43030baf
AH
1717 $this->_testObjects['CRM_Contact_DAO_Contact'][] = $contact['id'];
1718 $actionSchedule = $this->fixtures['sched_contact_grad_anniv'];
1719 $actionSchedule['entity_value'] = "custom_{$createField['id']}";
1720 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
1721 $this->assertTrue(is_numeric($actionScheduleDao->id));
1722 $this->assertCronRuns(array(
92c99a4a
EM
1723 array(
1724 // On some random day, no email.
43030baf
AH
1725 'time' => '2014-03-07 01:00:00',
1726 'recipients' => array(),
1727 ),
92c99a4a
EM
1728 array(
1729 // A week after their 5th anniversary of graduation, send an email.
43030baf
AH
1730 'time' => '2018-12-23 20:00:00',
1731 'recipients' => array(array('test-member@example.com')),
1732 ),
1733 ));
6c6e6187 1734 $this->callAPISuccess('custom_group', 'delete', array('id' => $createGroup['id']));
43030baf 1735 }
4b1efa1d 1736
76ea51c7
JP
1737 /**
1738 * Test sched reminder set via registration date.
1739 */
1740 public function testEventTypeRegistrationDate() {
1741 //Create contact
1742 $contactParams = array(
1743 'email' => 'test-event@example.com',
1744 );
1745 $contact = $this->individualCreate($contactParams);
1746 //Add it as a participant to an event ending registration - 7 days from now.
1747 $params = array(
1748 'start_date' => date('Ymd', strtotime('-5 day')),
1749 'end_date' => date('Ymd', strtotime('+7 day')),
1750 'registration_start_date' => date('Ymd', strtotime('-5 day')),
1751 'registration_end_date' => date('Ymd', strtotime('+7 day')),
1752 );
1753 $event = $this->eventCreate($params);
1754 $this->participantCreate(array('contact_id' => $contact, 'event_id' => $event['id']));
1755
1756 //Create a scheduled reminder to send email 7 days before registration date.
1757 $actionSchedule = $this->fixtures['sched_eventtype_start_1week_before'];
1758 $actionSchedule['start_action_offset'] = 7;
1759 $actionSchedule['start_action_unit'] = 'day';
1760 $actionSchedule['start_action_date'] = 'registration_end_date';
1761 $actionSchedule['entity_value'] = $event['values'][$event['id']]['event_type_id'];
1762 $actionSchedule['entity_status'] = $this->callAPISuccessGetValue('ParticipantStatusType', array(
1763 'return' => "id",
1764 'name' => "Attended",
1765 ));
899bd155 1766 $actionSched = $this->callAPISuccess('action_schedule', 'create', $actionSchedule);
76ea51c7
JP
1767 //Run the cron and verify if an email was sent.
1768 $this->assertCronRuns(array(
1769 array(
1770 'time' => date('Y-m-d'),
1771 'recipients' => array(array('test-event@example.com')),
1772 ),
1773 ));
899bd155
JP
1774
1775 //Create contact 2
1776 $contactParams = array(
1777 'email' => 'test-event2@example.com',
1778 );
1779 $contact2 = $this->individualCreate($contactParams);
1780 //Create an event with registration end date = 2 week from now.
1781 $params['end_date'] = date('Ymd', strtotime('+2 week'));
1782 $params['registration_end_date'] = date('Ymd', strtotime('+2 week'));
1783 $event2 = $this->eventCreate($params);
1784 $this->participantCreate(array('contact_id' => $contact2, 'event_id' => $event2['id']));
1785
1786 //Assert there is no reminder sent to the contact.
1787 $this->assertCronRuns(array(
1788 array(
1789 'time' => date('Y-m-d'),
1790 'recipients' => array(),
1791 ),
1792 ));
1793
1794 //Modify the sched reminder to be sent 2 week from registration end date.
1795 $this->callAPISuccess('action_schedule', 'create', array(
1796 'id' => $actionSched['id'],
1797 'start_action_offset' => 2,
1798 'start_action_unit' => 'week',
1799 ));
1800
1801 //Contact should receive the reminder now.
1802 $this->assertCronRuns(array(
1803 array(
1804 'time' => date('Y-m-d'),
1805 'recipients' => array(array('test-event2@example.com')),
1806 ),
1807 ));
76ea51c7
JP
1808 }
1809
1810 /**
1811 * Test sched reminder set via start date.
1812 */
d3eae6ea
TO
1813 public function testEventTypeStartDate() {
1814 // Create event+participant with start_date = 20120315, end_date = 20120615.
1815 $participant = $this->createTestObject('CRM_Event_DAO_Participant', array_merge($this->fixtures['participant'], array('status_id' => 2)));
1816 $this->callAPISuccess('Email', 'create', array(
1817 'contact_id' => $participant->contact_id,
1818 'email' => 'test-event@example.com',
1819 ));
1820 $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $participant->contact_id)));
1821
1822 $actionSchedule = $this->fixtures['sched_eventtype_start_1week_before'];
1823 $actionSchedule['entity_value'] = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $participant->event_id, 'event_type_id');
1824 $this->callAPISuccess('action_schedule', 'create', $actionSchedule);
1825
1826 //echo "CREATED\n"; ob_flush(); sleep(20);
1827
1828 // end_date=2012-06-15 ; schedule is 2 weeks before end_date
1829 $this->assertCronRuns(array(
1830 array(
1831 // 2 weeks before
1832 'time' => '2012-03-02 01:00:00',
1833 'recipients' => array(),
1834 ),
1835 array(
1836 // 1 week before
1837 'time' => '2012-03-08 01:00:00',
1838 'recipients' => array(array('test-event@example.com')),
1839 ),
1840 array(
1841 // And then nothing else
1842 'time' => '2012-03-16 01:00:00',
1843 'recipients' => array(),
1844 ),
1845 ));
1846 }
1847
1848 public function testEventTypeEndDateRepeat() {
1849 // Create event+participant with start_date = 20120315, end_date = 20120615.
1850 $participant = $this->createTestObject('CRM_Event_DAO_Participant', array_merge($this->fixtures['participant'], array('status_id' => 2)));
1851 $this->callAPISuccess('Email', 'create', array(
1852 'contact_id' => $participant->contact_id,
1853 'email' => 'test-event@example.com',
1854 ));
1855 $c = $this->callAPISuccess('contact', 'create', array_merge($this->fixtures['contact'], array('contact_id' => $participant->contact_id)));
1856
1857 $actionSchedule = $this->fixtures['sched_eventtype_end_2month_repeat_twice_2_weeks'];
1858 $actionSchedule['entity_value'] = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $participant->event_id, 'event_type_id');
1859 $this->callAPISuccess('action_schedule', 'create', $actionSchedule);
1860
1861 $this->assertCronRuns(array(
1862 array(
1863 // Almost 2 months.
1864 'time' => '2012-08-13 01:00:00',
1865 'recipients' => array(),
1866 ),
1867 array(
1868 // After the 2-month mark, send an email.
1869 'time' => '2012-08-16 01:00:00',
1870 'recipients' => array(array('test-event@example.com')),
1871 ),
1872 array(
1873 // After 2 months and 1 week, don't repeat yet.
1874 'time' => '2012-08-23 02:00:00',
1875 'recipients' => array(),
1876 ),
1877 array(
1878 // After 2 months and 2 weeks
1879 'time' => '2012-08-30 02:00:00',
1880 'recipients' => array(array('test-event@example.com')),
1881 ),
1882 array(
1883 // After 2 months and 4 week
1884 'time' => '2012-09-13 02:00:00',
1885 'recipients' => array(array('test-event@example.com')),
1886 ),
1887 array(
1888 // After 2 months and 6 weeks
1889 'time' => '2012-09-27 01:00:00',
1890 'recipients' => array(),
1891 ),
1892 ));
1893 }
1894
6a488035
TO
1895 // TODO // function testMembershipEndDate_NonMatch() { }
1896 // TODO // function testEventTypeStartDate_Match() { }
1897 // TODO // function testEventTypeEndDate_Match() { }
1898 // TODO // function testEventNameStartDate_Match() { }
1899 // TODO // function testEventNameEndDate_Match() { }
1900
1901 /**
92c99a4a 1902 * Run a series of cron jobs and make an assertion about email deliveries.
6a488035 1903 *
16b10e64
CW
1904 * @param array $cronRuns
1905 * array specifying when to run cron and what messages to expect; each item is an array with keys:
1906 * - time: string, e.g. '2012-06-15 21:00:01'
1907 * - recipients: array(array(string)), list of email addresses which should receive messages
6a488035 1908 */
00be9182 1909 public function assertCronRuns($cronRuns) {
6a488035
TO
1910 foreach ($cronRuns as $cronRun) {
1911 CRM_Utils_Time::setTime($cronRun['time']);
bf308d29 1912 $this->callAPISuccess('job', 'send_reminder', array());
6a488035 1913 $this->mut->assertRecipients($cronRun['recipients']);
f8c3594b
TO
1914 if (array_key_exists('subjects', $cronRun)) {
1915 $this->mut->assertSubjects($cronRun['subjects']);
1916 }
6a488035
TO
1917 $this->mut->clearMessages();
1918 }
1919 }
1920
6a488035
TO
1921 /**
1922 * @var array(DAO_Name => array(int)) List of items to garbage-collect during tearDown
1923 */
1924 private $_testObjects;
1925
1926 /**
1927 * Sets up the fixture, for example, opens a network connection.
92c99a4a 1928 *
6a488035 1929 * This method is called before a test is executed.
6a488035
TO
1930 */
1931 protected function _setUp() {
1932 $this->_testObjects = array();
1933 }
1934
1935 /**
1936 * Tears down the fixture, for example, closes a network connection.
92c99a4a 1937 *
6a488035 1938 * This method is called after a test is executed.
6a488035
TO
1939 */
1940 protected function _tearDown() {
1941 parent::tearDown();
1942 $this->deleteTestObjects();
1943 }
1944
1945 /**
1946 * This is a wrapper for CRM_Core_DAO::createTestObject which tracks
92c99a4a 1947 * created entities and provides for brainless cleanup.
6a488035
TO
1948 *
1949 * @see CRM_Core_DAO::createTestObject
92c99a4a 1950 *
1e1fdcf6
EM
1951 * @param $daoName
1952 * @param array $params
1953 * @param int $numObjects
1954 * @param bool $createOnly
92c99a4a
EM
1955 *
1956 * @return array|NULL|object
6a488035 1957 */
2da40d21 1958 public function createTestObject($daoName, $params = array(), $numObjects = 1, $createOnly = FALSE) {
6a488035
TO
1959 $objects = CRM_Core_DAO::createTestObject($daoName, $params, $numObjects, $createOnly);
1960 if (is_array($objects)) {
1961 $this->registerTestObjects($objects);
0db6c3e1
TO
1962 }
1963 else {
6a488035
TO
1964 $this->registerTestObjects(array($objects));
1965 }
1966 return $objects;
1967 }
1968
1969 /**
5a4f6742
CW
1970 * @param array $objects
1971 * DAO or BAO objects.
6a488035 1972 */
00be9182 1973 public function registerTestObjects($objects) {
6a488035
TO
1974 //if (is_object($objects)) {
1975 // $objects = array($objects);
1976 //}
1977 foreach ($objects as $object) {
1978 $daoName = preg_replace('/_BAO_/', '_DAO_', get_class($object));
1979 $this->_testObjects[$daoName][] = $object->id;
1980 }
1981 }
1982
00be9182 1983 public function deleteTestObjects() {
6a488035
TO
1984 // Note: You might argue that the FK relations between test
1985 // objects could make this problematic; however, it should
1986 // behave intuitively as long as we mentally split our
1987 // test-objects between the "manual/primary records"
1988 // and the "automatic/secondary records"
1989 foreach ($this->_testObjects as $daoName => $daoIds) {
1990 foreach ($daoIds as $daoId) {
1991 CRM_Core_DAO::deleteTestObjects($daoName, array('id' => $daoId));
1992 }
1993 }
1994 $this->_testObjects = array();
1995 }
1996
52f09320
PH
1997 /**
1998 * Test that the various repetition units work correctly.
1999 * CRM-17028
2000 */
2001 public function testRepetitionFrequencyUnit() {
2002 $membershipTypeParams = array(
2003 'duration_interval' => '1',
2004 'duration_unit' => 'year',
2005 'is_active' => 1,
2006 'period_type' => 'rolling',
2007 );
2008 $membershipType = $this->createTestObject('CRM_Member_DAO_MembershipType', $membershipTypeParams);
2009 $interval_units = array('hour', 'day', 'week', 'month', 'year');
2010 foreach ($interval_units as $interval_unit) {
2011 $membershipEndDate = DateTime::createFromFormat('Y-m-d H:i:s', "2013-03-15 00:00:00");
2012 $contactParams = array(
2013 'contact_type' => 'Individual',
2014 'first_name' => 'Test',
2015 'last_name' => "Interval $interval_unit",
2016 'is_deceased' => 0,
2017 );
2018 $contact = $this->createTestObject('CRM_Contact_DAO_Contact', $contactParams);
2019 $this->assertTrue(is_numeric($contact->id));
2020 $emailParams = array(
2021 'contact_id' => $contact->id,
62ca07e7 2022 'is_primary' => 1,
52f09320
PH
2023 'email' => "test-member-{$interval_unit}@example.com",
2024 'location_type_id' => 1,
2025 );
2026 $email = $this->createTestObject('CRM_Core_DAO_Email', $emailParams);
2027 $this->assertTrue(is_numeric($email->id));
2028 $membershipParams = array(
2029 'membership_type_id' => $membershipType->id,
2030 'contact_id' => $contact->id,
2031 'join_date' => '20120315',
2032 'start_date' => '20120315',
2033 'end_date' => '20130315',
2034 'is_override' => 0,
2035 'status_id' => 2,
2036 );
2037 $membershipParams['status-id'] = 1;
2038 $membership = $this->createTestObject('CRM_Member_DAO_Membership', $membershipParams);
2039 $actionScheduleParams = $this->fixtures['sched_on_membership_end_date_repeat_interval'];
2040 $actionScheduleParams['entity_value'] = $membershipType->id;
2041 $actionScheduleParams['repetition_frequency_unit'] = $interval_unit;
2042 $actionScheduleParams['repetition_frequency_interval'] = 2;
2043 $actionSchedule = CRM_Core_BAO_ActionSchedule::add($actionScheduleParams);
2044 $this->assertTrue(is_numeric($actionSchedule->id));
2045 $beforeEndDate = $this->createModifiedDateTime($membershipEndDate, '-1 day');
2046 $beforeFirstUnit = $this->createModifiedDateTime($membershipEndDate, "+1 $interval_unit");
2047 $afterFirstUnit = $this->createModifiedDateTime($membershipEndDate, "+2 $interval_unit");
2048 $cronRuns = array(
2049 array(
2050 'time' => $beforeEndDate->format('Y-m-d H:i:s'),
2051 'recipients' => array(),
2052 ),
2053 array(
2054 'time' => $membershipEndDate->format('Y-m-d H:i:s'),
2055 'recipients' => array(array("test-member-{$interval_unit}@example.com")),
2056 ),
2057 array(
2058 'time' => $beforeFirstUnit->format('Y-m-d H:i:s'),
2059 'recipients' => array(),
2060 ),
2061 array(
2062 'time' => $afterFirstUnit->format('Y-m-d H:i:s'),
2063 'recipients' => array(array("test-member-{$interval_unit}@example.com")),
2064 ),
2065 );
2066 $this->assertCronRuns($cronRuns);
2067 $actionSchedule->delete();
2068 $membership->delete();
2069 }
2070 }
2071
bb3ba83e
AH
2072 /**
2073 * Inherited members without permission to edit the main member contact should
2074 * not get reminders.
2075 *
2076 * However, just because a contact inherits one membership doesn't mean
2077 * reminders for other memberships should be suppressed.
2078 *
2079 * See CRM-14098
2080 */
2081 public function testInheritedMembershipPermissions() {
2082 // Set up common parameters for memberships.
2083 $membershipParams = $this->fixtures['rolling_membership'];
2084 $membershipParams['status_id'] = 1;
2085
2086 $membershipParams['membership_type_id']['relationship_type_id'] = 1;
2087 $membershipParams['membership_type_id']['relationship_direction'] = 'b_a';
2088 $membershipType1 = $this->createTestObject('CRM_Member_DAO_MembershipType', $membershipParams['membership_type_id']);
2089
2090 // We'll create a new membership type that can be held at the same time as
2091 // the first one.
2092 $membershipParams['membership_type_id']['relationship_type_id'] = 'NULL';
2093 $membershipParams['membership_type_id']['relationship_direction'] = 'NULL';
2094 $membershipType2 = $this->createTestObject('CRM_Member_DAO_MembershipType', $membershipParams['membership_type_id']);
2095
2096 // Create the parent membership and contact
2097 $membershipParams['membership_type_id'] = $membershipType1->id;
2098 $mainMembership = $this->createTestObject('CRM_Member_DAO_Membership', $membershipParams);
2099
2100 $contactParams = [
2101 'contact_type' => 'Individual',
2102 'first_name' => 'Mom',
2103 'last_name' => 'Rel',
2104 'is_deceased' => 0,
2105 ];
2106 $this->createTestObject('CRM_Contact_DAO_Contact', array_merge($contactParams, ['id' => $mainMembership->contact_id]));
2107
2108 $emailParams = [
2109 'contact_id' => $mainMembership->contact_id,
2110 'email' => 'test-member@example.com',
2111 'location_type_id' => 1,
2112 'is_primary' => 1,
2113 ];
2114 $email = $this->createTestObject('CRM_Core_DAO_Email', $emailParams);
2115
2116 // Set up contacts and emails for the two children
2117 $contactParams['first_name'] = 'Favorite';
2118 $permChild = $this->createTestObject('CRM_Contact_DAO_Contact', $contactParams);
2119 $emailParams['email'] = 'favorite@example.com';
2120 $emailParams['contact_id'] = $permChild->id;
2121 $this->createTestObject('CRM_Core_DAO_Email', $emailParams);
2122
2123 $contactParams['first_name'] = 'Black Sheep';
2124 $nonPermChild = $this->createTestObject('CRM_Contact_DAO_Contact', $contactParams);
2125 $emailParams['email'] = 'black.sheep@example.com';
2126 $emailParams['contact_id'] = $nonPermChild->id;
2127 $this->createTestObject('CRM_Core_DAO_Email', $emailParams);
2128
2129 // Each child gets a relationship, one with permission to edit the parent. This
2130 // will trigger inherited memberships for the first membership type
2131 $relParams = [
2132 'relationship_type_id' => 1,
2133 'contact_id_a' => $nonPermChild->id,
2134 'contact_id_b' => $mainMembership->contact_id,
2135 'is_active' => 1,
2136 ];
2137 $this->callAPISuccess('relationship', 'create', $relParams);
2138
2139 $relParams['contact_id_a'] = $permChild->id;
2140 $relParams['is_permission_a_b'] = CRM_Contact_BAO_Relationship::EDIT;
2141 $this->callAPISuccess('relationship', 'create', $relParams);
2142
2143 // Mom and Black Sheep get their own memberships of the second type.
2144 $membershipParams['membership_type_id'] = $membershipType2->id;
2145 $membershipParams['owner_membership_id'] = 'NULL';
2146 $membershipParams['contact_id'] = $mainMembership->contact_id;
2147 $this->createTestObject('CRM_Member_DAO_Membership', $membershipParams);
2148
2149 $membershipParams['contact_id'] = $nonPermChild->id;
2150 $this->createTestObject('CRM_Member_DAO_Membership', $membershipParams);
2151
2152 // Test a reminder for the first membership type - that should exclude Black
2153 // Sheep.
2154 $actionSchedule = $this->fixtures['sched_membership_join_2week'];
2155 $actionSchedule['entity_value'] = $membershipType1->id;
2156 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
2157 $this->assertTrue(is_numeric($actionScheduleDao->id));
2158
2159 $this->assertCronRuns([
2160 [
2161 'time' => '2012-03-29 01:00:00',
2162 'recipients' => [['test-member@example.com'], ['favorite@example.com']],
2163 'subjects' => [
2164 'subject sched_membership_join_2week (joined March 15th, 2012)',
2165 'subject sched_membership_join_2week (joined March 15th, 2012)',
2166 ],
2167 ],
2168 ]);
2169
2170 // Test a reminder for the second membership type - that should include
2171 // Black Sheep.
2172 $actionSchedule = $this->fixtures['sched_membership_start_1week'];
2173 $actionSchedule['entity_value'] = $membershipType2->id;
2174 $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionSchedule);
2175 $this->assertTrue(is_numeric($actionScheduleDao->id));
2176
2177 $this->assertCronRuns([
2178 [
2179 'time' => '2012-03-22 01:00:00',
2180 'recipients' => [['test-member@example.com'], ['black.sheep@example.com']],
2181 'subjects' => [
2182 'subject sched_membership_start_1week (joined March 15th, 2012)',
2183 'subject sched_membership_start_1week (joined March 15th, 2012)',
2184 ],
2185 ],
2186 ]);
2187 }
2188
52f09320
PH
2189 public function createModifiedDateTime($origDateTime, $modifyRule) {
2190 $newDateTime = clone($origDateTime);
2191 $newDateTime->modify($modifyRule);
2192 return $newDateTime;
2193 }
2194
6a488035 2195}