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 | |
36 | require_once 'packages/When/When.php'; |
37 | |
38 | class CRM_Core_BAO_RecurringEntity extends CRM_Core_DAO_RecurringEntity { |
39 | |
40 | static $_tableDAOMapper = |
41 | array( |
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', |
47 | ); |
48 | |
49 | static function add(&$params) { |
50 | if (CRM_Utils_Array::value('id', $params)) { |
51 | CRM_Utils_Hook::pre('edit', 'RecurringEntity', $params['id'], $params); |
52 | } |
53 | else { |
54 | CRM_Utils_Hook::pre('create', 'RecurringEntity', NULL, $params); |
55 | } |
56 | |
57 | $daoRecurringEntity = new CRM_Core_DAO_RecurringEntity(); |
58 | $daoRecurringEntity->copyValues($params); |
59 | $result = $daoRecurringEntity->save(); |
60 | |
61 | if (CRM_Utils_Array::value('id', $params)) { |
62 | CRM_Utils_Hook::post('edit', 'RecurringEntity', $daoRecurringEntity->id, $daoRecurringEntity); |
63 | } |
64 | else { |
65 | CRM_Utils_Hook::post('create', 'RecurringEntity', $daoRecurringEntity->id, $daoRecurringEntity); |
66 | } |
67 | return $result; |
68 | } |
69 | |
70 | static function quickAdd($parentId, $entityId, $entityTable) { |
71 | $params = |
72 | array( |
73 | 'parent_id' => $parentId, |
74 | 'entity_id' => $entityId, |
75 | 'entity_table' => $entityTable |
76 | ); |
77 | return self::add($params); |
78 | } |
79 | |
36b8b5f3 |
80 | // MODE = 3 (ALL) |
81 | static public function getEntitiesForParent($parentId, $entityTable, $includeParent = TRUE, $mode = 3, $initiatorId = NULL) { |
62933949 |
82 | $entities = array(); |
83 | |
36b8b5f3 |
84 | if (!$initiatorId) { |
85 | $initiatorId = $parentId; |
86 | } |
87 | |
88 | $queryParams = array( |
89 | 1 => array($parentId, 'Integer'), |
90 | 2 => array($entityTable, 'String'), |
91 | 3 => array($initiatorId, 'Integer'), |
92 | ); |
93 | |
94 | if (!$mode) { |
95 | $mode = CRM_Core_DAO::singleValueQuery("SELECT cascade_type FROM civicrm_recurring_entity WHERE entity_id = %3 AND entity_table = %2", $queryParams); |
96 | } |
97 | |
62933949 |
98 | $query = "SELECT * |
99 | FROM civicrm_recurring_entity |
100 | WHERE parent_id = %1 AND entity_table = %2"; |
101 | if (!$includeParent) { |
36b8b5f3 |
102 | $query .= " AND entity_id != " . ($initiatorId ? "%3" : "%1"); |
103 | } |
104 | |
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'); |
113 | } else { |
114 | // something wrong, return empty |
115 | return array(); |
116 | } |
62933949 |
117 | } |
62933949 |
118 | |
36b8b5f3 |
119 | $dao = CRM_Core_DAO::executeQuery($query, $queryParams); |
62933949 |
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; |
123 | } |
124 | return $entities; |
125 | } |
126 | |
36b8b5f3 |
127 | static public function getEntitiesFor($entityId, $entityTable, $includeParent = TRUE, $mode = 3) { |
62933949 |
128 | $parentId = self::getParentFor($entityId, $entityTable); |
129 | if ($parentId) { |
36b8b5f3 |
130 | return self::getEntitiesForParent($parentId, $entityTable, $includeParent, $mode, $entityId); |
62933949 |
131 | } |
132 | return array(); |
133 | } |
134 | |
135 | static public function getParentFor($entityId, $entityTable, $includeParent = TRUE) { |
136 | $query = " |
137 | SELECT parent_id |
138 | FROM civicrm_recurring_entity |
139 | WHERE entity_id = %1 AND entity_table = %2"; |
140 | if (!$includeParent) { |
141 | $query .= " AND parent_id != %1"; |
142 | } |
143 | $parentId = |
144 | CRM_Core_DAO::singleValueQuery($query, |
145 | array( |
146 | 1 => array($entityId, 'Integer'), |
147 | 2 => array($entityTable, 'String'), |
148 | ) |
149 | ); |
150 | return $parentId; |
151 | } |
152 | |
153 | //static public function copyCreateEntity('civicrm_event', array('id' => $params['parent_event_id'], $newParams) { |
154 | static public function copyCreateEntity($entityTable, $fromCriteria, $newParams, $createRecurringEntity = TRUE) { |
155 | $daoName = self::$_tableDAOMapper[$entityTable]; |
156 | $newObject = CRM_Core_DAO::copyGeneric($daoName, $fromCriteria, $newParams); |
157 | |
158 | if ($newObject->id && $createRecurringEntity) { |
159 | $object = new $daoName( ); |
160 | foreach ($fromCriteria as $key => $value) { |
161 | $object->$key = $value; |
162 | } |
163 | $object->find(TRUE); |
164 | |
165 | CRM_Core_BAO_RecurringEntity::quickAdd($object->id, $newObject->id, $entityTable); |
166 | } |
167 | return $newObject; |
168 | } |
169 | |
170 | static public function triggerUpdate($obj) { |
171 | static $processedEntities = array(); |
172 | if (empty($obj->id) || empty($obj->__table)) { |
173 | return FALSE; |
174 | } |
175 | $key = "{$obj->__table}_{$obj->id}"; |
176 | |
177 | if (array_key_exists($key, $processedEntities)) { |
178 | // already processed |
179 | return NULL; |
180 | } |
181 | |
182 | // get related entities |
36b8b5f3 |
183 | $repeatingEntities = self::getEntitiesFor($obj->id, $obj->__table, FALSE, NULL); |
62933949 |
184 | if (empty($repeatingEntities)) { |
185 | // return if its not a recurring entity parent |
186 | return NULL; |
187 | } |
36b8b5f3 |
188 | // mark being processed |
62933949 |
189 | $processedEntities[$key] = 1; |
190 | |
36b8b5f3 |
191 | // to make sure we not copying to source itself |
192 | unset($repeatingEntities[$key]); |
193 | |
194 | foreach($repeatingEntities as $key => $val) { |
62933949 |
195 | $entityID = $val['id']; |
196 | $entityTable = $val['table']; |
197 | |
198 | $processedEntities[$key] = 1; |
199 | |
200 | if (array_key_exists($entityTable, self::$_tableDAOMapper)) { |
201 | $daoName = self::$_tableDAOMapper[$entityTable]; |
202 | |
62933949 |
203 | // FIXME: generalize me |
204 | $skipData = array('start_date' => NULL, |
205 | 'end_date' => NULL, |
206 | ); |
207 | |
36b8b5f3 |
208 | $updateDAO = CRM_Core_DAO::cascadeUpdate($daoName, $obj->id, $entityID, $skipData); |
209 | CRM_Core_DAO::freeResult(); |
62933949 |
210 | } |
211 | } |
212 | // done with processing. lets unset static var. |
213 | unset($processedEntities); |
214 | } |
215 | |
216 | static function mapFormValuesToDB($formParams = array()){ |
217 | $dbParams = array(); |
218 | if(CRM_Utils_Array::value('used_for', $formParams)){ |
219 | $dbParams['used_for'] = $formParams['used_for']; |
220 | } |
221 | |
222 | if(CRM_Utils_Array::value('parent_event_id', $formParams)){ |
223 | $dbParams['entity_value'] = $formParams['parent_event_id']; |
224 | } |
225 | |
226 | if(CRM_Utils_Array::value('repetition_frequency_unit', $formParams)){ |
227 | $dbParams['repetition_frequency_unit'] = $formParams['repetition_frequency_unit']; |
228 | } |
229 | |
230 | if(CRM_Utils_Array::value('repetition_frequency_interval', $formParams)){ |
231 | $dbParams['repetition_frequency_interval'] = $formParams['repetition_frequency_interval']; |
232 | } |
233 | |
234 | //For Repeats on:(weekly case) |
235 | if($formParams['repetition_frequency_unit'] == 'week'){ |
236 | if(CRM_Utils_Array::value('start_action_condition', $formParams)){ |
237 | $repeats_on = CRM_Utils_Array::value('start_action_condition', $formParams); |
238 | $dbParams['start_action_condition'] = implode(",", array_keys($repeats_on)); |
239 | } |
240 | } |
241 | |
242 | //For Repeats By:(monthly case) |
243 | if($formParams['repetition_frequency_unit'] == 'month'){ |
244 | if($formParams['repeats_by'] == 1){ |
245 | if(CRM_Utils_Array::value('limit_to', $formParams)){ |
246 | $dbParams['limit_to'] = $formParams['limit_to']; |
247 | } |
248 | } |
249 | if($formParams['repeats_by'] == 2){ |
250 | if(CRM_Utils_Array::value('start_action_date_1', $formParams) && CRM_Utils_Array::value('start_action_date_2', $formParams)){ |
251 | $dbParams['start_action_date'] = $formParams['start_action_date_1']." ".$formParams['start_action_date_2']; |
252 | } |
253 | } |
254 | } |
255 | |
256 | //For "Ends" - After: |
257 | if($formParams['ends'] == 1){ |
258 | if(CRM_Utils_Array::value('start_action_offset', $formParams)){ |
259 | $dbParams['start_action_offset'] = $formParams['start_action_offset']; |
260 | } |
261 | } |
262 | |
263 | //For "Ends" - On: |
264 | if($formParams['ends'] == 2){ |
265 | if(CRM_Utils_Array::value('repeat_absolute_date', $formParams)){ |
266 | $dbParams['absolute_date'] = CRM_Utils_Date::processDate($formParams['repeat_absolute_date']); |
267 | } |
268 | } |
269 | return $dbParams; |
270 | } |
271 | |
272 | static public function getScheduleReminderDetailsById($scheduleReminderId){ |
273 | $query = "SELECT * |
274 | FROM civicrm_action_schedule WHERE 1"; |
275 | if($scheduleReminderId){ |
276 | $query .= " |
277 | AND id = %1"; |
278 | } |
279 | $dao = CRM_Core_DAO::executeQuery($query, |
280 | array( |
281 | 1 => array($scheduleReminderId, 'Integer') |
282 | ) |
283 | ); |
284 | $dao->fetch(); |
285 | return $dao; |
286 | } |
287 | |
288 | static function getRecursionFromReminder($scheduleReminderId){ |
289 | if($scheduleReminderId){ |
290 | //Get all the details from schedule reminder table |
291 | $scheduleReminderDetails = self::getScheduleReminderDetailsById($scheduleReminderId); |
292 | $scheduleReminderDetails = (array) $scheduleReminderDetails; |
293 | $recursionDetails = self::getRecursionFromReminderByDBParams($scheduleReminderDetails); |
294 | } |
295 | return $recursionDetails; |
296 | } |
297 | |
298 | static function getRecursionFromReminderByDBParams($scheduleReminderDetails = array()){ |
299 | $r = new When(); |
300 | //If there is some data for this id |
301 | if($scheduleReminderDetails['repetition_frequency_unit']){ |
302 | $currDate = date("Y-m-d H:i:s"); |
303 | $start = new DateTime($currDate); |
304 | if($scheduleReminderDetails['repetition_frequency_unit']){ |
305 | $repetition_frequency_unit = $scheduleReminderDetails['repetition_frequency_unit']; |
306 | if($repetition_frequency_unit == "day"){ |
307 | $repetition_frequency_unit = "dai"; |
308 | } |
309 | $repetition_frequency_unit = $repetition_frequency_unit.'ly'; |
310 | $r->recur($start, $repetition_frequency_unit); |
311 | } |
312 | |
313 | if($scheduleReminderDetails['repetition_frequency_interval']){ |
314 | $r->interval($scheduleReminderDetails['repetition_frequency_interval']); |
fd1abec4 |
315 | }else{ |
316 | $r->errors[] = 'Repeats every: is a required field'; |
62933949 |
317 | } |
318 | |
319 | //week |
320 | if($scheduleReminderDetails['repetition_frequency_unit'] == 'week'){ |
321 | if($scheduleReminderDetails['start_action_condition']){ |
322 | $startActionCondition = $scheduleReminderDetails['start_action_condition']; |
323 | $explodeStartActionCondition = explode(',', $startActionCondition); |
324 | $buildRuleArray = array(); |
325 | foreach($explodeStartActionCondition as $key => $val){ |
326 | $buildRuleArray[] = strtoupper(substr($val, 0, 2)); |
327 | } |
62933949 |
328 | $r->wkst('MO')->byday($buildRuleArray); |
329 | } |
330 | } |
331 | |
332 | //month |
333 | if($scheduleReminderDetails['repetition_frequency_unit'] == 'month'){ |
334 | if($scheduleReminderDetails['limit_to']){ |
335 | $r->bymonthday(array($scheduleReminderDetails['limit_to'])); |
336 | } |
337 | if($scheduleReminderDetails['start_action_date']){ |
338 | $startActionDate = explode(" ", $scheduleReminderDetails['start_action_date']); |
339 | switch ($startActionDate[0]) { |
340 | case 'first': |
341 | $startActionDate1 = 1; |
342 | break; |
343 | case 'second': |
344 | $startActionDate1 = 2; |
345 | break; |
346 | case 'third': |
347 | $startActionDate1 = 3; |
348 | break; |
349 | case 'fourth': |
350 | $startActionDate1 = 4; |
351 | break; |
352 | case 'last': |
353 | $startActionDate1 = -1; |
354 | break; |
355 | } |
356 | $concatStartActionDateBits = $startActionDate1.strtoupper(substr($startActionDate[1], 0, 2)); |
357 | $r->byday(array($concatStartActionDateBits)); |
358 | } |
359 | } |
360 | |
361 | //Ends |
362 | if($scheduleReminderDetails['start_action_offset']){ |
c828f12a |
363 | if($scheduleReminderDetails['start_action_offset'] > 30){ |
364 | $r->errors[] = 'Occurrences should be less than or equal to 30'; |
365 | } |
62933949 |
366 | $r->count($scheduleReminderDetails['start_action_offset']); |
367 | } |
368 | |
369 | if($scheduleReminderDetails['absolute_date']){ |
370 | $absoluteDate = CRM_Utils_Date::setDateDefaults($scheduleReminderDetails['absolute_date']); |
371 | $endDate = new DateTime($absoluteDate[0].' '.$absoluteDate[1]); |
372 | $r->until($endDate); |
373 | } |
374 | |
375 | if(!$scheduleReminderDetails['start_action_offset'] && !$scheduleReminderDetails['absolute_date']){ |
fd1abec4 |
376 | $r->errors[] = 'Ends: is a required field'; |
62933949 |
377 | } |
fd1abec4 |
378 | }else{ |
379 | $r->errors[] = 'Repeats: is a required field'; |
62933949 |
380 | } |
381 | return $r; |
382 | } |
383 | |
fd1abec4 |
384 | /* |
385 | * Get Reminder id based on event id |
386 | */ |
387 | static public function getReminderDetailsByEventId($eventId, $used_for){ |
388 | if($eventId){ |
389 | $query = " |
390 | SELECT * |
391 | FROM civicrm_action_schedule |
392 | WHERE entity_value = %1"; |
393 | if($used_for){ |
394 | $query .= " AND used_for = %2"; |
395 | } |
396 | $params = array( |
397 | 1 => array($eventId, 'Integer'), |
398 | 2 => array($used_for, 'String') |
399 | ); |
400 | $dao = CRM_Core_DAO::executeQuery($query, $params); |
401 | $dao->fetch(); |
402 | } |
403 | return $dao; |
2eeee284 |
404 | } |
405 | |
406 | static public function generateRecursions($recursionObj, $params=array()){ |
407 | $newParams = $recursionResult = array(); |
408 | if($recursionObj && !empty($params)){ |
409 | //Proceed only if these keys are found in array |
410 | if(CRM_Utils_Array::value('parent_event_start_date', $params) && CRM_Utils_Array::value('parent_event_id', $params)){ |
411 | $count = 1; |
412 | while($result = $recursionObj->next()){ |
413 | $newParams['start_date'] = CRM_Utils_Date::processDate($result->format('Y-m-d H:i:s')); |
414 | $parentStartDate = new DateTime($params['parent_event_start_date']); |
415 | //If events with end date |
416 | if(CRM_Utils_Array::value('parent_event_end_date', $params)){ |
417 | $parentEndDate = new DateTime($params['parent_event_end_date']); |
418 | $interval = $parentStartDate->diff($parentEndDate); |
419 | $end_date = new DateTime($newParams['start_date']); |
420 | $end_date->add($interval); |
421 | $newParams['end_date'] = CRM_Utils_Date::processDate($end_date->format('Y-m-d H:i:s')); |
422 | $recursionResult[$count]['end_date'] = $newParams['end_date']; |
423 | } |
424 | $recursionResult[$count]['start_date'] = $newParams['start_date']; |
425 | $count++; |
426 | } |
427 | } |
428 | } |
429 | return $recursionResult; |
430 | } |
431 | |
432 | static public function addEntityThroughRecursion($recursionResult = array(), $currEntityID){ |
433 | if(!empty($recursionResult) && $currEntityID){ |
434 | $parent_event_id = CRM_Core_BAO_RecurringEntity::getParentFor($currEntityID, 'civicrm_event'); |
435 | if(!$parent_event_id){ |
436 | $parent_event_id = $currEntityID; |
437 | } |
438 | |
439 | // add first entry just for parent |
440 | CRM_Core_BAO_RecurringEntity::quickAdd($parent_event_id, $parent_event_id, 'civicrm_event'); |
441 | |
442 | foreach ($recursionResult as $key => $value) { |
443 | $newEventObj = CRM_Core_BAO_RecurringEntity::copyCreateEntity('civicrm_event', |
444 | array('id' => $parent_event_id), |
445 | $value); |
446 | |
447 | CRM_Core_BAO_RecurringEntity::copyCreateEntity('civicrm_price_set_entity', |
448 | array( |
449 | 'entity_id' => $parent_event_id, |
450 | 'entity_table' => 'civicrm_event' |
451 | ), |
452 | array( |
453 | 'entity_id' => $newEventObj->id |
454 | ), |
455 | FALSE |
456 | ); |
457 | |
458 | CRM_Core_BAO_RecurringEntity::copyCreateEntity('civicrm_uf_join', |
459 | array( |
460 | 'entity_id' => $parent_event_id, |
461 | 'entity_table' => 'civicrm_event' |
462 | ), |
463 | array( |
464 | 'entity_id' => $newEventObj->id |
465 | ), |
466 | FALSE |
467 | ); |
468 | |
469 | CRM_Core_BAO_RecurringEntity::copyCreateEntity('civicrm_tell_friend', |
470 | array( |
471 | 'entity_id' => $parent_event_id, |
472 | 'entity_table' => 'civicrm_event' |
473 | ), |
474 | array( |
475 | 'entity_id' => $newEventObj->id |
476 | ) |
477 | ); |
478 | |
479 | CRM_Core_BAO_RecurringEntity::copyCreateEntity('civicrm_pcp_block', |
480 | array( |
481 | 'entity_id' => $parent_event_id, |
482 | 'entity_table' => 'civicrm_event' |
483 | ), |
484 | array( |
485 | 'entity_id' => $newEventObj->id |
486 | ) |
487 | ); |
488 | } |
489 | } |
490 | } |
62933949 |
491 | |
fd1abec4 |
492 | } |