WC_Zapier_Trigger_Order_New.php
5.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
<?php
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
class WC_Zapier_Trigger_Order_New extends WC_Zapier_Trigger_Order {
/**
* A (temporary) list of order IDs that have been sent to Zapier via the 'New Order' trigger.
* @var array
*/
protected static $orders_sent_to_zapier_via_new_order = array();
public function __construct() {
$this->status_slug = 'processing';
$this->trigger_title = __( 'New Order', 'wc_zapier' );
$this->trigger_description = __( 'Triggers when an order\'s payment is completed, or when an order has its status changed to Processing.', 'wc_zapier' );
// Prefix the trigger key with wc. to denote that this is a trigger that relates to a WooCommerce order
$this->trigger_key = 'wc.new_order';
$this->sort_order = 1;
// WooCommerce action(s) that apply to this trigger event
// Add the supported hooks for all the possible payment status transitions to processing
foreach ( WC_Zapier::get_order_statuses() as $status ) {
if ( $status != $this->status_slug )
$this->actions[ "woocommerce_order_status_{$status}_to_{$this->status_slug}" ] = 1;
}
// Ensure virtual-only orders also get sent to Zapier (they typically skip the "processing" status and go straight to "completed")
$this->actions['woocommerce_payment_complete'] = 1;
add_filter( 'wc_zapier_scheduled_event', array( $this, 'wc_zapier_scheduled_event' ), 10, 3 );
add_filter( 'wc_zapier_data_sent_to_zapier_successfully', array( $this, 'wc_zapier_data_sent_to_zapier_successfully' ), 10, 4 );
parent::__construct();
}
/**
* Executed whenever an order is scheduled to be sent to Zapier (via any Trigger).
*
* @param string $action_name Hook name
* @param array $arguments Hook arguments
* @param WC_Zapier_Trigger $trigger The trigger initiating the send
*/
public function wc_zapier_scheduled_event ( $action_name, $arguments, $trigger ) {
$this->maybe_record_send( $action_name, $arguments, $trigger );
}
/**
* Executed whenever an order is successfully sent to Zapier (via any Trigger).
*
* @param string $json_data The JSON data sent to Zapier
* @param WC_Zapier_Trigger $trigger The trigger initiating the send
* @param string $action_name Hook name
* @param array $arguments Hook arguments
*/
public function wc_zapier_data_sent_to_zapier_successfully( $json_data, $trigger, $action_name, $arguments ) {
$this->maybe_record_send( $action_name, $arguments, $trigger );
}
/**
* Attempt to prevent an order from being sent to Zapier twice via the "New Order" trigger when it has the
* payment_complete() function called on it.
*
* In that case, it will be sent via the 'woocommerce_order_status_pending_to_processing' hook, and not by the
* 'woocommerce_payment_complete' hook.
*
* See also the should_schedule_event() function below.
*
* @param string $action_name Hook name
* @param array $arguments Hook arguments
* @param WC_Zapier_Trigger $trigger The trigger initiating the send
*/
protected function maybe_record_send( $action_name, $arguments, $trigger ) {
if ( $trigger->is_sample() || !is_a( $trigger, 'WC_Zapier_Trigger_Order_New' ) ) {
// Data being sent is either sample data, or it isn't being sent by a "New Order" trigger.
return;
}
if ( false !== strpos( $action_name, 'woocommerce_order_status_' ) && array_key_exists( $action_name , $this->actions ) ) {
$order_id = intval( $arguments[0] );
self::$orders_sent_to_zapier_via_new_order[ $order_id ] = true;
WC_Zapier()->log( "Recorded Order #$order_id as being sent/scheduled to Zapier via a New Order trigger." );
WC_Zapier()->log( " hook: $action_name" );
WC_Zapier()->log( " arguments: " . print_r( $arguments, true ) );
}
}
/**
* Ensure that an order isn't sent to Zapier twice as part of the "New Order" trigger event.
*
* This can happen for orders that the WC_Order::payment_complete() function called on it (most automatic payment gateways),
* where the order is also set to processing (rather than completed).
*
* The most common scenario is for orders that contain physical products that need shipping.
*
* Orders that contain virtual & downloadable products only will not have this problem because their status never
* gets set to processing.
*
* See also the maybe_record_send() function above.
*
* @param string $action_name Hook name
* @param array $args Hook arguments
*
* @return bool true
*/
protected function should_schedule_event( $action_name, $args ) {
// Check to see if this order ID has already been sent to Zapier via the order status change to processing (woocommerce_order_status_pending_to_processing hook)
// If it has, don't send it again via the 'woocommerce_payment_complete' hook as well
$order_id = intval( $args[0] );
if ( isset( self::$orders_sent_to_zapier_via_new_order[ $order_id ] ) ) {
WC_Zapier()->log( "Order #$order_id has already been sent to Zapier via a New Order trigger, so don't send it a second time via the '$action_name' hook.\n\n" );
return false;
}
// Otherwise we'll send it to Zapier
return parent::should_schedule_event( $action_name, $args );
}
}