Merge pull request #5680 from elinw/restauthenticationjoomla
[civicrm-core.git] / CRM / Contribute / Form / UpdateSubscription.php
... / ...
CommitLineData
1<?php
2/*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.6 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2015 |
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-2015
32 * $Id$
33 *
34 */
35
36/**
37 * This class generates form components generic to recurring contributions
38 *
39 * It delegates the work to lower level subclasses and integrates the changes
40 * back in. It also uses a lot of functionality with the CRM API's, so any change
41 * made here could potentially affect the API etc. Be careful, be aware, use unit tests.
42 *
43 */
44class CRM_Contribute_Form_UpdateSubscription extends CRM_Core_Form {
45
46 /**
47 * The recurring contribution id, used when editing the recurring contribution
48 *
49 * @var int
50 */
51 protected $_crid = NULL;
52
53 protected $_coid = NULL;
54
55 protected $_subscriptionDetails = NULL;
56
57 protected $_selfService = FALSE;
58
59 public $_paymentProcessor = NULL;
60
61 public $_paymentProcessorObj = NULL;
62
63 /**
64 * The id of the contact associated with this recurring contribution.
65 *
66 * @var int
67 */
68 public $_contactID;
69
70 public function preProcess() {
71
72 $this->_crid = CRM_Utils_Request::retrieve('crid', 'Integer', $this, FALSE);
73 if ($this->_crid) {
74 $this->_paymentProcessor = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_crid, 'recur', 'info');
75 $this->_paymentProcessorObj = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_crid, 'recur', 'obj');
76 $this->_subscriptionDetails = CRM_Contribute_BAO_ContributionRecur::getSubscriptionDetails($this->_crid);
77 }
78
79 $this->_coid = CRM_Utils_Request::retrieve('coid', 'Integer', $this, FALSE);
80 if ($this->_coid) {
81 $this->_paymentProcessor = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_coid, 'contribute', 'info');
82 $this->_paymentProcessorObj = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_coid, 'contribute', 'obj');
83 $this->_subscriptionDetails = CRM_Contribute_BAO_ContributionRecur::getSubscriptionDetails($this->_coid, 'contribution');
84 }
85 elseif ($this->_crid) {
86 $this->_coid = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $this->_crid, 'id', 'contribution_recur_id');
87 }
88
89 if ((!$this->_crid && !$this->_coid) ||
90 ($this->_subscriptionDetails == CRM_Core_DAO::$_nullObject)
91 ) {
92 CRM_Core_Error::fatal('Required information missing.');
93 }
94
95 if ($this->_subscriptionDetails->membership_id && $this->_subscriptionDetails->auto_renew) {
96 CRM_Core_Error::fatal(ts('You cannot update the subscription.'));
97 }
98
99 if (!CRM_Core_Permission::check('edit contributions')) {
100 $userChecksum = CRM_Utils_Request::retrieve('cs', 'String', $this, FALSE);
101 if (!CRM_Contact_BAO_Contact_Utils::validChecksum($this->_subscriptionDetails->contact_id, $userChecksum)) {
102 CRM_Core_Error::fatal(ts('You do not have permission to update subscription.'));
103 }
104 $this->_selfService = TRUE;
105 }
106 $this->assign('self_service', $this->_selfService);
107
108 if (!$this->_paymentProcessorObj->isSupported('changeSubscriptionAmount')) {
109 $userAlert = ts('Updates made using this form will change the recurring contribution information stored in your CiviCRM database, but will NOT be sent to the payment processor. You must enter the same changes using the payment processor web site.');
110 CRM_Core_Session::setStatus($userAlert, ts('Warning'), 'alert');
111 }
112
113 $this->assign('isChangeSupported', $this->_paymentProcessorObj->isSupported('changeSubscriptionAmount'));
114 $this->assign('paymentProcessor', $this->_paymentProcessor);
115 $this->assign('frequency_unit', $this->_subscriptionDetails->frequency_unit);
116 $this->assign('frequency_interval', $this->_subscriptionDetails->frequency_interval);
117
118 if ($this->_subscriptionDetails->contact_id) {
119 list($this->_donorDisplayName, $this->_donorEmail) = CRM_Contact_BAO_Contact::getContactDetails($this->_subscriptionDetails->contact_id);
120 }
121
122 CRM_Utils_System::setTitle(ts('Update Recurring Contribution'));
123
124 // handle context redirection
125 CRM_Contribute_BAO_ContributionRecur::setSubscriptionContext();
126 }
127
128 /**
129 * Set default values for the form. Note that in edit/view mode
130 * the default values are retrieved from the database
131 *
132 *
133 * @return void
134 */
135 public function setDefaultValues() {
136
137 $this->_defaults = array();
138 $this->_defaults['amount'] = $this->_subscriptionDetails->amount;
139 $this->_defaults['installments'] = $this->_subscriptionDetails->installments;
140 $this->_defaults['is_notify'] = 1;
141
142 return $this->_defaults;
143 }
144
145 /**
146 * Actually build the components of the form.
147 *
148 * @return void
149 */
150 public function buildQuickForm() {
151 // CRM-16398: If current recurring contribution got > 1 lineitems then make amount field readonly
152 $amtAttr = array('size' => 20);
153 $lineItems = CRM_Price_BAO_LineItem::getLineItemsByContributionID($this->_coid);
154 if (count($lineItems) > 1) {
155 $amtAttr += array('readonly' => TRUE);
156 }
157 $this->addMoney('amount', ts('Recurring Contribution Amount'), TRUE, $amtAttr,
158 TRUE, 'currency', $this->_subscriptionDetails->currency, TRUE
159 );
160
161 $this->add('text', 'installments', ts('Number of Installments'), array('size' => 20), TRUE);
162
163 if ($this->_donorEmail) {
164 $this->add('checkbox', 'is_notify', ts('Notify Contributor?'));
165 }
166
167 $type = 'next';
168 if ($this->_selfService) {
169 $type = 'submit';
170 }
171
172 // define the buttons
173 $this->addButtons(array(
174 array(
175 'type' => $type,
176 'name' => ts('Save'),
177 'isDefault' => TRUE,
178 ),
179 array(
180 'type' => 'cancel',
181 'name' => ts('Cancel'),
182 ),
183 )
184 );
185 }
186
187 /**
188 * called after the user submits the form.
189 *
190 *
191 * @return void
192 */
193 public function postProcess() {
194 // store the submitted values in an array
195 $params = $this->exportValues();
196
197 if ($this->_selfService && $this->_donorEmail) {
198 // for self service force notify
199 $params['is_notify'] = 1;
200 }
201
202 // if this is an update of an existing recurring contribution, pass the ID
203 $params['id'] = $this->_subscriptionDetails->recur_id;
204 $message = '';
205
206 $params['subscriptionId'] = $this->_subscriptionDetails->subscription_id;
207 $updateSubscription = TRUE;
208 if ($this->_paymentProcessorObj->isSupported('changeSubscriptionAmount')) {
209 $updateSubscription = $this->_paymentProcessorObj->changeSubscriptionAmount($message, $params);
210 }
211 if (is_a($updateSubscription, 'CRM_Core_Error')) {
212 CRM_Core_Error::displaySessionError($updateSubscription);
213 $status = ts('Could not update the Recurring contribution details');
214 $msgTitle = ts('Update Error');
215 $msgType = 'error';
216 }
217 elseif ($updateSubscription) {
218 // save the changes
219 $result = CRM_Contribute_BAO_ContributionRecur::add($params);
220 $status = ts('Recurring contribution has been updated to: %1, every %2 %3(s) for %4 installments.',
221 array(
222 1 => CRM_Utils_Money::format($params['amount'], $this->_subscriptionDetails->currency),
223 2 => $this->_subscriptionDetails->frequency_interval,
224 3 => $this->_subscriptionDetails->frequency_unit,
225 4 => $params['installments'],
226 )
227 );
228
229 $msgTitle = ts('Update Success');
230 $msgType = 'success';
231 $msg = ts('Recurring Contribution Updated');
232 $contactID = $this->_subscriptionDetails->contact_id;
233
234 if ($this->_subscriptionDetails->amount != $params['amount']) {
235 $message .= "<br /> " . ts("Recurring contribution amount has been updated from %1 to %2 for this subscription.",
236 array(
237 1 => CRM_Utils_Money::format($this->_subscriptionDetails->amount, $this->_subscriptionDetails->currency),
238 2 => CRM_Utils_Money::format($params['amount'], $this->_subscriptionDetails->currency),
239 )) . ' ';
240 if ($this->_subscriptionDetails->amount < $params['amount']) {
241 $msg = ts('Recurring Contribution Updated - increased installment amount');
242 }
243 else {
244 $msg = ts('Recurring Contribution Updated - decreased installment amount');
245 }
246 }
247
248 if ($this->_subscriptionDetails->installments != $params['installments']) {
249 $message .= "<br /> " . ts("Recurring contribution installments have been updated from %1 to %2 for this subscription.", array(
250 1 => $this->_subscriptionDetails->installments,
251 2 => $params['installments'],
252 )) . ' ';
253 }
254
255 $activityParams = array(
256 'source_contact_id' => $contactID,
257 'activity_type_id' => CRM_Core_OptionGroup::getValue('activity_type',
258 'Update Recurring Contribution',
259 'name'
260 ),
261 'subject' => $msg,
262 'details' => $message,
263 'activity_date_time' => date('YmdHis'),
264 'status_id' => CRM_Core_OptionGroup::getValue('activity_status',
265 'Completed',
266 'name'
267 ),
268 );
269 $session = CRM_Core_Session::singleton();
270 $cid = $session->get('userID');
271
272 if ($cid) {
273 $activityParams['target_contact_id'][] = $activityParams['source_contact_id'];
274 $activityParams['source_contact_id'] = $cid;
275 }
276 CRM_Activity_BAO_Activity::create($activityParams);
277
278 if (!empty($params['is_notify'])) {
279 // send notification
280 if ($this->_subscriptionDetails->contribution_page_id) {
281 CRM_Core_DAO::commonRetrieveAll('CRM_Contribute_DAO_ContributionPage', 'id',
282 $this->_subscriptionDetails->contribution_page_id, $value, array(
283 'title',
284 'receipt_from_name',
285 'receipt_from_email',
286 )
287 );
288 $receiptFrom = '"' . CRM_Utils_Array::value('receipt_from_name', $value[$this->_subscriptionDetails->contribution_page_id]) . '" <' . $value[$this->_subscriptionDetails->contribution_page_id]['receipt_from_email'] . '>';
289 }
290 else {
291 $domainValues = CRM_Core_BAO_Domain::getNameAndEmail();
292 $receiptFrom = "$domainValues[0] <$domainValues[1]>";
293 }
294
295 list($donorDisplayName, $donorEmail) = CRM_Contact_BAO_Contact::getContactDetails($contactID);
296
297 $tplParams = array(
298 'recur_frequency_interval' => $this->_subscriptionDetails->frequency_interval,
299 'recur_frequency_unit' => $this->_subscriptionDetails->frequency_unit,
300 'amount' => CRM_Utils_Money::format($params['amount']),
301 'installments' => $params['installments'],
302 );
303
304 $tplParams['contact'] = array('display_name' => $donorDisplayName);
305 $tplParams['receipt_from_email'] = $receiptFrom;
306
307 $sendTemplateParams = array(
308 'groupName' => 'msg_tpl_workflow_contribution',
309 'valueName' => 'contribution_recurring_edit',
310 'contactId' => $contactID,
311 'tplParams' => $tplParams,
312 'isTest' => $this->_subscriptionDetails->is_test,
313 'PDFFilename' => 'receipt.pdf',
314 'from' => $receiptFrom,
315 'toName' => $donorDisplayName,
316 'toEmail' => $donorEmail,
317 );
318 list($sent) = CRM_Core_BAO_MessageTemplate::sendTemplate($sendTemplateParams);
319 }
320 }
321
322 $session = CRM_Core_Session::singleton();
323 $userID = $session->get('userID');
324 if ($userID && $status) {
325 CRM_Core_Session::setStatus($status, $msgTitle, $msgType);
326 }
327 elseif (!$userID) {
328 if ($status) {
329 CRM_Utils_System::setUFMessage($status);
330 }
331 // keep result as 1, since we not displaying anything on the redirected page anyway
332 return CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contribute/subscriptionstatus',
333 "reset=1&task=update&result=1"));
334 }
335 }
336
337}