PluginProbe
WCPOS – Point of Sale (POS) plugin for WooCommerce / 1.9.14
WCPOS – Point of Sale (POS) plugin for WooCommerce v1.9.14
1.10.19 1.10.18 1.10.17 1.10.16 1.10.15 1.10.13 1.10.14 1.10.12 1.10.11 1.10.10 1.10.9 1.10.8 untagged-3d9b7ccddc54df87c672 1.10.7 1.10.6 1.10.5 1.10.3 1.10.4 1.10.2 1.10.1 1.10.0 1.9.17 1.9.15 1.9.16 1.9.14 All 163 releases
woocommerce-pos / includes / Emails.php

Emails.php in WCPOS – Point of Sale (POS) plugin for WooCommerce 1.9.14, at includes/Emails.php

273 lines 8.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * WCPOS Emails Class
4 * Handles email management for POS orders.
5 *
6 * @author Paul Kilmurray <paul@kilbot.com>
7 *
8 * @see http://wcpos.com
9 * @package WCPOS\WooCommercePOS
10 */
11
12 namespace WCPOS\WooCommercePOS;
13
14 use WC_Email;
15 use WC_Order;
16
17 /**
18 * Emails Class
19 * - manages email sending for POS orders.
20 */
21 class Emails {
22 /**
23 * Constructor.
24 */
25 public function __construct() {
26 // Get filterable email arrays - allow users to customize which emails are affected.
27 $admin_emails = apply_filters(
28 'woocommerce_pos_admin_emails',
29 array(
30 'cancelled_order',
31 'failed_order',
32 )
33 );
34
35 $customer_emails = apply_filters(
36 'woocommerce_pos_customer_emails',
37 array(
38 'customer_failed_order',
39 'customer_on_hold_order',
40 'customer_processing_order',
41 'customer_completed_order',
42 'customer_refunded_order',
43 )
44 );
45
46 // Hook into email enabled filters - this is the main control mechanism.
47 foreach ( $admin_emails as $email_id ) {
48 add_filter( "woocommerce_email_enabled_{$email_id}", array( $this, 'manage_admin_emails' ), 999, 3 );
49 }
50 foreach ( $customer_emails as $email_id ) {
51 add_filter( "woocommerce_email_enabled_{$email_id}", array( $this, 'manage_customer_emails' ), 999, 3 );
52 }
53
54 // Control new_order recipients (admin + cashier) via the recipient filter.
55 add_filter( 'woocommerce_email_recipient_new_order', array( $this, 'filter_new_order_recipients' ), 10, 3 );
56
57 // Manually trigger new_order email for POS status changes.
58 // WooCommerce doesn't automatically trigger new_order for pos-open/pos-partial transitions.
59 add_action( 'woocommerce_order_status_pos-open_to_completed', array( $this, 'trigger_new_order_email' ), 10, 2 );
60 add_action( 'woocommerce_order_status_pos-open_to_processing', array( $this, 'trigger_new_order_email' ), 10, 2 );
61 add_action( 'woocommerce_order_status_pos-open_to_on-hold', array( $this, 'trigger_new_order_email' ), 10, 2 );
62 add_action( 'woocommerce_order_status_pos-partial_to_completed', array( $this, 'trigger_new_order_email' ), 10, 2 );
63 add_action( 'woocommerce_order_status_pos-partial_to_processing', array( $this, 'trigger_new_order_email' ), 10, 2 );
64 add_action( 'woocommerce_order_status_pos-partial_to_on-hold', array( $this, 'trigger_new_order_email' ), 10, 2 );
65 }
66
67 /**
68 * Manage admin email sending for POS orders.
69 * Handles cancelled_order and failed_order via the enabled filter.
70 * Note: new_order is handled separately via filter_new_order_recipients.
71 *
72 * @param bool $enabled Whether the email is enabled.
73 * @param null|WC_Order $order The order object.
74 * @param mixed|WC_Email $email_class The email class.
75 *
76 * @return bool Whether the email should be sent.
77 */
78 public function manage_admin_emails( $enabled, $order, $email_class ) {
79 if ( ! woocommerce_pos_is_pos_order( $order ) ) {
80 return $enabled;
81 }
82
83 $email_id = $email_class instanceof WC_Email ? $email_class->id : 'unknown';
84 $settings = woocommerce_pos_get_settings( 'checkout', 'admin_emails' );
85
86 // Master toggle off = all disabled.
87 if ( empty( $settings['enabled'] ) ) {
88 $is_enabled = false;
89 } else {
90 // Individual toggle (default true if key not set).
91 $is_enabled = $settings[ $email_id ] ?? true;
92 }
93
94 /**
95 * Filters whether a specific admin email is enabled for a POS order.
96 *
97 * @since 1.4.12
98 *
99 * @param bool $is_enabled Whether the email is enabled.
100 * @param string $email_id The WooCommerce email ID.
101 * @param WC_Order $order The order object.
102 * @param WC_Email $email_class The email class instance.
103 */
104 return apply_filters( 'woocommerce_pos_admin_email_enabled', $is_enabled, $email_id, $order, $email_class );
105 }
106
107 /**
108 * Manage customer email sending for POS orders.
109 *
110 * @param bool $enabled Whether the email is enabled.
111 * @param null|WC_Order $order The order object.
112 * @param mixed|WC_Email $email_class The email class.
113 *
114 * @return bool Whether the email should be sent.
115 */
116 public function manage_customer_emails( $enabled, $order, $email_class ) {
117 if ( ! woocommerce_pos_is_pos_order( $order ) ) {
118 return $enabled;
119 }
120
121 $email_id = $email_class instanceof WC_Email ? $email_class->id : 'unknown';
122 $settings = woocommerce_pos_get_settings( 'checkout', 'customer_emails' );
123
124 // Master toggle off = all disabled.
125 if ( empty( $settings['enabled'] ) ) {
126 $is_enabled = false;
127 } else {
128 // Individual toggle (default true if key not set).
129 $is_enabled = $settings[ $email_id ] ?? true;
130 }
131
132 /**
133 * Filters whether a specific customer email is enabled for a POS order.
134 *
135 * @since 1.4.12
136 *
137 * @param bool $is_enabled Whether the email is enabled.
138 * @param string $email_id The WooCommerce email ID.
139 * @param WC_Order $order The order object.
140 * @param WC_Email $email_class The email class instance.
141 */
142 return apply_filters( 'woocommerce_pos_customer_email_enabled', $is_enabled, $email_id, $order, $email_class );
143 }
144
145 /**
146 * Filter new_order email recipients for POS orders.
147 *
148 * Builds the recipient list based on admin and cashier email settings.
149 * Uses the recipient filter (not the enabled filter) so that admin and
150 * cashier toggles can work independently.
151 *
152 * @param string $recipient Comma-separated recipient emails.
153 * @param null|WC_Order $order The order object.
154 * @param null|WC_Email $email The email class instance.
155 *
156 * @return string Filtered comma-separated recipient emails.
157 */
158 public function filter_new_order_recipients( $recipient, $order = null, $email = null ) {
159 if ( ! $order instanceof WC_Order || ! woocommerce_pos_is_pos_order( $order ) ) {
160 return $recipient;
161 }
162
163 $admin_settings = woocommerce_pos_get_settings( 'checkout', 'admin_emails' );
164 $cashier_settings = woocommerce_pos_get_settings( 'checkout', 'cashier_emails' );
165
166 $admin_wants_new_order = ! empty( $admin_settings['enabled'] )
167 && ( $admin_settings['new_order'] ?? true );
168
169 // If admin doesn't want new_order, clear the default recipient list.
170 if ( ! $admin_wants_new_order ) {
171 $recipient = '';
172 }
173
174 // Check if cashier should receive the email.
175 $cashier_wants_new_order = ! empty( $cashier_settings['enabled'] )
176 && ( $cashier_settings['new_order'] ?? true );
177
178 if ( $cashier_wants_new_order ) {
179 $cashier_email = $this->get_cashier_email( $order );
180
181 if ( $cashier_email ) {
182 // Dedup: don't add if already in the recipient list.
183 $existing = array_map( 'trim', explode( ',', $recipient ) );
184 $existing = array_filter( $existing );
185
186 if ( ! \in_array( $cashier_email, $existing, true ) ) {
187 $existing[] = $cashier_email;
188 }
189
190 $recipient = implode( ', ', $existing );
191 }
192 }
193
194 return $recipient;
195 }
196
197 /**
198 * Manually trigger new_order admin email for POS orders.
199 *
200 * This is needed because WooCommerce doesn't automatically trigger new_order
201 * for pos-open/pos-partial status transitions.
202 *
203 * @param int $order_id Order ID.
204 * @param WC_Order $order Order object.
205 */
206 public function trigger_new_order_email( $order_id, $order = null ): void {
207 if ( ! $order ) {
208 $order = wc_get_order( $order_id );
209 }
210
211 if ( ! woocommerce_pos_is_pos_order( $order ) ) {
212 return;
213 }
214
215 // Check if anyone wants the new_order email.
216 $admin_settings = woocommerce_pos_get_settings( 'checkout', 'admin_emails' );
217 $cashier_settings = woocommerce_pos_get_settings( 'checkout', 'cashier_emails' );
218
219 $admin_wants = ! empty( $admin_settings['enabled'] )
220 && ( $admin_settings['new_order'] ?? true );
221 $cashier_wants = ! empty( $cashier_settings['enabled'] )
222 && ( $cashier_settings['new_order'] ?? true );
223
224 if ( ! $admin_wants && ! $cashier_wants ) {
225 return;
226 }
227
228 // Get the new_order email by ID, not class name.
229 $mailer = WC()->mailer();
230 $emails = $mailer->get_emails();
231
232 foreach ( $emails as $email ) {
233 if ( 'new_order' === $email->id ) {
234 // Temporarily enable the email to ensure it sends.
235 $original_enabled = $email->enabled;
236 $email->enabled = 'yes';
237
238 // Trigger the email.
239 // @phpstan-ignore-next-line.
240 $email->trigger( $order_id, $order );
241
242 // Restore original state.
243 $email->enabled = $original_enabled;
244
245 break;
246 }
247 }
248 }
249
250 /**
251 * Get the cashier's email address from the order.
252 *
253 * @param WC_Order $order The order object.
254 *
255 * @return string The cashier email address, or empty string if not found.
256 */
257 private function get_cashier_email( WC_Order $order ): string {
258 $cashier_id = $order->get_meta( '_pos_user' );
259
260 if ( empty( $cashier_id ) ) {
261 return '';
262 }
263
264 $user = get_user_by( 'id', $cashier_id );
265
266 if ( ! $user || empty( $user->user_email ) ) {
267 return '';
268 }
269
270 return $user->user_email;
271 }
272 }
273