3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.4 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2013 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
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. |
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. |
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 +--------------------------------------------------------------------+
31 * @copyright CiviCRM LLC (c) 2004-2013
36 require_once 'packages/When/When.php';
38 class CRM_Core_BAO_RecurringEntity
extends CRM_Core_DAO_RecurringEntity
{
40 static $_tableDAOMapper =
42 'civicrm_event' => 'CRM_Event_DAO_Event',
43 'civicrm_price_set_entity' => 'CRM_Price_DAO_PriceSetEntity',
44 'civicrm_uf_join' => 'CRM_Core_DAO_UFJoin',
45 'civicrm_tell_friend' => 'CRM_Friend_DAO_Friend',
46 'civicrm_pcp_block' => 'CRM_PCP_DAO_PCPBlock',
49 static function add(&$params) {
50 if (CRM_Utils_Array
::value('id', $params)) {
51 CRM_Utils_Hook
::pre('edit', 'RecurringEntity', $params['id'], $params);
54 CRM_Utils_Hook
::pre('create', 'RecurringEntity', NULL, $params);
57 $daoRecurringEntity = new CRM_Core_DAO_RecurringEntity();
58 $daoRecurringEntity->copyValues($params);
59 $result = $daoRecurringEntity->save();
61 if (CRM_Utils_Array
::value('id', $params)) {
62 CRM_Utils_Hook
::post('edit', 'RecurringEntity', $daoRecurringEntity->id
, $daoRecurringEntity);
65 CRM_Utils_Hook
::post('create', 'RecurringEntity', $daoRecurringEntity->id
, $daoRecurringEntity);
70 static function quickAdd($parentId, $entityId, $entityTable) {
73 'parent_id' => $parentId,
74 'entity_id' => $entityId,
75 'entity_table' => $entityTable
77 return self
::add($params);
81 static public function getEntitiesForParent($parentId, $entityTable, $includeParent = TRUE, $mode = 3, $initiatorId = NULL) {
85 $initiatorId = $parentId;
89 1 => array($parentId, 'Integer'),
90 2 => array($entityTable, 'String'),
91 3 => array($initiatorId, 'Integer'),
95 $mode = CRM_Core_DAO
::singleValueQuery("SELECT mode FROM civicrm_recurring_entity WHERE entity_id = %3 AND entity_table = %2", $queryParams);
99 FROM civicrm_recurring_entity
100 WHERE parent_id = %1 AND entity_table = %2";
101 if (!$includeParent) {
102 $query .= " AND entity_id != " . ($initiatorId ?
"%3" : "%1");
105 if ($mode == '1') { // MODE = SINGLE
106 $query .= " AND entity_id = %3";
107 } else if ($mode == '2') { // MODE = FUTURE
108 $recurringEntityID = CRM_Core_DAO
::singleValueQuery("SELECT id FROM civicrm_recurring_entity WHERE entity_id = %3 AND entity_table = %2", $queryParams);
109 if ($recurringEntityID) {
110 $query .= $includeParent ?
" AND id >= %4" : " AND id > %4";
111 $query .= " ORDER BY id ASC"; // FIXME: change to order by dates
112 $queryParams[4] = array($recurringEntityID, 'Integer');
114 // something wrong, return empty
119 $dao = CRM_Core_DAO
::executeQuery($query, $queryParams);
120 while ($dao->fetch()) {
121 $entities["{$dao->entity_table}_{$dao->entity_id}"]['table'] = $dao->entity_table
;
122 $entities["{$dao->entity_table}_{$dao->entity_id}"]['id'] = $dao->entity_id
;
127 static public function getEntitiesFor($entityId, $entityTable, $includeParent = TRUE, $mode = 3) {
128 $parentId = self
::getParentFor($entityId, $entityTable);
130 return self
::getEntitiesForParent($parentId, $entityTable, $includeParent, $mode, $entityId);
135 static public function getParentFor($entityId, $entityTable, $includeParent = TRUE) {
138 FROM civicrm_recurring_entity
139 WHERE entity_id = %1 AND entity_table = %2";
140 if (!$includeParent) {
141 $query .= " AND parent_id != %1";
144 CRM_Core_DAO
::singleValueQuery($query,
146 1 => array($entityId, 'Integer'),
147 2 => array($entityTable, 'String'),
153 static public function copyCreateEntity($entityTable, $fromCriteria, $newParams, $createRecurringEntity = TRUE) {
154 $daoName = self
::$_tableDAOMapper[$entityTable];
155 $newObject = CRM_Core_DAO
::copyGeneric($daoName, $fromCriteria, $newParams);
157 if ($newObject->id
&& $createRecurringEntity) {
158 $object = new $daoName( );
159 foreach ($fromCriteria as $key => $value) {
160 $object->$key = $value;
164 CRM_Core_BAO_RecurringEntity
::quickAdd($object->id
, $newObject->id
, $entityTable);
169 static public function triggerUpdate($obj) {
170 // if DB version is earlier than 4.6 skip any processing
171 static $currentVer = NULL;
173 $currentVer = CRM_Core_BAO_Domain
::version();
175 if (version_compare($currentVer, '4.6.alpha1') < 0) {
179 static $processedEntities = array();
180 if (empty($obj->id
) ||
empty($obj->__table
)) {
183 $key = "{$obj->__table}_{$obj->id}";
185 if (array_key_exists($key, $processedEntities)) {
190 // get related entities
191 $repeatingEntities = self
::getEntitiesFor($obj->id
, $obj->__table
, FALSE, NULL);
192 if (empty($repeatingEntities)) {
193 // return if its not a recurring entity parent
196 // mark being processed
197 $processedEntities[$key] = 1;
199 // to make sure we not copying to source itself
200 unset($repeatingEntities[$key]);
202 foreach($repeatingEntities as $key => $val) {
203 $entityID = $val['id'];
204 $entityTable = $val['table'];
206 $processedEntities[$key] = 1;
208 if (array_key_exists($entityTable, self
::$_tableDAOMapper)) {
209 $daoName = self
::$_tableDAOMapper[$entityTable];
211 // FIXME: generalize me
212 $skipData = array('start_date' => NULL,
216 $updateDAO = CRM_Core_DAO
::cascadeUpdate($daoName, $obj->id
, $entityID, $skipData);
217 CRM_Core_DAO
::freeResult();
220 // done with processing. lets unset static var.
221 unset($processedEntities);
224 static function mapFormValuesToDB($formParams = array()){
226 if(CRM_Utils_Array
::value('used_for', $formParams)){
227 $dbParams['used_for'] = $formParams['used_for'];
230 if(CRM_Utils_Array
::value('parent_event_id', $formParams)){
231 $dbParams['entity_value'] = $formParams['parent_event_id'];
234 if(CRM_Utils_Array
::value('repetition_start_date', $formParams) &&
235 CRM_Utils_Array
::value('repetition_start_date_time', $formParams)){
236 $repetition_start_date = new DateTime($formParams['repetition_start_date']." ".$formParams['repetition_start_date_time']);
237 $repetition_start_date->modify('+1 day');
238 $dbParams['entity_status'] = CRM_Utils_Date
::processDate($repetition_start_date->format('Y-m-d H:i:s'));
241 if(CRM_Utils_Array
::value('repetition_frequency_unit', $formParams)){
242 $dbParams['repetition_frequency_unit'] = $formParams['repetition_frequency_unit'];
245 if(CRM_Utils_Array
::value('repetition_frequency_interval', $formParams)){
246 $dbParams['repetition_frequency_interval'] = $formParams['repetition_frequency_interval'];
249 //For Repeats on:(weekly case)
250 if($formParams['repetition_frequency_unit'] == 'week'){
251 if(CRM_Utils_Array
::value('start_action_condition', $formParams)){
252 $repeats_on = CRM_Utils_Array
::value('start_action_condition', $formParams);
253 $dbParams['start_action_condition'] = implode(",", array_keys($repeats_on));
257 //For Repeats By:(monthly case)
258 if($formParams['repetition_frequency_unit'] == 'month'){
259 if($formParams['repeats_by'] == 1){
260 if(CRM_Utils_Array
::value('limit_to', $formParams)){
261 $dbParams['limit_to'] = $formParams['limit_to'];
264 if($formParams['repeats_by'] == 2){
265 if(CRM_Utils_Array
::value('start_action_date_1', $formParams) && CRM_Utils_Array
::value('start_action_date_2', $formParams)){
266 $dbParams['start_action_date'] = $formParams['start_action_date_1']." ".$formParams['start_action_date_2'];
271 //For "Ends" - After:
272 if($formParams['ends'] == 1){
273 if(CRM_Utils_Array
::value('start_action_offset', $formParams)){
274 $dbParams['start_action_offset'] = $formParams['start_action_offset'];
279 if($formParams['ends'] == 2){
280 if(CRM_Utils_Array
::value('repeat_absolute_date', $formParams)){
281 $dbParams['absolute_date'] = CRM_Utils_Date
::processDate($formParams['repeat_absolute_date']);
287 static public function getScheduleReminderDetailsById($scheduleReminderId){
289 FROM civicrm_action_schedule WHERE 1";
290 if($scheduleReminderId){
294 $dao = CRM_Core_DAO
::executeQuery($query,
296 1 => array($scheduleReminderId, 'Integer')
303 static function getRecursionFromReminder($scheduleReminderId){
304 if($scheduleReminderId){
305 //Get all the details from schedule reminder table
306 $scheduleReminderDetails = self
::getScheduleReminderDetailsById($scheduleReminderId);
307 $scheduleReminderDetails = (array) $scheduleReminderDetails;
308 $recursionDetails = self
::getRecursionFromReminderByDBParams($scheduleReminderDetails);
310 return $recursionDetails;
313 static function getRecursionFromReminderByDBParams($scheduleReminderDetails = array()){
315 //If there is some data for this id
316 if($scheduleReminderDetails['repetition_frequency_unit']){
317 if($scheduleReminderDetails['entity_status']){
318 $currDate = date('Y-m-d H:i:s', strtotime($scheduleReminderDetails['entity_status']));
320 $currDate = date("Y-m-d H:i:s");
322 $start = new DateTime($currDate);
323 if($scheduleReminderDetails['repetition_frequency_unit']){
324 $repetition_frequency_unit = $scheduleReminderDetails['repetition_frequency_unit'];
325 if($repetition_frequency_unit == "day"){
326 $repetition_frequency_unit = "dai";
328 $repetition_frequency_unit = $repetition_frequency_unit.'ly';
329 $r->recur($start, $repetition_frequency_unit);
332 if($scheduleReminderDetails['repetition_frequency_interval']){
333 $r->interval($scheduleReminderDetails['repetition_frequency_interval']);
335 $r->errors
[] = 'Repeats every: is a required field';
339 if($scheduleReminderDetails['repetition_frequency_unit'] == 'week'){
340 if($scheduleReminderDetails['start_action_condition']){
341 $startActionCondition = $scheduleReminderDetails['start_action_condition'];
342 $explodeStartActionCondition = explode(',', $startActionCondition);
343 $buildRuleArray = array();
344 foreach($explodeStartActionCondition as $key => $val){
345 $buildRuleArray[] = strtoupper(substr($val, 0, 2));
347 $r->wkst('MO')->byday($buildRuleArray);
352 if($scheduleReminderDetails['repetition_frequency_unit'] == 'month'){
353 if($scheduleReminderDetails['start_action_date']){
354 $startActionDate = explode(" ", $scheduleReminderDetails['start_action_date']);
355 switch ($startActionDate[0]) {
357 $startActionDate1 = 1;
360 $startActionDate1 = 2;
363 $startActionDate1 = 3;
366 $startActionDate1 = 4;
369 $startActionDate1 = -1;
372 $concatStartActionDateBits = $startActionDate1.strtoupper(substr($startActionDate[1], 0, 2));
373 $r->byday(array($concatStartActionDateBits));
374 }else if($scheduleReminderDetails['limit_to']){
375 $r->bymonthday(array($scheduleReminderDetails['limit_to']));
380 if($scheduleReminderDetails['start_action_offset']){
381 if($scheduleReminderDetails['start_action_offset'] > 30){
382 $r->errors
[] = 'Occurrences should be less than or equal to 30';
384 $r->count($scheduleReminderDetails['start_action_offset']);
387 if($scheduleReminderDetails['absolute_date']){
388 $absoluteDate = CRM_Utils_Date
::setDateDefaults($scheduleReminderDetails['absolute_date']);
389 $endDate = new DateTime($absoluteDate[0].' '.$absoluteDate[1]);
393 if(!$scheduleReminderDetails['start_action_offset'] && !$scheduleReminderDetails['absolute_date']){
394 $r->errors
[] = 'Ends: is a required field';
397 $r->errors
[] = 'Repeats: is a required field';
403 * Get Reminder id based on event id
405 static public function getReminderDetailsByEventId($eventId, $used_for){
409 FROM civicrm_action_schedule
410 WHERE entity_value = %1";
412 $query .= " AND used_for = %2";
415 1 => array($eventId, 'Integer'),
416 2 => array($used_for, 'String')
418 $dao = CRM_Core_DAO
::executeQuery($query, $params);
424 static public function getInterval($startDate, $endDate) {
425 if ($startDate && $endDate) {
426 $startDate = new DateTime($startDate);
427 $endDate = new DateTime($endDate);
429 return $startDate->diff($endDate);
433 static public function generateRecursions($recursionObj, $params = array(), $excludeDates = array()) {
434 $newParams = $recursionResult = array();
435 if ($recursionObj && !empty($params)) {
436 $initialCount = CRM_Utils_Array
::value('start_action_offset', $params);
437 $interval = CRM_Utils_Array
::value('interval', $params);
440 while ($result = $recursionObj->next()) {
441 $recursionResult[$count]['start_date'] = CRM_Utils_Date
::processDate($result->format('Y-m-d H:i:s'));
444 $endDate = new DateTime($recursionResult[$count]['start_date']);
445 $endDate->add($interval);
446 $recursionResult[$count]['end_date'] = CRM_Utils_Date
::processDate($endDate->format('Y-m-d H:i:s'));
450 foreach ($excludeDates as $date) {
451 $date = CRM_Utils_Date
::processDate($date, NULL, FALSE, 'Ymd');
452 if (($date == $result->format('Ymd')) ||
453 ($endDate && ($date > $result->format('Ymd')) && ($date <= $endDate->format('Ymd')))
461 unset($recursionResult[$count]);
462 if ($initialCount && ($initialCount > 0)) {
463 // lets increase the counter, so we get correct number of occurrences
465 $recursionObj->count($initialCount);
472 return $recursionResult;
476 static public function delEntityRelations($entityId, $entityTable){
477 if(!$entityId && !$entityTable){
480 $parentID = self
::getParentFor($entityId, $entityTable);
482 $dao = new CRM_Core_DAO_RecurringEntity();
483 $dao->parent_id
= $parentID;
484 return $dao->delete();