1
|
|
|
<?php |
|
|
|
|
2
|
|
|
|
3
|
|
|
if ( ! defined( 'ABSPATH' ) ) { |
4
|
|
|
exit; // Exit if accessed directly |
5
|
|
|
} |
6
|
|
|
|
7
|
|
|
/** |
8
|
|
|
* Cash on Delivery Gateway. |
9
|
|
|
* |
10
|
|
|
* Provides a Cash on Delivery Payment Gateway. |
11
|
|
|
* |
12
|
|
|
* @class WC_Gateway_COD |
13
|
|
|
* @extends WC_Payment_Gateway |
14
|
|
|
* @version 2.1.0 |
15
|
|
|
* @package WooCommerce/Classes/Payment |
16
|
|
|
* @author WooThemes |
17
|
|
|
*/ |
18
|
|
|
class WC_Gateway_COD extends WC_Payment_Gateway { |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* Constructor for the gateway. |
22
|
|
|
*/ |
23
|
|
|
public function __construct() { |
24
|
|
|
$this->id = 'cod'; |
25
|
|
|
$this->icon = apply_filters( 'woocommerce_cod_icon', '' ); |
26
|
|
|
$this->method_title = __( 'Cash on Delivery', 'woocommerce' ); |
27
|
|
|
$this->method_description = __( 'Have your customers pay with cash (or by other means) upon delivery.', 'woocommerce' ); |
28
|
|
|
$this->has_fields = false; |
29
|
|
|
|
30
|
|
|
// Load the settings |
31
|
|
|
$this->init_form_fields(); |
32
|
|
|
$this->init_settings(); |
33
|
|
|
|
34
|
|
|
// Get settings |
35
|
|
|
$this->title = $this->get_option( 'title' ); |
36
|
|
|
$this->description = $this->get_option( 'description' ); |
37
|
|
|
$this->instructions = $this->get_option( 'instructions', $this->description ); |
38
|
|
|
$this->enable_for_methods = $this->get_option( 'enable_for_methods', array() ); |
39
|
|
|
$this->enable_for_virtual = $this->get_option( 'enable_for_virtual', 'yes' ) === 'yes' ? true : false; |
40
|
|
|
|
41
|
|
|
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) ); |
42
|
|
|
add_action( 'woocommerce_thankyou_cod', array( $this, 'thankyou_page' ) ); |
43
|
|
|
|
44
|
|
|
// Customer Emails |
45
|
|
|
add_action( 'woocommerce_email_before_order_table', array( $this, 'email_instructions' ), 10, 3 ); |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* Initialise Gateway Settings Form Fields. |
50
|
|
|
*/ |
51
|
|
|
public function init_form_fields() { |
52
|
|
|
$shipping_methods = array(); |
53
|
|
|
|
54
|
|
|
if ( is_admin() ) |
55
|
|
|
foreach ( WC()->shipping()->load_shipping_methods() as $method ) { |
|
|
|
|
56
|
|
|
$shipping_methods[ $method->id ] = $method->get_title(); |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
$this->form_fields = array( |
60
|
|
|
'enabled' => array( |
61
|
|
|
'title' => __( 'Enable COD', 'woocommerce' ), |
62
|
|
|
'label' => __( 'Enable Cash on Delivery', 'woocommerce' ), |
63
|
|
|
'type' => 'checkbox', |
64
|
|
|
'description' => '', |
65
|
|
|
'default' => 'no' |
66
|
|
|
), |
67
|
|
|
'title' => array( |
68
|
|
|
'title' => __( 'Title', 'woocommerce' ), |
69
|
|
|
'type' => 'text', |
70
|
|
|
'description' => __( 'Payment method description that the customer will see on your checkout.', 'woocommerce' ), |
71
|
|
|
'default' => __( 'Cash on Delivery', 'woocommerce' ), |
72
|
|
|
'desc_tip' => true, |
73
|
|
|
), |
74
|
|
|
'description' => array( |
75
|
|
|
'title' => __( 'Description', 'woocommerce' ), |
76
|
|
|
'type' => 'textarea', |
77
|
|
|
'description' => __( 'Payment method description that the customer will see on your website.', 'woocommerce' ), |
78
|
|
|
'default' => __( 'Pay with cash upon delivery.', 'woocommerce' ), |
79
|
|
|
'desc_tip' => true, |
80
|
|
|
), |
81
|
|
|
'instructions' => array( |
82
|
|
|
'title' => __( 'Instructions', 'woocommerce' ), |
83
|
|
|
'type' => 'textarea', |
84
|
|
|
'description' => __( 'Instructions that will be added to the thank you page.', 'woocommerce' ), |
85
|
|
|
'default' => __( 'Pay with cash upon delivery.', 'woocommerce' ), |
86
|
|
|
'desc_tip' => true, |
87
|
|
|
), |
88
|
|
|
'enable_for_methods' => array( |
89
|
|
|
'title' => __( 'Enable for shipping methods', 'woocommerce' ), |
90
|
|
|
'type' => 'multiselect', |
91
|
|
|
'class' => 'wc-enhanced-select', |
92
|
|
|
'css' => 'width: 450px;', |
93
|
|
|
'default' => '', |
94
|
|
|
'description' => __( 'If COD is only available for certain methods, set it up here. Leave blank to enable for all methods.', 'woocommerce' ), |
95
|
|
|
'options' => $shipping_methods, |
96
|
|
|
'desc_tip' => true, |
97
|
|
|
'custom_attributes' => array( |
98
|
|
|
'data-placeholder' => __( 'Select shipping methods', 'woocommerce' ) |
99
|
|
|
) |
100
|
|
|
), |
101
|
|
|
'enable_for_virtual' => array( |
102
|
|
|
'title' => __( 'Accept for virtual orders', 'woocommerce' ), |
103
|
|
|
'label' => __( 'Accept COD if the order is virtual', 'woocommerce' ), |
104
|
|
|
'type' => 'checkbox', |
105
|
|
|
'default' => 'yes' |
106
|
|
|
) |
107
|
|
|
); |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* Check If The Gateway Is Available For Use. |
112
|
|
|
* |
113
|
|
|
* @return bool |
114
|
|
|
*/ |
115
|
|
|
public function is_available() { |
116
|
|
|
$order = null; |
117
|
|
|
$needs_shipping = false; |
118
|
|
|
|
119
|
|
|
// Test if shipping is needed first |
120
|
|
|
if ( WC()->cart && WC()->cart->needs_shipping() ) { |
121
|
|
|
$needs_shipping = true; |
122
|
|
|
} elseif ( is_page( wc_get_page_id( 'checkout' ) ) && 0 < get_query_var( 'order-pay' ) ) { |
123
|
|
|
$order_id = absint( get_query_var( 'order-pay' ) ); |
124
|
|
|
$order = wc_get_order( $order_id ); |
125
|
|
|
|
126
|
|
|
// Test if order needs shipping. |
127
|
|
|
if ( 0 < sizeof( $order->get_items() ) ) { |
128
|
|
|
foreach ( $order->get_items() as $item ) { |
129
|
|
|
$_product = $order->get_product_from_item( $item ); |
130
|
|
|
if ( $_product && $_product->needs_shipping() ) { |
131
|
|
|
$needs_shipping = true; |
132
|
|
|
break; |
133
|
|
|
} |
134
|
|
|
} |
135
|
|
|
} |
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
$needs_shipping = apply_filters( 'woocommerce_cart_needs_shipping', $needs_shipping ); |
139
|
|
|
|
140
|
|
|
// Virtual order, with virtual disabled |
141
|
|
|
if ( ! $this->enable_for_virtual && ! $needs_shipping ) { |
142
|
|
|
return false; |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
// Check methods |
146
|
|
|
if ( ! empty( $this->enable_for_methods ) && $needs_shipping ) { |
147
|
|
|
|
148
|
|
|
// Only apply if all packages are being shipped via chosen methods, or order is virtual |
149
|
|
|
$chosen_shipping_methods_session = WC()->session->get( 'chosen_shipping_methods' ); |
150
|
|
|
|
151
|
|
|
if ( isset( $chosen_shipping_methods_session ) ) { |
152
|
|
|
$chosen_shipping_methods = array_unique( $chosen_shipping_methods_session ); |
153
|
|
|
} else { |
154
|
|
|
$chosen_shipping_methods = array(); |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
$check_method = false; |
158
|
|
|
|
159
|
|
|
if ( is_object( $order ) ) { |
160
|
|
|
if ( $order->shipping_method ) { |
161
|
|
|
$check_method = $order->shipping_method; |
162
|
|
|
} |
163
|
|
|
|
164
|
|
|
} elseif ( empty( $chosen_shipping_methods ) || sizeof( $chosen_shipping_methods ) > 1 ) { |
165
|
|
|
$check_method = false; |
166
|
|
|
} elseif ( sizeof( $chosen_shipping_methods ) == 1 ) { |
167
|
|
|
$check_method = $chosen_shipping_methods[0]; |
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
if ( ! $check_method ) { |
171
|
|
|
return false; |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
$found = false; |
175
|
|
|
|
176
|
|
|
foreach ( $this->enable_for_methods as $method_id ) { |
177
|
|
|
if ( strpos( $check_method, $method_id ) === 0 ) { |
178
|
|
|
$found = true; |
179
|
|
|
break; |
180
|
|
|
} |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
if ( ! $found ) { |
184
|
|
|
return false; |
185
|
|
|
} |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
return parent::is_available(); |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
|
192
|
|
|
/** |
193
|
|
|
* Process the payment and return the result. |
194
|
|
|
* |
195
|
|
|
* @param int $order_id |
196
|
|
|
* @return array |
197
|
|
|
*/ |
198
|
|
View Code Duplication |
public function process_payment( $order_id ) { |
|
|
|
|
199
|
|
|
$order = wc_get_order( $order_id ); |
200
|
|
|
|
201
|
|
|
// Mark as processing or on-hold (payment won't be taken until delivery) |
202
|
|
|
$order->update_status( apply_filters( 'woocommerce_cod_process_payment_order_status', $order->has_downloadable_item() ? 'on-hold' : 'processing', $order ), __( 'Payment to be made upon delivery.', 'woocommerce' ) ); |
203
|
|
|
|
204
|
|
|
// Reduce stock levels |
205
|
|
|
$order->reduce_order_stock(); |
206
|
|
|
|
207
|
|
|
// Remove cart |
208
|
|
|
WC()->cart->empty_cart(); |
209
|
|
|
|
210
|
|
|
// Return thankyou redirect |
211
|
|
|
return array( |
212
|
|
|
'result' => 'success', |
213
|
|
|
'redirect' => $this->get_return_url( $order ) |
214
|
|
|
); |
215
|
|
|
} |
216
|
|
|
|
217
|
|
|
/** |
218
|
|
|
* Output for the order received page. |
219
|
|
|
*/ |
220
|
|
|
public function thankyou_page() { |
221
|
|
|
if ( $this->instructions ) { |
222
|
|
|
echo wpautop( wptexturize( $this->instructions ) ); |
223
|
|
|
} |
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
/** |
227
|
|
|
* Add content to the WC emails. |
228
|
|
|
* |
229
|
|
|
* @access public |
230
|
|
|
* @param WC_Order $order |
231
|
|
|
* @param bool $sent_to_admin |
232
|
|
|
* @param bool $plain_text |
233
|
|
|
*/ |
234
|
|
|
public function email_instructions( $order, $sent_to_admin, $plain_text = false ) { |
|
|
|
|
235
|
|
View Code Duplication |
if ( $this->instructions && ! $sent_to_admin && 'cod' === $order->payment_method ) { |
|
|
|
|
236
|
|
|
echo wpautop( wptexturize( $this->instructions ) ) . PHP_EOL; |
237
|
|
|
} |
238
|
|
|
} |
239
|
|
|
} |
240
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.