1
|
<?php
|
2
|
|
3
|
/**
|
4
|
* @file
|
5
|
* Rules integration for payments.
|
6
|
*
|
7
|
* @addtogroup rules
|
8
|
* @{
|
9
|
*/
|
10
|
|
11
|
/**
|
12
|
* Implements hook_rules_event_info().
|
13
|
*/
|
14
|
function commerce_payment_rules_event_info() {
|
15
|
// So that we can use the entity_rules_events_variables() helper function.
|
16
|
module_load_include('inc', 'entity', 'entity.rules');
|
17
|
|
18
|
$events = array();
|
19
|
|
20
|
$events['commerce_payment_methods'] = array(
|
21
|
'label' => t('Select available payment methods for an order'),
|
22
|
'group' => t('Commerce Payment'),
|
23
|
'variables' => entity_rules_events_variables('commerce_order', t('Order', array(), array('context' => 'a drupal commerce order'))),
|
24
|
'access callback' => 'commerce_order_rules_access',
|
25
|
);
|
26
|
|
27
|
$variables = array_merge(
|
28
|
entity_rules_events_variables('commerce_order', t('Order', array(), array('context' => 'a drupal commerce order')), TRUE, TRUE),
|
29
|
entity_rules_events_variables('commerce_payment_transaction', t('Last completed transaction'), TRUE)
|
30
|
);
|
31
|
|
32
|
$events['commerce_payment_order_paid_in_full'] = array(
|
33
|
'label' => t('When an order is first paid in full'),
|
34
|
'group' => t('Commerce Payment'),
|
35
|
'variables' => $variables,
|
36
|
'access callback' => 'commerce_order_rules_access',
|
37
|
);
|
38
|
|
39
|
return $events;
|
40
|
}
|
41
|
|
42
|
/**
|
43
|
* Implements hook_rules_condition_info().
|
44
|
*/
|
45
|
function commerce_payment_rules_condition_info() {
|
46
|
$conditions = array();
|
47
|
|
48
|
$conditions['commerce_payment_order_balance_comparison'] = array(
|
49
|
'label' => t('Order balance comparison'),
|
50
|
'parameter' => array(
|
51
|
'commerce_order' => array(
|
52
|
'type' => 'commerce_order',
|
53
|
'label' => t('Order'),
|
54
|
'description' => t('The order whose balance should be compared (calculated as the order total minus completed payment amounts).'),
|
55
|
),
|
56
|
'operator' => array(
|
57
|
'type' => 'text',
|
58
|
'label' => t('Operator'),
|
59
|
'description' => t('The comparison operator.'),
|
60
|
'optional' => TRUE,
|
61
|
'default value' => '<=',
|
62
|
'options list' => 'commerce_numeric_comparison_operator_options_list',
|
63
|
'restriction' => 'input',
|
64
|
),
|
65
|
'value' => array(
|
66
|
'type' => 'text',
|
67
|
'label' => t('Value'),
|
68
|
'description' => t('Integer representing a value in minor currency units to compare against, such as 1000 for $10. A balance of 0 or less indicates the order has been paid in full.'),
|
69
|
'default value' => '0',
|
70
|
),
|
71
|
),
|
72
|
'group' => t('Commerce Payment'),
|
73
|
'callbacks' => array(
|
74
|
'execute' => 'commerce_payment_rules_compare_balance',
|
75
|
),
|
76
|
);
|
77
|
|
78
|
$conditions['commerce_payment_selected_payment_method'] = array(
|
79
|
'label' => t('Selected payment method comparison'),
|
80
|
'parameter' => array(
|
81
|
'commerce_order' => array(
|
82
|
'type' => 'commerce_order',
|
83
|
'label' => t('Order'),
|
84
|
'description' => t('The order whose selected payment method (if any) should be compared against the method specified below.'),
|
85
|
),
|
86
|
'method_id' => array(
|
87
|
'type' => 'text',
|
88
|
'label' => t('Payment method'),
|
89
|
'description' => t('This condition will perform a simple equivalency check to see if the payment method you specify matches what a customer selected on the checkout form.'),
|
90
|
'options list' => 'commerce_payment_rules_payment_method_options_list',
|
91
|
'restriction' => 'input',
|
92
|
),
|
93
|
),
|
94
|
'group' => t('Commerce Payment'),
|
95
|
'callbacks' => array(
|
96
|
'execute' => 'commerce_payment_rules_compare_selected_payment_method',
|
97
|
),
|
98
|
);
|
99
|
|
100
|
return $conditions;
|
101
|
}
|
102
|
|
103
|
/**
|
104
|
* Condition callback: checks the unpaid balance of an order.
|
105
|
*/
|
106
|
function commerce_payment_rules_compare_balance($order, $operator, $value) {
|
107
|
// Check the balance of the order.
|
108
|
$balance = commerce_payment_order_balance($order);
|
109
|
|
110
|
// If the balance was incalculable, set the balance to the order total.
|
111
|
if ($balance === FALSE) {
|
112
|
$balance = entity_metadata_wrapper('commerce_order', $order)->commerce_order_total->value();
|
113
|
}
|
114
|
|
115
|
// Make a quantity comparison based on the operator.
|
116
|
switch ($operator) {
|
117
|
case '<':
|
118
|
return $balance['amount'] < $value;
|
119
|
case '<=':
|
120
|
return $balance['amount'] <= $value;
|
121
|
case '=':
|
122
|
return $balance['amount'] == $value;
|
123
|
case '>=':
|
124
|
return $balance['amount'] >= $value;
|
125
|
case '>':
|
126
|
return $balance['amount'] > $value;
|
127
|
}
|
128
|
|
129
|
return FALSE;
|
130
|
}
|
131
|
|
132
|
/**
|
133
|
* Returns an options list of available payment methods including a None option.
|
134
|
*/
|
135
|
function commerce_payment_rules_payment_method_options_list() {
|
136
|
return array('-none-' => t('None')) + commerce_payment_method_get_title();
|
137
|
}
|
138
|
|
139
|
/**
|
140
|
* Condition callback: compares the selected payment method for an order.
|
141
|
*/
|
142
|
function commerce_payment_rules_compare_selected_payment_method($order, $method_id) {
|
143
|
if (!empty($order->data['payment_method'])) {
|
144
|
list($selected_method_id, ) = explode('|', $order->data['payment_method']);
|
145
|
}
|
146
|
else {
|
147
|
$selected_method_id = '-none-';
|
148
|
}
|
149
|
|
150
|
return $method_id == $selected_method_id;
|
151
|
}
|
152
|
|
153
|
/**
|
154
|
* Implements hook_rules_action_info().
|
155
|
*/
|
156
|
function commerce_payment_rules_action_info() {
|
157
|
$actions = array();
|
158
|
|
159
|
// Add an action for each available payment method.
|
160
|
foreach (commerce_payment_methods() as $payment_method) {
|
161
|
$actions['commerce_payment_enable_' . $payment_method['method_id']] = array(
|
162
|
'label' => t('Enable payment method: @method', array('@method' => $payment_method['title'])),
|
163
|
'parameter' => array(
|
164
|
'commerce_order' => array(
|
165
|
'type' => 'commerce_order',
|
166
|
'label' => t('Order', array(), array('context' => 'a drupal commerce order')),
|
167
|
'skip save' => TRUE,
|
168
|
),
|
169
|
'payment_method' => array(
|
170
|
'type' => 'commerce_payment_settings',
|
171
|
'restriction' => 'input',
|
172
|
'label' => t('Payment settings'),
|
173
|
'payment_method' => $payment_method['method_id'],
|
174
|
),
|
175
|
),
|
176
|
'group' => t('Commerce Payment'),
|
177
|
'callbacks' => array(
|
178
|
'execute' => 'commerce_payment_enable_method',
|
179
|
),
|
180
|
);
|
181
|
}
|
182
|
|
183
|
$actions['commerce_payment_redirect_pane_previous_page'] = array(
|
184
|
'label' => t('Redirect the checkout to the previous pane'),
|
185
|
'parameter' => array(
|
186
|
'commerce_order' => array(
|
187
|
'type' => 'commerce_order',
|
188
|
'label' => t('Order', array(), array(
|
189
|
'context' => 'a drupal commerce order',
|
190
|
)),
|
191
|
'skip save' => TRUE,
|
192
|
),
|
193
|
),
|
194
|
'group' => t('Commerce Payment'),
|
195
|
'callbacks' => array(
|
196
|
'execute' => 'commerce_payment_rules_redirect_pane_previous_page',
|
197
|
),
|
198
|
);
|
199
|
$actions['commerce_payment_redirect_pane_next_page'] = array(
|
200
|
'label' => t('Redirect the checkout to the next pane'),
|
201
|
'parameter' => array(
|
202
|
'commerce_order' => array(
|
203
|
'type' => 'commerce_order',
|
204
|
'label' => t('Order', array(), array(
|
205
|
'context' => 'a drupal commerce order',
|
206
|
)),
|
207
|
'skip save' => TRUE,
|
208
|
),
|
209
|
),
|
210
|
'group' => t('Commerce Payment'),
|
211
|
'callbacks' => array(
|
212
|
'execute' => 'commerce_payment_rules_redirect_pane_next_page',
|
213
|
),
|
214
|
);
|
215
|
|
216
|
return $actions;
|
217
|
}
|
218
|
|
219
|
/**
|
220
|
* Implements Rules action execution callback.
|
221
|
*
|
222
|
* @param stdClass $order
|
223
|
* An order.
|
224
|
*/
|
225
|
function commerce_payment_rules_redirect_pane_previous_page($order) {
|
226
|
commerce_payment_redirect_pane_previous_page($order);
|
227
|
}
|
228
|
|
229
|
/**
|
230
|
* Implements Rules action execution callback.
|
231
|
*
|
232
|
* @param stdClass $order
|
233
|
* An order.
|
234
|
*/
|
235
|
function commerce_payment_rules_redirect_pane_next_page($order) {
|
236
|
commerce_payment_redirect_pane_next_page($order);
|
237
|
}
|
238
|
|
239
|
/**
|
240
|
* Generic execution callback for the payment method.
|
241
|
*/
|
242
|
function commerce_payment_enable_method($order, $payment_method, $action_settings, $rule_state, $action, $callback_type) {
|
243
|
// Find the Rule that contains this action.
|
244
|
$rule = $action->parentElement();
|
245
|
|
246
|
while (!($rule instanceof RulesActionContainer)) {
|
247
|
if ($rule->parentElement()) {
|
248
|
$rule = $rule->parentElement();
|
249
|
}
|
250
|
else {
|
251
|
return;
|
252
|
}
|
253
|
}
|
254
|
|
255
|
// Initialize variables for the payment method ID and settings.
|
256
|
if (is_array($payment_method)) {
|
257
|
$method_id = $payment_method['method_id'];
|
258
|
$settings = !empty($payment_method['settings']) ? $payment_method['settings'] : array();
|
259
|
}
|
260
|
else {
|
261
|
$method_id = $payment_method;
|
262
|
$settings = array();
|
263
|
}
|
264
|
|
265
|
// Create a unique key for the instance of the payment method represented by
|
266
|
// this action.
|
267
|
$instance_id = commerce_payment_method_instance_id($method_id, $rule);
|
268
|
|
269
|
// Set the payment method to the order along with its settings and context.
|
270
|
$order->payment_methods[$instance_id] = array(
|
271
|
'method_id' => $method_id,
|
272
|
'settings' => $settings,
|
273
|
'rule_name' => $rule->name,
|
274
|
'weight' => $rule->weight,
|
275
|
);
|
276
|
}
|
277
|
|
278
|
/**
|
279
|
* Implements hook_rules_data_info().
|
280
|
*/
|
281
|
function commerce_payment_rules_data_info() {
|
282
|
$data['commerce_payment_settings'] = array(
|
283
|
'label' => t('Payment settings'),
|
284
|
'ui class' => 'RulesDataUIPaymentSettings',
|
285
|
);
|
286
|
return $data;
|
287
|
}
|
288
|
|
289
|
/**
|
290
|
* Adds a payment method settings form to the enabling action.
|
291
|
*/
|
292
|
class RulesDataUIPaymentSettings extends RulesDataUI implements RulesDataDirectInputFormInterface {
|
293
|
public static function getDefaultMode() {
|
294
|
return 'input';
|
295
|
}
|
296
|
|
297
|
public static function inputForm($name, $info, $settings, RulesPlugin $element) {
|
298
|
// If the specified payment method exists...
|
299
|
if (!empty($info['payment_method']) && $payment_method = commerce_payment_method_load($info['payment_method'])) {
|
300
|
$form[$name]['method_id'] = array('#type' => 'value', '#value' => $info['payment_method']);
|
301
|
|
302
|
// If the payment method has a settings callback...
|
303
|
if ($callback = commerce_payment_method_callback($payment_method, 'settings_form')) {
|
304
|
// Prepare an array of payment method settings defaults.
|
305
|
$method_settings = !empty($settings[$name]['settings']) && is_array($settings[$name]['settings']) ? $settings[$name]['settings'] : array();
|
306
|
|
307
|
// Add the settings form elements to the action form.
|
308
|
$form[$name]['settings'] = $callback($method_settings);
|
309
|
}
|
310
|
else {
|
311
|
// Otherwise add an appropriate message.
|
312
|
$form[$name]['settings']['no_settings']['#markup'] = t('No settings for this payment method.');
|
313
|
}
|
314
|
}
|
315
|
else {
|
316
|
$form[$name]['invalid']['#markup'] = t('Invalid or missing payment method.');
|
317
|
}
|
318
|
|
319
|
return $form;
|
320
|
}
|
321
|
|
322
|
public static function render($value) {
|
323
|
return array();
|
324
|
}
|
325
|
}
|
326
|
|
327
|
/**
|
328
|
* @}
|
329
|
*/
|