1
|
|
|
<?php |
|
|
|
|
2
|
|
|
|
3
|
|
|
if ( ! defined( 'ABSPATH' ) ) { |
4
|
|
|
exit; // Exit if accessed directly |
5
|
|
|
} |
6
|
|
|
|
7
|
|
|
/** |
8
|
|
|
* Transactional Emails Controller |
9
|
|
|
* |
10
|
|
|
* WooCommerce Emails Class which handles the sending on transactional emails and email templates. This class loads in available emails. |
11
|
|
|
* |
12
|
|
|
* @class WC_Emails |
13
|
|
|
* @version 2.3.0 |
14
|
|
|
* @package WooCommerce/Classes/Emails |
15
|
|
|
* @category Class |
16
|
|
|
* @author WooThemes |
17
|
|
|
*/ |
18
|
|
|
class WC_Emails { |
19
|
|
|
|
20
|
|
|
/** @var array Array of email notification classes */ |
21
|
|
|
public $emails; |
22
|
|
|
|
23
|
|
|
/** @var WC_Emails The single instance of the class */ |
24
|
|
|
protected static $_instance = null; |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* Main WC_Emails Instance. |
28
|
|
|
* |
29
|
|
|
* Ensures only one instance of WC_Emails is loaded or can be loaded. |
30
|
|
|
* |
31
|
|
|
* @since 2.1 |
32
|
|
|
* @static |
33
|
|
|
* @return WC_Emails Main instance |
34
|
|
|
*/ |
35
|
|
|
public static function instance() { |
36
|
|
|
if ( is_null( self::$_instance ) ) { |
37
|
|
|
self::$_instance = new self(); |
38
|
|
|
} |
39
|
|
|
return self::$_instance; |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* Cloning is forbidden. |
44
|
|
|
* |
45
|
|
|
* @since 2.1 |
46
|
|
|
*/ |
47
|
|
|
public function __clone() { |
48
|
|
|
_doing_it_wrong( __FUNCTION__, __( 'Cheatin’ huh?', 'woocommerce' ), '2.1' ); |
49
|
|
|
} |
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* Unserializing instances of this class is forbidden. |
53
|
|
|
* |
54
|
|
|
* @since 2.1 |
55
|
|
|
*/ |
56
|
|
|
public function __wakeup() { |
57
|
|
|
_doing_it_wrong( __FUNCTION__, __( 'Cheatin’ huh?', 'woocommerce' ), '2.1' ); |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* Hook in all transactional emails. |
62
|
|
|
*/ |
63
|
|
|
public static function init_transactional_emails() { |
64
|
|
|
$email_actions = apply_filters( 'woocommerce_email_actions', array( |
65
|
|
|
'woocommerce_low_stock', |
66
|
|
|
'woocommerce_no_stock', |
67
|
|
|
'woocommerce_product_on_backorder', |
68
|
|
|
'woocommerce_order_status_pending_to_processing', |
69
|
|
|
'woocommerce_order_status_pending_to_completed', |
70
|
|
|
'woocommerce_order_status_pending_to_cancelled', |
71
|
|
|
'woocommerce_order_status_pending_to_failed', |
72
|
|
|
'woocommerce_order_status_pending_to_on-hold', |
73
|
|
|
'woocommerce_order_status_failed_to_processing', |
74
|
|
|
'woocommerce_order_status_failed_to_completed', |
75
|
|
|
'woocommerce_order_status_failed_to_on-hold', |
76
|
|
|
'woocommerce_order_status_on-hold_to_processing', |
77
|
|
|
'woocommerce_order_status_on-hold_to_cancelled', |
78
|
|
|
'woocommerce_order_status_on-hold_to_failed', |
79
|
|
|
'woocommerce_order_status_completed', |
80
|
|
|
'woocommerce_order_fully_refunded', |
81
|
|
|
'woocommerce_order_partially_refunded', |
82
|
|
|
'woocommerce_new_customer_note', |
83
|
|
|
'woocommerce_created_customer' |
84
|
|
|
) ); |
85
|
|
|
|
86
|
|
|
foreach ( $email_actions as $action ) { |
87
|
|
|
add_action( $action, array( __CLASS__, 'send_transactional_email' ), 10, 10 ); |
88
|
|
|
} |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* Init the mailer instance and call the notifications for the current filter. |
93
|
|
|
* @internal param array $args (default: array()) |
94
|
|
|
*/ |
95
|
|
|
public static function send_transactional_email() { |
96
|
|
|
self::instance(); |
97
|
|
|
$args = func_get_args(); |
98
|
|
|
do_action_ref_array( current_filter() . '_notification', $args ); |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
/** |
102
|
|
|
* Constructor for the email class hooks in all emails that can be sent. |
103
|
|
|
* |
104
|
|
|
*/ |
105
|
|
|
public function __construct() { |
106
|
|
|
$this->init(); |
107
|
|
|
|
108
|
|
|
// Email Header, Footer and content hooks |
109
|
|
|
add_action( 'woocommerce_email_header', array( $this, 'email_header' ) ); |
110
|
|
|
add_action( 'woocommerce_email_footer', array( $this, 'email_footer' ) ); |
111
|
|
|
add_action( 'woocommerce_email_order_details', array( $this, 'order_details' ), 10, 4 ); |
112
|
|
|
add_action( 'woocommerce_email_order_details', array( $this, 'order_schema_markup' ), 20, 4 ); |
113
|
|
|
add_action( 'woocommerce_email_order_meta', array( $this, 'order_meta' ), 10, 3 ); |
114
|
|
|
add_action( 'woocommerce_email_customer_details', array( $this, 'customer_details' ), 10, 3 ); |
115
|
|
|
add_action( 'woocommerce_email_customer_details', array( $this, 'email_addresses' ), 20, 3 ); |
116
|
|
|
|
117
|
|
|
// Hooks for sending emails during store events |
118
|
|
|
add_action( 'woocommerce_low_stock_notification', array( $this, 'low_stock' ) ); |
119
|
|
|
add_action( 'woocommerce_no_stock_notification', array( $this, 'no_stock' ) ); |
120
|
|
|
add_action( 'woocommerce_product_on_backorder_notification', array( $this, 'backorder' ) ); |
121
|
|
|
add_action( 'woocommerce_created_customer_notification', array( $this, 'customer_new_account' ), 10, 3 ); |
122
|
|
|
|
123
|
|
|
// Let 3rd parties unhook the above via this hook |
124
|
|
|
do_action( 'woocommerce_email', $this ); |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
/** |
128
|
|
|
* Init email classes. |
129
|
|
|
*/ |
130
|
|
|
public function init() { |
131
|
|
|
// Include email classes |
132
|
|
|
include_once( 'emails/class-wc-email.php' ); |
133
|
|
|
|
134
|
|
|
$this->emails['WC_Email_New_Order'] = include( 'emails/class-wc-email-new-order.php' ); |
135
|
|
|
$this->emails['WC_Email_Cancelled_Order'] = include( 'emails/class-wc-email-cancelled-order.php' ); |
136
|
|
|
$this->emails['WC_Email_Failed_Order'] = include( 'emails/class-wc-email-failed-order.php' ); |
137
|
|
|
$this->emails['WC_Email_Customer_On_Hold_Order'] = include( 'emails/class-wc-email-customer-on-hold-order.php' ); |
138
|
|
|
$this->emails['WC_Email_Customer_Processing_Order'] = include( 'emails/class-wc-email-customer-processing-order.php' ); |
139
|
|
|
$this->emails['WC_Email_Customer_Completed_Order'] = include( 'emails/class-wc-email-customer-completed-order.php' ); |
140
|
|
|
$this->emails['WC_Email_Customer_Refunded_Order'] = include( 'emails/class-wc-email-customer-refunded-order.php' ); |
141
|
|
|
$this->emails['WC_Email_Customer_Invoice'] = include( 'emails/class-wc-email-customer-invoice.php' ); |
142
|
|
|
$this->emails['WC_Email_Customer_Note'] = include( 'emails/class-wc-email-customer-note.php' ); |
143
|
|
|
$this->emails['WC_Email_Customer_Reset_Password'] = include( 'emails/class-wc-email-customer-reset-password.php' ); |
144
|
|
|
$this->emails['WC_Email_Customer_New_Account'] = include( 'emails/class-wc-email-customer-new-account.php' ); |
145
|
|
|
|
146
|
|
|
$this->emails = apply_filters( 'woocommerce_email_classes', $this->emails ); |
147
|
|
|
|
148
|
|
|
// include css inliner |
149
|
|
|
if ( ! class_exists( 'Emogrifier' ) && class_exists( 'DOMDocument' ) ) { |
150
|
|
|
include_once( 'libraries/class-emogrifier.php' ); |
151
|
|
|
} |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
/** |
155
|
|
|
* Return the email classes - used in admin to load settings. |
156
|
|
|
* |
157
|
|
|
* @return array |
158
|
|
|
*/ |
159
|
|
|
public function get_emails() { |
160
|
|
|
return $this->emails; |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
/** |
164
|
|
|
* Get from name for email. |
165
|
|
|
* |
166
|
|
|
* @return string |
167
|
|
|
*/ |
168
|
|
|
public function get_from_name() { |
169
|
|
|
return wp_specialchars_decode( get_option( 'woocommerce_email_from_name' ), ENT_QUOTES ); |
170
|
|
|
} |
171
|
|
|
|
172
|
|
|
/** |
173
|
|
|
* Get from email address. |
174
|
|
|
* |
175
|
|
|
* @return string |
176
|
|
|
*/ |
177
|
|
|
public function get_from_address() { |
178
|
|
|
return sanitize_email( get_option( 'woocommerce_email_from_address' ) ); |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
/** |
182
|
|
|
* Get the email header. |
183
|
|
|
* |
184
|
|
|
* @param mixed $email_heading heading for the email |
185
|
|
|
*/ |
186
|
|
|
public function email_header( $email_heading ) { |
187
|
|
|
wc_get_template( 'emails/email-header.php', array( 'email_heading' => $email_heading ) ); |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
/** |
191
|
|
|
* Get the email footer. |
192
|
|
|
*/ |
193
|
|
|
public function email_footer() { |
194
|
|
|
wc_get_template( 'emails/email-footer.php' ); |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
/** |
198
|
|
|
* Wraps a message in the woocommerce mail template. |
199
|
|
|
* |
200
|
|
|
* @param mixed $email_heading |
201
|
|
|
* @param string $message |
202
|
|
|
* @return string |
203
|
|
|
*/ |
204
|
|
|
public function wrap_message( $email_heading, $message, $plain_text = false ) { |
|
|
|
|
205
|
|
|
// Buffer |
206
|
|
|
ob_start(); |
207
|
|
|
|
208
|
|
|
do_action( 'woocommerce_email_header', $email_heading ); |
209
|
|
|
|
210
|
|
|
echo wpautop( wptexturize( $message ) ); |
211
|
|
|
|
212
|
|
|
do_action( 'woocommerce_email_footer' ); |
213
|
|
|
|
214
|
|
|
// Get contents |
215
|
|
|
$message = ob_get_clean(); |
216
|
|
|
|
217
|
|
|
return $message; |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
/** |
221
|
|
|
* Send the email. |
222
|
|
|
* |
223
|
|
|
* @param mixed $to |
224
|
|
|
* @param mixed $subject |
225
|
|
|
* @param mixed $message |
226
|
|
|
* @param string $headers (default: "Content-Type: text/html\r\n") |
227
|
|
|
* @param string $attachments (default: "") |
228
|
|
|
* @return bool |
229
|
|
|
*/ |
230
|
|
|
public function send( $to, $subject, $message, $headers = "Content-Type: text/html\r\n", $attachments = "" ) { |
231
|
|
|
// Send |
232
|
|
|
$email = new WC_Email(); |
233
|
|
|
return $email->send( $to, $subject, $message, $headers, $attachments ); |
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
/** |
237
|
|
|
* Prepare and send the customer invoice email on demand. |
238
|
|
|
*/ |
239
|
|
|
public function customer_invoice( $order ) { |
240
|
|
|
$email = $this->emails['WC_Email_Customer_Invoice']; |
241
|
|
|
$email->trigger( $order ); |
242
|
|
|
} |
243
|
|
|
|
244
|
|
|
/** |
245
|
|
|
* Customer new account welcome email. |
246
|
|
|
* |
247
|
|
|
* @param int $customer_id |
248
|
|
|
* @param array $new_customer_data |
249
|
|
|
*/ |
250
|
|
|
public function customer_new_account( $customer_id, $new_customer_data = array(), $password_generated = false ) { |
251
|
|
|
if ( ! $customer_id ) { |
252
|
|
|
return; |
253
|
|
|
} |
254
|
|
|
|
255
|
|
|
$user_pass = ! empty( $new_customer_data['user_pass'] ) ? $new_customer_data['user_pass'] : ''; |
256
|
|
|
|
257
|
|
|
$email = $this->emails['WC_Email_Customer_New_Account']; |
258
|
|
|
$email->trigger( $customer_id, $user_pass, $password_generated ); |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
/** |
262
|
|
|
* Show the order details table |
263
|
|
|
*/ |
264
|
|
|
public function order_details( $order, $sent_to_admin = false, $plain_text = false, $email = '' ) { |
265
|
|
|
if ( $plain_text ) { |
266
|
|
|
wc_get_template( 'emails/plain/email-order-details.php', array( 'order' => $order, 'sent_to_admin' => $sent_to_admin, 'plain_text' => $plain_text, 'email' => $email ) ); |
267
|
|
|
} else { |
268
|
|
|
wc_get_template( 'emails/email-order-details.php', array( 'order' => $order, 'sent_to_admin' => $sent_to_admin, 'plain_text' => $plain_text, 'email' => $email ) ); |
269
|
|
|
} |
270
|
|
|
} |
271
|
|
|
|
272
|
|
|
/** |
273
|
|
|
* Adds Schema.org markup for order in JSON-LD format. |
274
|
|
|
* |
275
|
|
|
* @since 2.6.0 |
276
|
|
|
* @param mixed $order |
277
|
|
|
* @param bool $sent_to_admin (default: false) |
278
|
|
|
* @param bool $plain_text (default: false) |
279
|
|
|
*/ |
280
|
|
|
public function order_schema_markup( $order, $sent_to_admin = false, $plain_text = false ) { |
281
|
|
|
if ( $plain_text ) { |
282
|
|
|
return; |
283
|
|
|
} |
284
|
|
|
|
285
|
|
|
$accepted_offers = array(); |
286
|
|
|
|
287
|
|
|
foreach ( $order->get_items() as $item ) { |
288
|
|
|
if ( ! apply_filters( 'woocommerce_order_item_visible', true, $item ) ) { |
289
|
|
|
continue; |
290
|
|
|
} |
291
|
|
|
|
292
|
|
|
$product = apply_filters( 'woocommerce_order_item_product', $order->get_product_from_item( $item ), $item ); |
293
|
|
|
$is_visible = $product && $product->is_visible(); |
294
|
|
|
|
295
|
|
|
$item_offered = array( |
296
|
|
|
'@type' => 'Product', |
297
|
|
|
'name' => apply_filters( 'woocommerce_order_item_name', $item['name'], $item, $is_visible ) |
298
|
|
|
); |
299
|
|
|
|
300
|
|
|
if ( $sku = $product->get_sku() ) { |
301
|
|
|
$item_offered['sku'] = $sku; |
302
|
|
|
} |
303
|
|
|
|
304
|
|
|
if ( $is_visible ) { |
305
|
|
|
$item_offered['url'] = get_permalink( $product->get_id() ); |
306
|
|
|
} else { |
307
|
|
|
$item_offered['url'] = get_home_url(); |
308
|
|
|
} |
309
|
|
|
|
310
|
|
|
if ( $image_id = $product->get_image_id() ) { |
311
|
|
|
$item_offered['image'] = wp_get_attachment_image_url( $image_id, 'thumbnail' ); |
312
|
|
|
} |
313
|
|
|
|
314
|
|
|
$accepted_offer = (object) array( |
315
|
|
|
'@type' => 'Offer', |
316
|
|
|
'itemOffered' => $item_offered, |
317
|
|
|
'price' => $order->get_line_subtotal( $item ), |
318
|
|
|
'priceCurrency' => $order->get_order_currency(), |
319
|
|
|
'eligibleQuantity' => (object) array( |
320
|
|
|
'@type' => 'QuantitativeValue', |
321
|
|
|
'value' => apply_filters( 'woocommerce_email_order_item_quantity', $item['qty'], $item ) |
322
|
|
|
), |
323
|
|
|
'url' => get_home_url(), |
324
|
|
|
); |
325
|
|
|
|
326
|
|
|
$accepted_offers[] = $accepted_offer; |
327
|
|
|
} |
328
|
|
|
|
329
|
|
|
$markup = array( |
330
|
|
|
'@context' => 'http://schema.org', |
331
|
|
|
'@type' => 'Order', |
332
|
|
|
'merchant' => (object) array( |
333
|
|
|
'@type' => 'Organization', |
334
|
|
|
'name' => get_bloginfo( 'name' ), |
335
|
|
|
), |
336
|
|
|
'orderNumber' => strval( $order->get_order_number() ), |
337
|
|
|
'priceCurrency' => $order->get_order_currency(), |
338
|
|
|
'price' => $order->get_total(), |
339
|
|
|
'acceptedOffer' => count( $accepted_offers ) > 1 ? $accepted_offers : $accepted_offers[0], |
340
|
|
|
'url' => $order->get_view_order_url(), |
341
|
|
|
); |
342
|
|
|
|
343
|
|
|
switch ( $order->get_status() ) { |
344
|
|
|
case 'pending': |
345
|
|
|
$markup['orderStatus'] = 'http://schema.org/OrderPaymentDue'; |
346
|
|
|
break; |
347
|
|
|
case 'processing': |
348
|
|
|
$markup['orderStatus'] = 'http://schema.org/OrderProcessing'; |
349
|
|
|
break; |
350
|
|
|
case 'on-hold': |
351
|
|
|
$markup['orderStatus'] = 'http://schema.org/OrderProblem'; |
352
|
|
|
break; |
353
|
|
|
case 'completed': |
354
|
|
|
$markup['orderStatus'] = 'http://schema.org/OrderDelivered'; |
355
|
|
|
break; |
356
|
|
|
case 'cancelled': |
357
|
|
|
$markup['orderStatus'] = 'http://schema.org/OrderCancelled'; |
358
|
|
|
break; |
359
|
|
|
case 'refunded': |
360
|
|
|
$markup['orderStatus'] = 'http://schema.org/OrderReturned'; |
361
|
|
|
break; |
362
|
|
|
case 'failed': |
363
|
|
|
$markup['orderStatus'] = 'http://schema.org/OrderProblem'; |
364
|
|
|
break; |
365
|
|
|
} |
366
|
|
|
|
367
|
|
|
if ( $sent_to_admin ) { |
368
|
|
|
$markup['potentialAction'] = (object) array( |
369
|
|
|
'@type' => 'ViewAction', |
370
|
|
|
'target' => admin_url( 'post.php?post=' . absint( $order->id ) . '&action=edit' ), |
371
|
|
|
); |
372
|
|
|
} |
373
|
|
|
|
374
|
|
|
$markup = apply_filters( 'woocommerce_email_order_schema_markup', $markup, $sent_to_admin, $order ); |
375
|
|
|
|
376
|
|
|
echo '<script type="application/ld+json">' . wp_json_encode( (object) $markup ) . '</script>'; |
377
|
|
|
} |
378
|
|
|
|
379
|
|
|
/** |
380
|
|
|
* Add order meta to email templates. |
381
|
|
|
* |
382
|
|
|
* @param mixed $order |
383
|
|
|
* @param bool $sent_to_admin (default: false) |
384
|
|
|
* @param bool $plain_text (default: false) |
385
|
|
|
* @return string |
386
|
|
|
*/ |
387
|
|
|
public function order_meta( $order, $sent_to_admin = false, $plain_text = false ) { |
388
|
|
|
$fields = apply_filters( 'woocommerce_email_order_meta_fields', array(), $sent_to_admin, $order ); |
389
|
|
|
|
390
|
|
|
/** |
391
|
|
|
* Deprecated woocommerce_email_order_meta_keys filter. |
392
|
|
|
* |
393
|
|
|
* @since 2.3.0 |
394
|
|
|
*/ |
395
|
|
|
$_fields = apply_filters( 'woocommerce_email_order_meta_keys', array(), $sent_to_admin ); |
396
|
|
|
|
397
|
|
|
if ( $_fields ) { |
398
|
|
|
foreach ( $_fields as $key => $field ) { |
399
|
|
|
if ( is_numeric( $key ) ) { |
400
|
|
|
$key = $field; |
401
|
|
|
} |
402
|
|
|
|
403
|
|
|
$fields[ $key ] = array( |
404
|
|
|
'label' => wptexturize( $key ), |
405
|
|
|
'value' => wptexturize( get_post_meta( $order->id, $field, true ) ) |
406
|
|
|
); |
407
|
|
|
} |
408
|
|
|
} |
409
|
|
|
|
410
|
|
|
if ( $fields ) { |
411
|
|
|
|
412
|
|
|
if ( $plain_text ) { |
413
|
|
|
|
414
|
|
|
foreach ( $fields as $field ) { |
415
|
|
|
if ( isset( $field['label'] ) && isset( $field['value'] ) && $field['value'] ) { |
416
|
|
|
echo $field['label'] . ': ' . $field['value'] . "\n"; |
417
|
|
|
} |
418
|
|
|
} |
419
|
|
|
|
420
|
|
|
} else { |
421
|
|
|
|
422
|
|
|
foreach ( $fields as $field ) { |
423
|
|
|
if ( isset( $field['label'] ) && isset( $field['value'] ) && $field['value'] ) { |
424
|
|
|
echo '<p><strong>' . $field['label'] . ':</strong> ' . $field['value'] . '</p>'; |
425
|
|
|
} |
426
|
|
|
} |
427
|
|
|
} |
428
|
|
|
} |
429
|
|
|
} |
430
|
|
|
|
431
|
|
|
/** |
432
|
|
|
* Is customer detail field valid? |
433
|
|
|
* @param array $field |
434
|
|
|
* @return boolean |
435
|
|
|
*/ |
436
|
|
|
public function customer_detail_field_is_valid( $field ) { |
437
|
|
|
return isset( $field['label'] ) && ! empty( $field['value'] ); |
438
|
|
|
} |
439
|
|
|
|
440
|
|
|
/** |
441
|
|
|
* Add customer details to email templates. |
442
|
|
|
* |
443
|
|
|
* @param mixed $order |
444
|
|
|
* @param bool $sent_to_admin (default: false) |
445
|
|
|
* @param bool $plain_text (default: false) |
446
|
|
|
* @return string |
447
|
|
|
*/ |
448
|
|
|
public function customer_details( $order, $sent_to_admin = false, $plain_text = false ) { |
449
|
|
|
$fields = array(); |
450
|
|
|
|
451
|
|
View Code Duplication |
if ( $order->customer_note ) { |
|
|
|
|
452
|
|
|
$fields['customer_note'] = array( |
453
|
|
|
'label' => __( 'Note', 'woocommerce' ), |
454
|
|
|
'value' => wptexturize( $order->customer_note ) |
455
|
|
|
); |
456
|
|
|
} |
457
|
|
|
|
458
|
|
|
if ( $order->billing_email ) { |
459
|
|
|
$fields['billing_email'] = array( |
460
|
|
|
'label' => __( 'Email', 'woocommerce' ), |
461
|
|
|
'value' => wptexturize( $order->billing_email ) |
462
|
|
|
); |
463
|
|
|
} |
464
|
|
|
|
465
|
|
View Code Duplication |
if ( $order->billing_phone ) { |
|
|
|
|
466
|
|
|
$fields['billing_phone'] = array( |
467
|
|
|
'label' => __( 'Tel', 'woocommerce' ), |
468
|
|
|
'value' => wptexturize( $order->billing_phone ) |
469
|
|
|
); |
470
|
|
|
} |
471
|
|
|
|
472
|
|
|
$fields = array_filter( apply_filters( 'woocommerce_email_customer_details_fields', $fields, $sent_to_admin, $order ), array( $this, 'customer_detail_field_is_valid' ) ); |
473
|
|
|
|
474
|
|
|
if ( $plain_text ) { |
475
|
|
|
wc_get_template( 'emails/plain/email-customer-details.php', array( 'fields' => $fields ) ); |
476
|
|
|
} else { |
477
|
|
|
wc_get_template( 'emails/email-customer-details.php', array( 'fields' => $fields ) ); |
478
|
|
|
} |
479
|
|
|
} |
480
|
|
|
|
481
|
|
|
/** |
482
|
|
|
* Get the email addresses. |
483
|
|
|
*/ |
484
|
|
|
public function email_addresses( $order, $sent_to_admin = false, $plain_text = false ) { |
485
|
|
|
if ( $plain_text ) { |
486
|
|
|
wc_get_template( 'emails/plain/email-addresses.php', array( 'order' => $order ) ); |
487
|
|
|
} else { |
488
|
|
|
wc_get_template( 'emails/email-addresses.php', array( 'order' => $order ) ); |
489
|
|
|
} |
490
|
|
|
} |
491
|
|
|
|
492
|
|
|
/** |
493
|
|
|
* Get blog name formatted for emails. |
494
|
|
|
* @return string |
495
|
|
|
*/ |
496
|
|
|
private function get_blogname() { |
497
|
|
|
return wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); |
498
|
|
|
} |
499
|
|
|
|
500
|
|
|
/** |
501
|
|
|
* Low stock notification email. |
502
|
|
|
* |
503
|
|
|
* @param WC_Product $product |
504
|
|
|
*/ |
505
|
|
|
public function low_stock( $product ) { |
506
|
|
|
$subject = sprintf( '[%s] %s', $this->get_blogname(), __( 'Product low in stock', 'woocommerce' ) ); |
507
|
|
|
$message = sprintf( __( '%s is low in stock.', 'woocommerce' ), html_entity_decode( strip_tags( $product->get_formatted_name() ), ENT_QUOTES, get_bloginfo( 'charset' ) ) ) . ' ' . sprintf( __( 'There are %d left', 'woocommerce' ), html_entity_decode( strip_tags( $product->get_total_stock() ) ) ); |
508
|
|
|
|
509
|
|
|
wp_mail( |
510
|
|
|
apply_filters( 'woocommerce_email_recipient_low_stock', get_option( 'woocommerce_stock_email_recipient' ), $product ), |
511
|
|
|
apply_filters( 'woocommerce_email_subject_low_stock', $subject, $product ), |
512
|
|
|
apply_filters( 'woocommerce_email_content_low_stock', $message, $product ), |
513
|
|
|
apply_filters( 'woocommerce_email_headers', '', 'low_stock', $product ), |
514
|
|
|
apply_filters( 'woocommerce_email_attachments', array(), 'low_stock', $product ) |
515
|
|
|
); |
516
|
|
|
} |
517
|
|
|
|
518
|
|
|
/** |
519
|
|
|
* No stock notification email. |
520
|
|
|
* |
521
|
|
|
* @param WC_Product $product |
522
|
|
|
*/ |
523
|
|
|
public function no_stock( $product ) { |
524
|
|
|
$subject = sprintf( '[%s] %s', $this->get_blogname(), __( 'Product out of stock', 'woocommerce' ) ); |
525
|
|
|
$message = sprintf( __( '%s is out of stock.', 'woocommerce' ), html_entity_decode( strip_tags( $product->get_formatted_name() ), ENT_QUOTES, get_bloginfo( 'charset' ) ) ); |
526
|
|
|
|
527
|
|
|
wp_mail( |
528
|
|
|
apply_filters( 'woocommerce_email_recipient_no_stock', get_option( 'woocommerce_stock_email_recipient' ), $product ), |
529
|
|
|
apply_filters( 'woocommerce_email_subject_no_stock', $subject, $product ), |
530
|
|
|
apply_filters( 'woocommerce_email_content_no_stock', $message, $product ), |
531
|
|
|
apply_filters( 'woocommerce_email_headers', '', 'no_stock', $product ), |
532
|
|
|
apply_filters( 'woocommerce_email_attachments', array(), 'no_stock', $product ) |
533
|
|
|
); |
534
|
|
|
} |
535
|
|
|
|
536
|
|
|
/** |
537
|
|
|
* Backorder notification email. |
538
|
|
|
* |
539
|
|
|
* @param array $args |
540
|
|
|
*/ |
541
|
|
|
public function backorder( $args ) { |
542
|
|
|
$args = wp_parse_args( $args, array( |
543
|
|
|
'product' => '', |
544
|
|
|
'quantity' => '', |
545
|
|
|
'order_id' => '' |
546
|
|
|
) ); |
547
|
|
|
|
548
|
|
|
extract( $args ); |
549
|
|
|
|
550
|
|
|
if ( ! $product || ! $quantity || ! ( $order = wc_get_order( $order_id ) ) ) { |
551
|
|
|
return; |
552
|
|
|
} |
553
|
|
|
|
554
|
|
|
$subject = sprintf( '[%s] %s', $this->get_blogname(), __( 'Product Backorder', 'woocommerce' ) ); |
555
|
|
|
$message = sprintf( __( '%s units of %s have been backordered in order #%s.', 'woocommerce' ), $quantity, html_entity_decode( strip_tags( $product->get_formatted_name() ), ENT_QUOTES, get_bloginfo( 'charset' ) ), $order->get_order_number() ); |
556
|
|
|
|
557
|
|
|
wp_mail( |
558
|
|
|
apply_filters( 'woocommerce_email_recipient_backorder', get_option( 'woocommerce_stock_email_recipient' ), $args ), |
559
|
|
|
apply_filters( 'woocommerce_email_subject_backorder', $subject, $args ), |
560
|
|
|
apply_filters( 'woocommerce_email_content_backorder', $message, $args ), |
561
|
|
|
apply_filters( 'woocommerce_email_headers', '', 'backorder', $args ), |
562
|
|
|
apply_filters( 'woocommerce_email_attachments', array(), 'backorder', $args ) |
563
|
|
|
); |
564
|
|
|
} |
565
|
|
|
} |
566
|
|
|
|
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.