Commit | Line | Data |
---|---|---|
6a488035 TO |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
39de6fd5 | 4 | | CiviCRM version 4.6 | |
6a488035 | 5 | +--------------------------------------------------------------------+ |
e7112fa7 | 6 | | Copyright CiviCRM LLC (c) 2004-2015 | |
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 TO |
27 | |
28 | /** | |
1d86918a | 29 | * Class CRM_Core_Payment_BaseIPN. |
6a488035 TO |
30 | */ |
31 | class CRM_Core_Payment_BaseIPN { | |
32 | ||
33 | static $_now = NULL; | |
8196c759 | 34 | |
c8aa607b | 35 | /** |
36 | * Input parameters from payment processor. Store these so that | |
37 | * the code does not need to keep retrieving from the http request | |
38 | * @var array | |
39 | */ | |
40 | protected $_inputParameters = array(); | |
41 | ||
937cf542 EM |
42 | protected $_isRecurring = FALSE; |
43 | ||
44 | protected $_isFirstOrLastRecurringPayment = FALSE; | |
353ffa53 | 45 | |
8196c759 | 46 | /** |
fe482240 | 47 | * Constructor. |
8196c759 | 48 | */ |
00be9182 | 49 | public function __construct() { |
6a488035 TO |
50 | self::$_now = date('YmdHis'); |
51 | } | |
52 | ||
c8aa607b | 53 | /** |
fe482240 | 54 | * Store input array on the class. |
77b97be7 | 55 | * |
c8aa607b | 56 | * @param array $parameters |
77b97be7 EM |
57 | * |
58 | * @throws CRM_Core_Exception | |
c8aa607b | 59 | */ |
00be9182 | 60 | public function setInputParameters($parameters) { |
22e263ad | 61 | if (!is_array($parameters)) { |
cc0c30cc | 62 | throw new CRM_Core_Exception('Invalid input parameters'); |
c8aa607b | 63 | } |
64 | $this->_inputParameters = $parameters; | |
65 | } | |
353ffa53 | 66 | |
8196c759 | 67 | /** |
1d86918a EM |
68 | * Validate incoming data. |
69 | * | |
70 | * This function is intended to ensure that incoming data matches | |
8196c759 | 71 | * It provides a form of pseudo-authentication - by checking the calling fn already knows |
72 | * the correct contact id & contribution id (this can be problematic when that has changed in | |
73 | * the meantime for transactions that are delayed & contacts are merged in-between. e.g | |
74 | * Paypal allows you to resend Instant Payment Notifications if you, for example, moved site | |
75 | * and didn't update your IPN URL. | |
76 | * | |
6a0b768e TO |
77 | * @param array $input |
78 | * Interpreted values from the values returned through the IPN. | |
79 | * @param array $ids | |
80 | * More interpreted values (ids) from the values returned through the IPN. | |
81 | * @param array $objects | |
82 | * An empty array that will be populated with loaded object. | |
83 | * @param bool $required | |
84 | * Boolean Return FALSE if the relevant objects don't exist. | |
85 | * @param int $paymentProcessorID | |
86 | * Id of the payment processor ID in use. | |
1d86918a | 87 | * |
5c766a0b | 88 | * @return bool |
8196c759 | 89 | */ |
00be9182 | 90 | public function validateData(&$input, &$ids, &$objects, $required = TRUE, $paymentProcessorID = NULL) { |
6a488035 TO |
91 | |
92 | // make sure contact exists and is valid | |
5a9c68ac | 93 | $contact = new CRM_Contact_BAO_Contact(); |
6a488035 TO |
94 | $contact->id = $ids['contact']; |
95 | if (!$contact->find(TRUE)) { | |
92fcb95f | 96 | CRM_Core_Error::debug_log_message("Could not find contact record: {$ids['contact']} in IPN request: " . print_r($input, TRUE)); |
6a488035 TO |
97 | echo "Failure: Could not find contact record: {$ids['contact']}<p>"; |
98 | return FALSE; | |
99 | } | |
100 | ||
101 | // make sure contribution exists and is valid | |
5a9c68ac | 102 | $contribution = new CRM_Contribute_BAO_Contribution(); |
6a488035 TO |
103 | $contribution->id = $ids['contribution']; |
104 | if (!$contribution->find(TRUE)) { | |
92fcb95f | 105 | CRM_Core_Error::debug_log_message("Could not find contribution record: {$contribution->id} in IPN request: " . print_r($input, TRUE)); |
6a488035 TO |
106 | echo "Failure: Could not find contribution record for {$contribution->id}<p>"; |
107 | return FALSE; | |
108 | } | |
109 | $contribution->receive_date = CRM_Utils_Date::isoToMysql($contribution->receive_date); | |
110 | ||
111 | $objects['contact'] = &$contact; | |
112 | $objects['contribution'] = &$contribution; | |
113 | if (!$this->loadObjects($input, $ids, $objects, $required, $paymentProcessorID)) { | |
114 | return FALSE; | |
115 | } | |
a284891b EM |
116 | //the process is that the loadObjects is kind of hacked by loading the objects for the original contribution and then somewhat inconsistently using them for the |
117 | //current contribution. Here we ensure that the original contribution is available to the complete transaction function | |
118 | //we don't want to fix this in the payment processor classes because we would have to fix all of them - so better to fix somewhere central | |
119 | if (isset($objects['contributionRecur'])) { | |
120 | $objects['first_contribution'] = $objects['contribution']; | |
121 | } | |
6a488035 TO |
122 | return TRUE; |
123 | } | |
124 | ||
8196c759 | 125 | /** |
fe482240 | 126 | * Load objects related to contribution. |
6a488035 TO |
127 | * |
128 | * @input array information from Payment processor | |
dd244018 EM |
129 | * |
130 | * @param $input | |
8196c759 | 131 | * @param array $ids |
132 | * @param array $objects | |
6a0b768e TO |
133 | * @param bool $required |
134 | * @param int $paymentProcessorID | |
8196c759 | 135 | * @param array $error_handling |
dd244018 | 136 | * |
5c766a0b | 137 | * @return bool |
6a488035 | 138 | */ |
00be9182 | 139 | public function loadObjects(&$input, &$ids, &$objects, $required, $paymentProcessorID, $error_handling = NULL) { |
6a488035 TO |
140 | if (empty($error_handling)) { |
141 | // default options are that we log an error & echo it out | |
142 | // note that we should refactor this error handling into error code @ some point | |
143 | // but for now setting up enough separation so we can do unit tests | |
144 | $error_handling = array( | |
145 | 'log_error' => 1, | |
146 | 'echo_error' => 1, | |
147 | ); | |
148 | } | |
149 | $ids['paymentProcessor'] = $paymentProcessorID; | |
150 | if (is_a($objects['contribution'], 'CRM_Contribute_BAO_Contribution')) { | |
151 | $contribution = &$objects['contribution']; | |
152 | } | |
153 | else { | |
154 | //legacy support - functions are 'used' to be able to pass in a DAO | |
155 | $contribution = new CRM_Contribute_BAO_Contribution(); | |
156 | $contribution->id = CRM_Utils_Array::value('contribution', $ids); | |
157 | $contribution->find(TRUE); | |
158 | $objects['contribution'] = &$contribution; | |
159 | } | |
160 | try { | |
161 | $success = $contribution->loadRelatedObjects($input, $ids, $required); | |
162 | } | |
353ffa53 | 163 | catch (Exception $e) { |
cc0c30cc | 164 | $success = FALSE; |
a7488080 | 165 | if (!empty($error_handling['log_error'])) { |
6a488035 TO |
166 | CRM_Core_Error::debug_log_message($e->getMessage()); |
167 | } | |
a7488080 | 168 | if (!empty($error_handling['echo_error'])) { |
6c552737 | 169 | echo $e->getMessage(); |
6a488035 | 170 | } |
a7488080 | 171 | if (!empty($error_handling['return_error'])) { |
6a488035 TO |
172 | return array( |
173 | 'is_error' => 1, | |
174 | 'error_message' => ($e->getMessage()), | |
175 | ); | |
176 | } | |
177 | } | |
178 | $objects = array_merge($objects, $contribution->_relatedObjects); | |
179 | return $success; | |
180 | } | |
181 | ||
8196c759 | 182 | /** |
fe482240 | 183 | * Set contribution to failed. |
28de42d1 | 184 | * |
8196c759 | 185 | * @param array $objects |
186 | * @param object $transaction | |
187 | * @param array $input | |
28de42d1 | 188 | * |
5c766a0b | 189 | * @return bool |
8196c759 | 190 | */ |
00be9182 | 191 | public function failed(&$objects, &$transaction, $input = array()) { |
6a488035 TO |
192 | $contribution = &$objects['contribution']; |
193 | $memberships = array(); | |
a7488080 | 194 | if (!empty($objects['membership'])) { |
6a488035 TO |
195 | $memberships = &$objects['membership']; |
196 | if (is_numeric($memberships)) { | |
197 | $memberships = array($objects['membership']); | |
198 | } | |
199 | } | |
200 | ||
201 | $addLineItems = FALSE; | |
202 | if (empty($contribution->id)) { | |
203 | $addLineItems = TRUE; | |
204 | } | |
205 | $participant = &$objects['participant']; | |
206 | ||
71d085fe | 207 | //CRM-15546 |
353ffa53 TO |
208 | $contributionStatuses = CRM_Core_PseudoConstant::get('CRM_Contribute_DAO_Contribution', 'contribution_status_id', array( |
209 | 'labelColumn' => 'name', | |
af9b09df | 210 | 'flip' => 1, |
353ffa53 | 211 | )); |
5a9c68ac PJ |
212 | $contribution->receive_date = CRM_Utils_Date::isoToMysql($contribution->receive_date); |
213 | $contribution->receipt_date = CRM_Utils_Date::isoToMysql($contribution->receipt_date); | |
214 | $contribution->thankyou_date = CRM_Utils_Date::isoToMysql($contribution->thankyou_date); | |
71d085fe | 215 | $contribution->contribution_status_id = $contributionStatuses['Failed']; |
6a488035 TO |
216 | $contribution->save(); |
217 | ||
28de42d1 | 218 | // Add line items for recurring payments. |
a7488080 | 219 | if (!empty($objects['contributionRecur']) && $objects['contributionRecur']->id && $addLineItems) { |
e577770c | 220 | CRM_Contribute_BAO_ContributionRecur::addRecurLineItems($objects['contributionRecur']->id, $contribution); |
6a488035 TO |
221 | } |
222 | ||
8381af80 | 223 | //add new soft credit against current contribution id and |
6357981e | 224 | //copy initial contribution custom fields for recurring contributions |
a7488080 | 225 | if (!empty($objects['contributionRecur']) && $objects['contributionRecur']->id) { |
e577770c EM |
226 | CRM_Contribute_BAO_ContributionRecur::addrecurSoftCredit($objects['contributionRecur']->id, $contribution->id); |
227 | CRM_Contribute_BAO_ContributionRecur::copyCustomValues($objects['contributionRecur']->id, $contribution->id); | |
6357981e PJ |
228 | } |
229 | ||
a7488080 | 230 | if (empty($input['skipComponentSync'])) { |
6a488035 | 231 | if (!empty($memberships)) { |
5968aa47 | 232 | // if transaction is failed then set "Cancelled" as membership status |
353ffa53 TO |
233 | $membershipStatuses = CRM_Core_PseudoConstant::get('CRM_Member_DAO_Membership', 'status_id', array( |
234 | 'labelColumn' => 'name', | |
af9b09df | 235 | 'flip' => 1, |
353ffa53 | 236 | )); |
6a488035 TO |
237 | foreach ($memberships as $membership) { |
238 | if ($membership) { | |
71d085fe | 239 | $membership->status_id = $membershipStatuses['Cancelled']; |
6a488035 | 240 | $membership->save(); |
d63f4fc3 | 241 | |
6a488035 | 242 | //update related Memberships. |
71d085fe | 243 | $params = array('status_id' => $membershipStatuses['Cancelled']); |
6a488035 TO |
244 | CRM_Member_BAO_Membership::updateRelatedMemberships($membership->id, $params); |
245 | } | |
246 | } | |
247 | } | |
d63f4fc3 | 248 | |
6a488035 | 249 | if ($participant) { |
353ffa53 TO |
250 | $participantStatuses = CRM_Core_PseudoConstant::get('CRM_Event_DAO_Participant', 'status_id', array( |
251 | 'labelColumn' => 'name', | |
af9b09df | 252 | 'flip' => 1, |
353ffa53 | 253 | )); |
71d085fe | 254 | $participant->status_id = $participantStatuses['Cancelled']; |
6a488035 TO |
255 | $participant->save(); |
256 | } | |
257 | } | |
258 | ||
259 | $transaction->commit(); | |
260 | CRM_Core_Error::debug_log_message("Setting contribution status to failed"); | |
261 | //echo "Success: Setting contribution status to failed<p>"; | |
262 | return TRUE; | |
263 | } | |
264 | ||
8196c759 | 265 | /** |
fe482240 | 266 | * Handled pending contribution status. |
1d86918a | 267 | * |
8196c759 | 268 | * @param array $objects |
269 | * @param object $transaction | |
1d86918a | 270 | * |
5c766a0b | 271 | * @return bool |
8196c759 | 272 | */ |
00be9182 | 273 | public function pending(&$objects, &$transaction) { |
6a488035 TO |
274 | $transaction->commit(); |
275 | CRM_Core_Error::debug_log_message("returning since contribution status is pending"); | |
276 | echo "Success: Returning since contribution status is pending<p>"; | |
277 | return TRUE; | |
278 | } | |
279 | ||
6c786a9b | 280 | /** |
1d86918a EM |
281 | * Process cancelled payment outcome. |
282 | * | |
6c786a9b EM |
283 | * @param $objects |
284 | * @param $transaction | |
285 | * @param array $input | |
286 | * | |
287 | * @return bool | |
288 | */ | |
00be9182 | 289 | public function cancelled(&$objects, &$transaction, $input = array()) { |
6a488035 TO |
290 | $contribution = &$objects['contribution']; |
291 | $memberships = &$objects['membership']; | |
292 | if (is_numeric($memberships)) { | |
293 | $memberships = array($objects['membership']); | |
294 | } | |
295 | ||
296 | $participant = &$objects['participant']; | |
297 | $addLineItems = FALSE; | |
298 | if (empty($contribution->id)) { | |
299 | $addLineItems = TRUE; | |
300 | } | |
353ffa53 TO |
301 | $contributionStatuses = CRM_Core_PseudoConstant::get('CRM_Contribute_DAO_Contribution', 'contribution_status_id', array( |
302 | 'labelColumn' => 'name', | |
af9b09df | 303 | 'flip' => 1, |
353ffa53 | 304 | )); |
71d085fe | 305 | $contribution->contribution_status_id = $contributionStatuses['Cancelled']; |
6a488035 TO |
306 | $contribution->cancel_date = self::$_now; |
307 | $contribution->cancel_reason = CRM_Utils_Array::value('reasonCode', $input); | |
308 | $contribution->receive_date = CRM_Utils_Date::isoToMysql($contribution->receive_date); | |
309 | $contribution->receipt_date = CRM_Utils_Date::isoToMysql($contribution->receipt_date); | |
310 | $contribution->thankyou_date = CRM_Utils_Date::isoToMysql($contribution->thankyou_date); | |
311 | $contribution->save(); | |
312 | ||
313 | //add lineitems for recurring payments | |
a7488080 | 314 | if (!empty($objects['contributionRecur']) && $objects['contributionRecur']->id && $addLineItems) { |
e577770c | 315 | CRM_Contribute_BAO_ContributionRecur::addRecurLineItems($objects['contributionRecur']->id, $contribution); |
6a488035 TO |
316 | } |
317 | ||
8381af80 | 318 | //add new soft credit against current $contribution and |
6357981e | 319 | //copy initial contribution custom fields for recurring contributions |
a7488080 | 320 | if (!empty($objects['contributionRecur']) && $objects['contributionRecur']->id) { |
e577770c EM |
321 | CRM_Contribute_BAO_ContributionRecur::addrecurSoftCredit($objects['contributionRecur']->id, $contribution->id); |
322 | CRM_Contribute_BAO_ContributionRecur::copyCustomValues($objects['contributionRecur']->id, $contribution->id); | |
6357981e PJ |
323 | } |
324 | ||
a7488080 | 325 | if (empty($input['skipComponentSync'])) { |
6a488035 | 326 | if (!empty($memberships)) { |
353ffa53 TO |
327 | $membershipStatuses = CRM_Core_PseudoConstant::get('CRM_Member_DAO_Membership', 'status_id', array( |
328 | 'labelColumn' => 'name', | |
af9b09df | 329 | 'flip' => 1, |
353ffa53 | 330 | )); |
6a488035 TO |
331 | foreach ($memberships as $membership) { |
332 | if ($membership) { | |
71d085fe | 333 | $membership->status_id = $membershipStatuses['Cancelled']; |
6a488035 | 334 | $membership->save(); |
d63f4fc3 | 335 | |
6a488035 | 336 | //update related Memberships. |
71d085fe | 337 | $params = array('status_id' => $membershipStatuses['Cancelled']); |
6a488035 TO |
338 | CRM_Member_BAO_Membership::updateRelatedMemberships($membership->id, $params); |
339 | } | |
340 | } | |
341 | } | |
d63f4fc3 | 342 | |
6a488035 | 343 | if ($participant) { |
353ffa53 TO |
344 | $participantStatuses = CRM_Core_PseudoConstant::get('CRM_Event_DAO_Participant', 'status_id', array( |
345 | 'labelColumn' => 'name', | |
af9b09df | 346 | 'flip' => 1, |
353ffa53 | 347 | )); |
71d085fe | 348 | $participant->status_id = $participantStatuses['Cancelled']; |
6a488035 TO |
349 | $participant->save(); |
350 | } | |
351 | } | |
352 | $transaction->commit(); | |
353 | CRM_Core_Error::debug_log_message("Setting contribution status to cancelled"); | |
354 | //echo "Success: Setting contribution status to cancelled<p>"; | |
355 | return TRUE; | |
356 | } | |
357 | ||
6c786a9b | 358 | /** |
1d86918a EM |
359 | * Rollback unhandled outcomes. |
360 | * | |
6c786a9b EM |
361 | * @param $objects |
362 | * @param $transaction | |
363 | * | |
364 | * @return bool | |
365 | */ | |
00be9182 | 366 | public function unhandled(&$objects, &$transaction) { |
6a488035 | 367 | $transaction->rollback(); |
2d8851f6 EM |
368 | CRM_Core_Error::debug_log_message("returning since contribution status: is not handled"); |
369 | echo "Failure: contribution status is not handled<p>"; | |
6a488035 TO |
370 | return FALSE; |
371 | } | |
372 | ||
6c786a9b | 373 | /** |
3ccde016 | 374 | * Jumbled up function. |
1d86918a | 375 | * |
3ccde016 EM |
376 | * The purpose of this function is to transition a pending transaction to Completed including updating any |
377 | * related entities. | |
378 | * | |
379 | * It has been overloaded to also add recurring transactions to the database, cloning the original transaction and | |
380 | * updating related entities. | |
381 | * | |
382 | * It is recommended to avoid calling this function directly and call the api functions: | |
383 | * - contribution.completetransaction | |
384 | * - contribution.repeattransaction | |
385 | * | |
386 | * These functions are the focus of testing efforts and more accurately reflect the division of roles | |
387 | * (the job of the IPN class is to determine the outcome, transaction id, invoice id & to validate the source | |
388 | * and from there it should be possible to pass off transaction management.) | |
389 | * | |
390 | * This function has been problematic for some time but there are now several tests via the api_v3_Contribution test | |
391 | * and the Paypal & Authorize.net IPN tests so any refactoring should be done in conjunction with those. | |
392 | * | |
393 | * This function needs to have the 'body' moved to the CRM_Contribution_BAO_Contribute class and to undergo | |
394 | * refactoring to separate the complete transaction and repeat transaction functionality into separate functions with | |
395 | * a shared function that updates related components. | |
396 | * | |
397 | * Note that it is not necessary payment processor extension to implement an IPN class now. In general the code on the | |
398 | * IPN class is better accessed through the api which de-jumbles it a bit. | |
399 | * | |
400 | * e.g the payment class can have a function like (based on Omnipay extension): | |
401 | * | |
402 | * public function handlePaymentNotification() { | |
403 | * $response = $this->getValidatedOutcome(); | |
404 | * if ($response->isSuccessful()) { | |
405 | * try { | |
406 | * // @todo check if it is a repeat transaction & call repeattransaction instead. | |
407 | * civicrm_api3('contribution', 'completetransaction', array('id' => $this->transaction_id)); | |
408 | * } | |
409 | * catch (CiviCRM_API3_Exception $e) { | |
410 | * if (!stristr($e->getMessage(), 'Contribution already completed')) { | |
411 | * $this->handleError('error', $this->transaction_id . $e->getMessage(), 'ipn_completion', 9000, 'An error may | |
412 | * have occurred. Please check your receipt is correct'); | |
413 | * $this->redirectOrExit('success'); | |
414 | * } | |
415 | * elseif ($this->transaction_id) { | |
416 | * civicrm_api3('contribution', 'create', array('id' => $this->transaction_id, 'contribution_status_id' => | |
417 | * 'Failed')); | |
418 | * } | |
419 | * | |
420 | * @param array $input | |
421 | * @param array $ids | |
422 | * @param array $objects | |
6c786a9b EM |
423 | * @param $transaction |
424 | * @param bool $recur | |
425 | */ | |
00be9182 | 426 | public function completeTransaction(&$input, &$ids, &$objects, &$transaction, $recur = FALSE) { |
db59bb73 EM |
427 | $isRecurring = $this->_isRecurring; |
428 | $isFirstOrLastRecurringPayment = $this->_isFirstOrLastRecurringPayment; | |
6a488035 | 429 | $contribution = &$objects['contribution']; |
a284891b | 430 | |
db59bb73 EM |
431 | CRM_Contribute_BAO_Contribution::completeOrder($input, $ids, $objects, $transaction, $recur, $contribution, |
432 | $isRecurring, $isFirstOrLastRecurringPayment); | |
6a488035 TO |
433 | } |
434 | ||
6c786a9b | 435 | /** |
1d86918a EM |
436 | * Get site billing ID. |
437 | * | |
438 | * @param array $ids | |
6c786a9b EM |
439 | * |
440 | * @return bool | |
441 | */ | |
00be9182 | 442 | public function getBillingID(&$ids) { |
6a488035 | 443 | // get the billing location type |
180409a4 | 444 | $locationTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id', array(), 'validate'); |
1d86918a | 445 | // CRM-8108 remove the ts around the Billing location type |
6a488035 TO |
446 | //$ids['billing'] = array_search( ts('Billing'), $locationTypes ); |
447 | $ids['billing'] = array_search('Billing', $locationTypes); | |
448 | if (!$ids['billing']) { | |
449 | CRM_Core_Error::debug_log_message(ts('Please set a location type of %1', array(1 => 'Billing'))); | |
450 | echo "Failure: Could not find billing location type<p>"; | |
451 | return FALSE; | |
452 | } | |
453 | return TRUE; | |
454 | } | |
455 | ||
c490a46a | 456 | /** |
1d86918a EM |
457 | * Send receipt from contribution. |
458 | * | |
db59bb73 EM |
459 | * @deprecated |
460 | * | |
1d86918a | 461 | * Note that the compose message part has been moved to contribution |
6a488035 TO |
462 | * In general LoadObjects is called first to get the objects but the composeMessageArray function now calls it |
463 | * | |
6a0b768e TO |
464 | * @param array $input |
465 | * Incoming data from Payment processor. | |
466 | * @param array $ids | |
467 | * Related object IDs. | |
6c786a9b | 468 | * @param $objects |
6a0b768e TO |
469 | * @param array $values |
470 | * Values related to objects that have already been loaded. | |
471 | * @param bool $recur | |
472 | * Is it part of a recurring contribution. | |
473 | * @param bool $returnMessageText | |
474 | * Should text be returned instead of sent. This. | |
16b10e64 | 475 | * is because the function is also used to generate pdfs |
6c786a9b | 476 | * |
c490a46a | 477 | * @return array |
6c786a9b | 478 | */ |
00be9182 | 479 | public function sendMail(&$input, &$ids, &$objects, &$values, $recur = FALSE, $returnMessageText = FALSE) { |
db59bb73 | 480 | return CRM_Contribute_BAO_Contribution::sendMail($input, $ids, $objects, $values, $recur, $returnMessageText); |
6a488035 TO |
481 | } |
482 | ||
b2b0530a | 483 | } |