handle recurring entity delete
[civicrm-core.git] / CRM / Core / BAO / RecurringEntity.php
CommitLineData
62933949 1<?php
2/*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.4 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2013 |
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/**
29 *
30 * @package CRM
31 * @copyright CiviCRM LLC (c) 2004-2013
32 * $Id$
33 *
34 */
35
36require_once 'packages/When/When.php';
37
38class CRM_Core_BAO_RecurringEntity extends CRM_Core_DAO_RecurringEntity {
84f02991 39
05121fdd 40 public $schedule = array();
41 public $scheduleId = NULL;
84f02991 42 public $scheduleFormValues = array();
72e95527 43
05121fdd 44 public $dateColumns = array();
45 public $overwriteColumns = array();
46 public $intervalDateColumns = array();
05121fdd 47 public $excludeDates = array();
84f02991 48
49 public $linkedEntities = array();
72e95527 50
dc07e5a7 51 public $isRecurringEntityRecord = TRUE;
72e95527 52
84f02991 53 protected $recursion = NULL;
54
62933949 55 static $_tableDAOMapper =
56 array(
50b39b5b 57 'civicrm_event' => 'CRM_Event_DAO_Event',
62933949 58 'civicrm_price_set_entity' => 'CRM_Price_DAO_PriceSetEntity',
59 'civicrm_uf_join' => 'CRM_Core_DAO_UFJoin',
60 'civicrm_tell_friend' => 'CRM_Friend_DAO_Friend',
61 'civicrm_pcp_block' => 'CRM_PCP_DAO_PCPBlock',
50b39b5b 62 'civicrm_activity' => 'CRM_Activity_DAO_Activity',
dc07e5a7 63 'civicrm_activity_contact' => 'CRM_Activity_DAO_ActivityContact',
62933949 64 );
65
84f02991 66
67 static $_updateSkipFields =
68 array(
69 'civicrm_event' => array('start_date', 'end_date'),
70 'civicrm_tell_friend' => array('entity_id'),
71 'civicrm_pcp_block' => array('entity_id'),
72 'civicrm_activity' => array('activity_date_time'),
73 );
83cf188e 74
75 /**
76 * Function to save records in civicrm_recujrring_entity table
77 *
78 * @param array $params reference array contains the values submitted by the form
79 *
80 * @access public
81 * @static
82 *
83 * @return object
84 */
62933949 85 static function add(&$params) {
86 if (CRM_Utils_Array::value('id', $params)) {
87 CRM_Utils_Hook::pre('edit', 'RecurringEntity', $params['id'], $params);
88 }
89 else {
90 CRM_Utils_Hook::pre('create', 'RecurringEntity', NULL, $params);
91 }
92
93 $daoRecurringEntity = new CRM_Core_DAO_RecurringEntity();
94 $daoRecurringEntity->copyValues($params);
95 $result = $daoRecurringEntity->save();
96
97 if (CRM_Utils_Array::value('id', $params)) {
98 CRM_Utils_Hook::post('edit', 'RecurringEntity', $daoRecurringEntity->id, $daoRecurringEntity);
99 }
100 else {
101 CRM_Utils_Hook::post('create', 'RecurringEntity', $daoRecurringEntity->id, $daoRecurringEntity);
102 }
103 return $result;
104 }
105
83cf188e 106 /**
107 * Wrapper for the function add() to add entry in recurring entity
108 *
109 * @param int $parentId Parent entity id
110 * @param int $entityId Child entity id
111 * @param String $entityTable Name of the entity table
112 *
113 * @access public
114 * @static
115 *
116 * @return object
117 */
62933949 118 static function quickAdd($parentId, $entityId, $entityTable) {
119 $params =
120 array(
121 'parent_id' => $parentId,
122 'entity_id' => $entityId,
123 'entity_table' => $entityTable
124 );
125 return self::add($params);
126 }
127
83cf188e 128 /**
129 * This function updates the mode column in the civicrm_recurring_entity table
130 *
131 * @param int $mode Mode of the entity to cascade changes across parent/child relations eg 1 - only this entity, 2 - this and the following entity, 3 - All the entity
132 *
133 * @access public
134 *
135 * @return void
136 */
05121fdd 137 function mode($mode) {
206c0c43 138 if ($this->entity_id && $this->entity_table) {
139 if ($this->find(TRUE)) {
140 $this->mode = $mode;
141 } else {
142 $this->parent_id = $this->entity_id;
143 $this->mode = $mode;
144 }
145 $this->save();
dfbe9b91 146 }
72e95527 147 }
148
83cf188e 149 /**
150 * This function generates all new entities based on object vars
151 *
152 * @return array
153 */
72e95527 154 function generate() {
c09936e1 155 $this->generateRecursiveDates();
c09936e1 156
157 return $this->generateEntities();
158 }
159
83cf188e 160 /**
161 * This function gives call to When library, converts formparams to dbparams,
162 * or if there is repeat configuration saved in civicrm_action_achedule table, takes params from there.
163 * DBparams are finally mapped to When params/criterias
164 *
165 * @return object When object
166 */
dfbe9b91 167 function generateRecursion() {
c09936e1 168 // return if already generated
169 if (is_a($this->recursion, 'When')) {
170 return $this->recursion;
171 }
72e95527 172
173 if ($this->scheduleId) {
174 // get params by ID
84f02991 175 $this->schedule = $this->getScheduleParams($this->scheduleId);
176 } else if (!empty($this->scheduleFormValues)) {
177 $this->schedule = $this->mapFormValuesToDB($this->scheduleFormValues);
72e95527 178 }
c09936e1 179
84f02991 180 if (!empty($this->schedule)) {
181 $this->recursion = $this->getRecursionFromSchedule($this->schedule);
72e95527 182 }
c09936e1 183 return $this->recursion;
184 }
72e95527 185
83cf188e 186 /**
187 * Generate new DAOs and along with entries in civicrm_recurring_entity table
188 *
189 * @return array
190 */
c09936e1 191 function generateEntities() {
dc07e5a7 192 $newEntities = array();
193 $findCriteria = array();
c09936e1 194 if (!empty($this->recursionDates)) {
dc07e5a7 195 if ($this->entity_id) {
196 $findCriteria = array('id' => $this->entity_id);
197
198 // save an entry with initiating entity-id & entity-table
199 if ($this->entity_table && !$this->find(TRUE)) {
200 $this->parent_id = $this->entity_id;
201 $this->save();
202 }
203 }
204 if (empty($findCriteria)) {
205 CRM_Core_Error::fatal("Find criteria missing to generate from. Make sure entity_id and table is set.");
72e95527 206 }
72e95527 207
342c3f9e 208 $count = 0;
c09936e1 209 foreach ($this->recursionDates as $key => $dateCols) {
210 $newCriteria = $dateCols;
211 foreach ($this->overwriteColumns as $col => $val) {
212 $newCriteria[$col] = $val;
213 }
c09936e1 214 $obj = CRM_Core_BAO_RecurringEntity::copyCreateEntity($this->entity_table,
dc07e5a7 215 $findCriteria,
c09936e1 216 $newCriteria,
dc07e5a7 217 $this->isRecurringEntityRecord
c09936e1 218 );
dc07e5a7 219
84f02991 220 if (is_a($obj, 'CRM_Core_DAO') && $obj->id) {
dc07e5a7 221 $newCriteria = array();
342c3f9e 222 $newEntities[$this->entity_table][$count] = $obj->id;
223
dc07e5a7 224 foreach ($this->linkedEntities as $linkedInfo) {
225 foreach ($linkedInfo['linkedColumns'] as $col) {
226 $newCriteria[$col] = $obj->id;
227 }
228 $linkedObj = CRM_Core_BAO_RecurringEntity::copyCreateEntity($linkedInfo['table'],
229 $linkedInfo['findCriteria'],
230 $newCriteria,
231 CRM_Utils_Array::value('isRecurringEntityRecord', $linkedInfo, TRUE)
232 );
342c3f9e 233
84f02991 234 if (is_a($linkedObj, 'CRM_Core_DAO') && $linkedObj->id) {
342c3f9e 235 $newEntities[$linkedInfo['table']][$count] = $linkedObj->id;
236 }
dc07e5a7 237 }
238 }
342c3f9e 239 $count++;
72e95527 240 }
72e95527 241 }
dc07e5a7 242
72e95527 243 return $newEntities;
244 }
245
83cf188e 246 /**
247 * This function iterates through when object criterias and
248 * generates recursive dates based on that
249 *
250 * @return array array of dates
251 */
c09936e1 252 function generateRecursiveDates() {
dfbe9b91 253 $this->generateRecursion();
c09936e1 254
255 $recursionDates = array();
72e95527 256 if (is_a($this->recursion, 'When')) {
84f02991 257 $initialCount = CRM_Utils_Array::value('start_action_offset', $this->scheduleFormValues);
c09936e1 258
259 $exRangeStart = $exRangeEnd = NULL;
260 if (!empty($this->excludeDateRangeColumns)) {
261 $exRangeStart = $this->excludeDateRangeColumns[0];
262 $exRangeEnd = $this->excludeDateRangeColumns[1];
263 }
72e95527 264
265 $count = 1;
266 while ($result = $this->recursion->next()) {
c09936e1 267 $baseDate = CRM_Utils_Date::processDate($result->format('Y-m-d H:i:s'));
268
269 foreach ($this->dateColumns as $col) {
270 $recursionDates[$count][$col] = $baseDate;
271 }
272 foreach ($this->intervalDateColumns as $col => $interval) {
273 $newDate = new DateTime($baseDate);
274 $newDate->add($interval);
275 $recursionDates[$count][$col] = CRM_Utils_Date::processDate($newDate->format('Y-m-d H:i:s'));
276 }
277 if ($exRangeStart) {
278 $exRangeStartDate = CRM_Utils_Date::processDate($recursionDates[$count][$exRangeStart], NULL, FALSE, 'Ymd');
279 $exRangeEndDate = CRM_Utils_Date::processDate($recursionDates[$count][$exRangeEnd], NULL, FALSE, 'Ymd');
280 }
72e95527 281
282 $skip = FALSE;
c09936e1 283 foreach ($this->excludeDates as $exDate) {
284 $exDate = CRM_Utils_Date::processDate($exDate, NULL, FALSE, 'Ymd');
285 if (!$exRangeStart) {
286 if ($exDate == $result->format('Ymd')) {
287 $skip = TRUE;
288 break;
289 }
290 } else {
291 if (($exDate == $exRangeStartDate) ||
292 ($exRangeEndDate && ($exDate > $exRangeStartDate) && ($exDate <= $exRangeEndDate))
293 ) {
294 $skip = TRUE;
295 break;
296 }
72e95527 297 }
298 }
299
300 if ($skip) {
c09936e1 301 unset($recursionDates[$count]);
72e95527 302 if ($initialCount && ($initialCount > 0)) {
303 // lets increase the counter, so we get correct number of occurrences
304 $initialCount++;
305 $this->recursion->count($initialCount);
306 }
307 continue;
308 }
309 $count++;
310 }
311 }
c09936e1 312 $this->recursionDates = $recursionDates;
c09936e1 313
314 return $recursionDates;
72e95527 315 }
316
83cf188e 317 /**
318 * This function gets all the children for that particular parent
319 *
320 * @param int $parentId Parent entity id
321 * @param string $entityTable Name of the entity table
322 * @param boolean $includeParent If true parent id is included in result set and vice versa
323 * @param int $mode ??
324 * @param int $initiatorId ??
325 *
326 * @access public
327 * @static
328 *
329 * @return array an array of child ids
330 */
36b8b5f3 331 static public function getEntitiesForParent($parentId, $entityTable, $includeParent = TRUE, $mode = 3, $initiatorId = NULL) {
62933949 332 $entities = array();
333
36b8b5f3 334 if (!$initiatorId) {
335 $initiatorId = $parentId;
336 }
337
338 $queryParams = array(
339 1 => array($parentId, 'Integer'),
340 2 => array($entityTable, 'String'),
341 3 => array($initiatorId, 'Integer'),
342 );
343
344 if (!$mode) {
60b36f60 345 $mode = CRM_Core_DAO::singleValueQuery("SELECT mode FROM civicrm_recurring_entity WHERE entity_id = %3 AND entity_table = %2", $queryParams);
36b8b5f3 346 }
347
62933949 348 $query = "SELECT *
349 FROM civicrm_recurring_entity
350 WHERE parent_id = %1 AND entity_table = %2";
351 if (!$includeParent) {
36b8b5f3 352 $query .= " AND entity_id != " . ($initiatorId ? "%3" : "%1");
353 }
354
355 if ($mode == '1') { // MODE = SINGLE
356 $query .= " AND entity_id = %3";
357 } else if ($mode == '2') { // MODE = FUTURE
358 $recurringEntityID = CRM_Core_DAO::singleValueQuery("SELECT id FROM civicrm_recurring_entity WHERE entity_id = %3 AND entity_table = %2", $queryParams);
359 if ($recurringEntityID) {
360 $query .= $includeParent ? " AND id >= %4" : " AND id > %4";
361 $query .= " ORDER BY id ASC"; // FIXME: change to order by dates
362 $queryParams[4] = array($recurringEntityID, 'Integer');
363 } else {
364 // something wrong, return empty
365 return array();
366 }
62933949 367 }
62933949 368
36b8b5f3 369 $dao = CRM_Core_DAO::executeQuery($query, $queryParams);
62933949 370 while ($dao->fetch()) {
371 $entities["{$dao->entity_table}_{$dao->entity_id}"]['table'] = $dao->entity_table;
372 $entities["{$dao->entity_table}_{$dao->entity_id}"]['id'] = $dao->entity_id;
373 }
374 return $entities;
375 }
376
83cf188e 377 /**
378 * This function when passed an entity id checks if it has parent and
379 * returns all other entities that are connected to same parent.
380 *
381 * @param int $entityId entity id
382 * @param string $entityTable Entity table name
383 * @param boolean $includeParent Include parent in result set
384 * @param int $mode ??
385 *
386 * @access public
387 * @static
388 *
389 * @return array array of connected ids
390 */
36b8b5f3 391 static public function getEntitiesFor($entityId, $entityTable, $includeParent = TRUE, $mode = 3) {
62933949 392 $parentId = self::getParentFor($entityId, $entityTable);
393 if ($parentId) {
36b8b5f3 394 return self::getEntitiesForParent($parentId, $entityTable, $includeParent, $mode, $entityId);
62933949 395 }
396 return array();
397 }
398
83cf188e 399 /**
400 * This function gets the parent for the entity id passed to it
401 *
402 * @param int $entityId entity ID
403 * @param string $entityTable Entity table name
404 * @param boolean $includeParent Include parent in result set
405 *
406 * @access public
407 * @static
408 *
409 * @return int unsigned $parentId Parent ID
410 */
62933949 411 static public function getParentFor($entityId, $entityTable, $includeParent = TRUE) {
412 $query = "
413 SELECT parent_id
414 FROM civicrm_recurring_entity
415 WHERE entity_id = %1 AND entity_table = %2";
416 if (!$includeParent) {
417 $query .= " AND parent_id != %1";
418 }
419 $parentId =
420 CRM_Core_DAO::singleValueQuery($query,
421 array(
422 1 => array($entityId, 'Integer'),
423 2 => array($entityTable, 'String'),
424 )
425 );
426 return $parentId;
427 }
428
83cf188e 429 /**
430 * This function copies the information from parent entity and creates other entities with same information
431 *
432 * @param string $entityTable Entity table name
433 * @param array $fromCriteria array of all the fields & values on which basis to copy
434 * @param array $newParams array of all the fields & values to be copied besides the other fields
435 * @param type $createRecurringEntity ??
436 *
437 * @access public
438 * @static
439 *
440 * @return object
441 */
62933949 442 static public function copyCreateEntity($entityTable, $fromCriteria, $newParams, $createRecurringEntity = TRUE) {
443 $daoName = self::$_tableDAOMapper[$entityTable];
dc07e5a7 444 if (!$daoName) {
445 CRM_Core_Error::fatal("DAO Mapper missing for $entityTable.");
446 }
62933949 447 $newObject = CRM_Core_DAO::copyGeneric($daoName, $fromCriteria, $newParams);
448
84f02991 449 if (is_a($newObject, 'CRM_Core_DAO') && $newObject->id && $createRecurringEntity) {
62933949 450 $object = new $daoName( );
451 foreach ($fromCriteria as $key => $value) {
452 $object->$key = $value;
453 }
454 $object->find(TRUE);
455
456 CRM_Core_BAO_RecurringEntity::quickAdd($object->id, $newObject->id, $entityTable);
457 }
458 return $newObject;
459 }
460
83cf188e 461 /**
462 * This function acts as a listener to dao->update whenever there is an update,
463 * and the it matched entries in recurring entity, it cascaded the changes across
464 * the related entities
465 *
466 * @param object $obj An object containing data that needs to be updated *
467 * @access public
468 * @static
469 *
470 * @return void
471 */
62933949 472 static public function triggerUpdate($obj) {
60b36f60 473 // if DB version is earlier than 4.6 skip any processing
474 static $currentVer = NULL;
475 if (!$currentVer) {
476 $currentVer = CRM_Core_BAO_Domain::version();
477 }
478 if (version_compare($currentVer, '4.6.alpha1') < 0) {
479 return;
480 }
481
62933949 482 static $processedEntities = array();
483 if (empty($obj->id) || empty($obj->__table)) {
484 return FALSE;
485 }
486 $key = "{$obj->__table}_{$obj->id}";
83cf188e 487
62933949 488 if (array_key_exists($key, $processedEntities)) {
489 // already processed
490 return NULL;
491 }
492
493 // get related entities
36b8b5f3 494 $repeatingEntities = self::getEntitiesFor($obj->id, $obj->__table, FALSE, NULL);
62933949 495 if (empty($repeatingEntities)) {
496 // return if its not a recurring entity parent
497 return NULL;
498 }
36b8b5f3 499 // mark being processed
62933949 500 $processedEntities[$key] = 1;
501
36b8b5f3 502 // to make sure we not copying to source itself
503 unset($repeatingEntities[$key]);
504
505 foreach($repeatingEntities as $key => $val) {
62933949 506 $entityID = $val['id'];
507 $entityTable = $val['table'];
508
509 $processedEntities[$key] = 1;
510
511 if (array_key_exists($entityTable, self::$_tableDAOMapper)) {
84f02991 512 $daoName = self::$_tableDAOMapper[$entityTable];
62933949 513
84f02991 514 $skipData = array();
515 if (array_key_exists($entityTable, self::$_updateSkipFields)) {
516 $skipFields = self::$_updateSkipFields[$entityTable];
517 foreach ($skipFields as $sfield) {
518 $skipData[$sfield] = NULL;
519 }
520 }
62933949 521
36b8b5f3 522 $updateDAO = CRM_Core_DAO::cascadeUpdate($daoName, $obj->id, $entityID, $skipData);
523 CRM_Core_DAO::freeResult();
50b39b5b 524 } else {
525 CRM_Core_Error::fatal("DAO Mapper missing for $entityTable.");
62933949 526 }
527 }
528 // done with processing. lets unset static var.
529 unset($processedEntities);
530 }
531
97c4fe76 532 static public function triggerDelete($obj){
533 // if DB version is earlier than 4.6 skip any processing
534 static $currentVer = NULL;
535 if (!$currentVer) {
536 $currentVer = CRM_Core_BAO_Domain::version();
537 }
538 if (version_compare($currentVer, '4.6.alpha1') < 0) {
539 return;
540 }
541
542 static $processedEntities = array();
543 if (empty($obj->id) || empty($obj->__table)) {
544 return FALSE;
545 }
546 $key = "{$obj->__table}_{$obj->id}";
547 CRM_Core_Error::debug_var('$key', $key);
548
549 if (array_key_exists($key, $processedEntities)) {
550 // already processed
551 return NULL;
552 }
553
554 // mark being processed
555 $processedEntities[$key] = 1;
556
557 $parentID = self::getParentFor($obj->id, $obj->__table, FALSE);
558 if ($parentID) {
559 $dao = new CRM_Core_DAO_RecurringEntity();
560 $dao->entity_id = $obj->id;
561 $dao->entity_table = $obj->__table;
562 $dao->delete();
563 }
564 }
565
83cf188e 566 /**
567 * This function maps values posted from form to civicrm_action_schedule columns
568 *
569 * @param array $formParams and array of form values posted
570 *
571 * @return array
572 */
72e95527 573 function mapFormValuesToDB($formParams = array()){
62933949 574 $dbParams = array();
575 if(CRM_Utils_Array::value('used_for', $formParams)){
576 $dbParams['used_for'] = $formParams['used_for'];
577 }
1b1fcd9e 578
3af75991 579 if(CRM_Utils_Array::value('event_id', $formParams)){
cc0ed5ce 580 $dbParams['entity_value'] = $formParams['event_id'];
b1d1479a 581 }
1b1fcd9e 582
c09936e1 583 if(CRM_Utils_Array::value('repetition_start_date', $formParams)) {
584 $repetitionStartDate = $formParams['repetition_start_date'];
585 if (CRM_Utils_Array::value('repetition_start_date_time', $formParams)){
586 $repetitionStartDate = $repetitionStartDate . " " . $formParams['repetition_start_date_time'];
1b1fcd9e 587 }
c09936e1 588 $repetition_start_date = new DateTime($repetitionStartDate);
589 $repetition_start_date->modify('+1 day');
a1a821bc 590 $dbParams['start_action_date'] = CRM_Utils_Date::processDate($repetition_start_date->format('Y-m-d H:i:s'));
c09936e1 591 }
62933949 592
593 if(CRM_Utils_Array::value('repetition_frequency_unit', $formParams)){
b1d1479a 594 $dbParams['repetition_frequency_unit'] = $formParams['repetition_frequency_unit'];
595 }
62933949 596
597 if(CRM_Utils_Array::value('repetition_frequency_interval', $formParams)){
b1d1479a 598 $dbParams['repetition_frequency_interval'] = $formParams['repetition_frequency_interval'];
599 }
62933949 600
601 //For Repeats on:(weekly case)
b1d1479a 602 if($formParams['repetition_frequency_unit'] == 'week'){
603 if(CRM_Utils_Array::value('start_action_condition', $formParams)){
604 $repeats_on = CRM_Utils_Array::value('start_action_condition', $formParams);
605 $dbParams['start_action_condition'] = implode(",", array_keys($repeats_on));
62933949 606 }
b1d1479a 607 }
62933949 608
609 //For Repeats By:(monthly case)
b1d1479a 610 if($formParams['repetition_frequency_unit'] == 'month'){
611 if($formParams['repeats_by'] == 1){
612 if(CRM_Utils_Array::value('limit_to', $formParams)){
613 $dbParams['limit_to'] = $formParams['limit_to'];
62933949 614 }
b1d1479a 615 }
616 if($formParams['repeats_by'] == 2){
a1a821bc 617 if(CRM_Utils_Array::value('entity_status_1', $formParams) && CRM_Utils_Array::value('entity_status_2', $formParams)){
618 $dbParams['entity_status'] = $formParams['entity_status_1']." ".$formParams['entity_status_2'];
62933949 619 }
620 }
b1d1479a 621 }
62933949 622
623 //For "Ends" - After:
b1d1479a 624 if($formParams['ends'] == 1){
625 if(CRM_Utils_Array::value('start_action_offset', $formParams)){
626 $dbParams['start_action_offset'] = $formParams['start_action_offset'];
62933949 627 }
b1d1479a 628 }
62933949 629
b1d1479a 630 //For "Ends" - On:
631 if($formParams['ends'] == 2){
632 if(CRM_Utils_Array::value('repeat_absolute_date', $formParams)){
633 $dbParams['absolute_date'] = CRM_Utils_Date::processDate($formParams['repeat_absolute_date']);
62933949 634 }
62933949 635 }
b1d1479a 636 return $dbParams;
637 }
62933949 638
83cf188e 639 /**
640 * This function gets all the columns of civicrm_action_schedule table based on id(primary key)
641 *
642 * @param int $scheduleReminderId primary key of civicrm_action_schedule table
643 *
644 * @access public
645 * @static
646 *
647 * @return object
648 */
b1d1479a 649 static public function getScheduleReminderDetailsById($scheduleReminderId){
650 $query = "SELECT *
1b1fcd9e 651 FROM civicrm_action_schedule WHERE 1";
b1d1479a 652 if($scheduleReminderId){
653 $query .= "
1b1fcd9e 654 AND id = %1";
62933949 655 }
b1d1479a 656 $dao = CRM_Core_DAO::executeQuery($query,
1b1fcd9e 657 array(
658 1 => array($scheduleReminderId, 'Integer')
659 )
660 );
b1d1479a 661 $dao->fetch();
662 return $dao;
663 }
1b1fcd9e 664
83cf188e 665 /**
666 * This function is a wrapper of getScheduleReminderDetailsById function
667 *
668 * @param int $scheduleReminderId primary key of civicrm_action_schedule table
669 *
670 * @return array
671 */
84f02991 672 function getScheduleParams($scheduleReminderId) {
673 $scheduleReminderDetails = array();
674 if ($scheduleReminderId){
b1d1479a 675 //Get all the details from schedule reminder table
676 $scheduleReminderDetails = self::getScheduleReminderDetailsById($scheduleReminderId);
677 $scheduleReminderDetails = (array) $scheduleReminderDetails;
62933949 678 }
84f02991 679 return $scheduleReminderDetails;
b1d1479a 680 }
1b1fcd9e 681
83cf188e 682 /**
683 * This function takes criterias saved in civicrm_action_schedule table
684 * and creates recursion rule
685 *
686 * @param array $scheduleReminderDetails array of repeat criterias saved in civicrm_action_schedule table
687 *
688 * @return object When object
689 */
84f02991 690 function getRecursionFromSchedule($scheduleReminderDetails = array()){
b1d1479a 691 $r = new When();
692 //If there is some data for this id
693 if($scheduleReminderDetails['repetition_frequency_unit']){
a1a821bc 694 if($scheduleReminderDetails['start_action_date']){
695 $currDate = date('Y-m-d H:i:s', strtotime($scheduleReminderDetails['start_action_date']));
b1d1479a 696 }else{
62933949 697 $currDate = date("Y-m-d H:i:s");
b1d1479a 698 }
699 $start = new DateTime($currDate);
700 if($scheduleReminderDetails['repetition_frequency_unit']){
701 $repetition_frequency_unit = $scheduleReminderDetails['repetition_frequency_unit'];
702 if($repetition_frequency_unit == "day"){
703 $repetition_frequency_unit = "dai";
62933949 704 }
b1d1479a 705 $repetition_frequency_unit = $repetition_frequency_unit.'ly';
706 $r->recur($start, $repetition_frequency_unit);
707 }
62933949 708
b1d1479a 709 if($scheduleReminderDetails['repetition_frequency_interval']){
710 $r->interval($scheduleReminderDetails['repetition_frequency_interval']);
711 }else{
712 $r->errors[] = 'Repeats every: is a required field';
713 }
62933949 714
b1d1479a 715 //week
716 if($scheduleReminderDetails['repetition_frequency_unit'] == 'week'){
717 if($scheduleReminderDetails['start_action_condition']){
718 $startActionCondition = $scheduleReminderDetails['start_action_condition'];
719 $explodeStartActionCondition = explode(',', $startActionCondition);
720 $buildRuleArray = array();
721 foreach($explodeStartActionCondition as $key => $val){
722 $buildRuleArray[] = strtoupper(substr($val, 0, 2));
62933949 723 }
b1d1479a 724 $r->wkst('MO')->byday($buildRuleArray);
62933949 725 }
b1d1479a 726 }
62933949 727
b1d1479a 728 //month
729 if($scheduleReminderDetails['repetition_frequency_unit'] == 'month'){
a1a821bc 730 if($scheduleReminderDetails['entity_status']){
731 $startActionDate = explode(" ", $scheduleReminderDetails['entity_status']);
b1d1479a 732 switch ($startActionDate[0]) {
1b1fcd9e 733 case 'first':
734 $startActionDate1 = 1;
735 break;
736 case 'second':
737 $startActionDate1 = 2;
738 break;
739 case 'third':
740 $startActionDate1 = 3;
741 break;
742 case 'fourth':
743 $startActionDate1 = 4;
744 break;
745 case 'last':
746 $startActionDate1 = -1;
747 break;
c828f12a 748 }
b1d1479a 749 $concatStartActionDateBits = $startActionDate1.strtoupper(substr($startActionDate[1], 0, 2));
750 $r->byday(array($concatStartActionDateBits));
4cf90acd 751 }else if($scheduleReminderDetails['limit_to']){
752 $r->bymonthday(array($scheduleReminderDetails['limit_to']));
62933949 753 }
b1d1479a 754 }
62933949 755
b1d1479a 756 //Ends
757 if($scheduleReminderDetails['start_action_offset']){
758 if($scheduleReminderDetails['start_action_offset'] > 30){
759 $r->errors[] = 'Occurrences should be less than or equal to 30';
62933949 760 }
b1d1479a 761 $r->count($scheduleReminderDetails['start_action_offset']);
762 }
62933949 763
690bf076 764 if(CRM_Utils_Array::value('absolute_date', $scheduleReminderDetails)) {
b1d1479a 765 $absoluteDate = CRM_Utils_Date::setDateDefaults($scheduleReminderDetails['absolute_date']);
766 $endDate = new DateTime($absoluteDate[0].' '.$absoluteDate[1]);
767 $r->until($endDate);
768 }
769
770 if(!$scheduleReminderDetails['start_action_offset'] && !$scheduleReminderDetails['absolute_date']){
771 $r->errors[] = 'Ends: is a required field';
772 }
1b1fcd9e 773 }else{
774 $r->errors[] = 'Repeats: is a required field';
775 }
b1d1479a 776 return $r;
777 }
83cf188e 778
779 /**
780 * This function gets time difference between the two datetime object
781 *
782 * @param DateTime $startDate Start Date
783 * @param DateTime $endDate End Date
784 *
785 * @access public
786 * @static
787 *
788 * @return object DateTime object which contain time difference
1b1fcd9e 789 */
1b1fcd9e 790 static public function getInterval($startDate, $endDate) {
791 if ($startDate && $endDate) {
792 $startDate = new DateTime($startDate);
793 $endDate = new DateTime($endDate);
794
795 return $startDate->diff($endDate);
fd1abec4 796 }
1b1fcd9e 797 }
798
83cf188e 799 /**
800 * This function deletes all the other entities that are related to it
801 *
802 * @param int $entityId Entity id
803 * @param string $entityTable Name of the entity table
804 *
805 * @access public
806 * @static
807 *
808 * @return boolean|object Returns either boolean value or CRM_Core_DAO_RecurringEntity object
809 */
8dc6e78a 810 static public function delEntityRelations($entityId, $entityTable){
811 if(!$entityId && !$entityTable){
812 return FALSE;
813 }
814 $parentID = self::getParentFor($entityId, $entityTable);
815 if($parentID){
816 $dao = new CRM_Core_DAO_RecurringEntity();
817 $dao->parent_id = $parentID;
818 return $dao->delete();
819 }
820 }
1b1fcd9e 821
fd1abec4 822}