-
Notifications
You must be signed in to change notification settings - Fork 0
/
woocommerce-slack.php
287 lines (247 loc) · 8.87 KB
/
woocommerce-slack.php
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
<?php
/**
* Plugin Name: WooCommerce Slack Integration
* Plugin URI:
* Description: This plugin allows you to send notifications to Slack channels whenever payment in WooCommerce is marked as complete.
* Version: 2.0.0
* Author: Trevor Bice
* Text Domain: slack-woocommerce
* Domain Path: /languages
* License: GPL v2 or later
*/
define('WOOCOMMERCE_SLACK_ABS_PATH', ABSPATH . "wp-content/plugins/woocommerce-slack-notifications/");
include(WOOCOMMERCE_SLACK_ABS_PATH . 'class-testmode.php');
include(WOOCOMMERCE_SLACK_ABS_PATH . 'class-settings.php');
class wp_slack_woocommerce
{
private static $instance = false;
public static function instance()
{
if (!self::$instance) {
self::$instance = new self;
self::$instance->init();
}
return self::$instance;
}
public function init()
{
if (class_exists('wp_slack_woocommerce_testmode')) {
$wp_slack_woocommerce_testmode = new wp_slack_woocommerce_testmode;
$wp_slack_woocommerce_testmode->init();
}
if (class_exists('wp_slack_woocommerce_settings')) {
$wp_slack_woocommerce_settings = new wp_slack_woocommerce_settings;
$wp_slack_woocommerce_settings->init();
}
add_action('init', array($this, 'wp_init'), 10, 3);
// add_action( 'admin_init', array( $this, 'wp_admin_init'), 10, 3 );
}
public function wp_init()
{
$enabled = get_option('wc_settings_tab_slack_woocommerce_enable_notifications');
if ($enabled == 'yes') {
add_filter('woocommerce_payment_complete_order_status', array($this, 'rfvc_update_order_status'), 10, 2);
add_action('woocommerce_order_status_completed', array($this, 'mysite_woocommerce_order_status_completed'));
add_action('woocommerce_order_status_cancelled', array($this, 'mysite_woocommerce_order_status_cancelled'));
add_action('woocommerce_order_status_failed', array($this, 'mysite_woocommerce_order_status_failed'));
}
if (is_admin()) {
add_action('wp_ajax_test_slack', array($this, 'test_slack'));
add_action('in_admin_footer', array($this, 'enqueue_scripts'));
}
}
public function enqueue_scripts()
{
?>
<script>
jQuery(window).ready(function () {
jQuery("#test_slack").click(function () {
jQuery.ajax({
type: "post",
url: 'admin-ajax.php',
data: {
action: "test_slack"
},
success: function (response) {
console.log(response);
}
});
});
});
</script>
<?php
}
/**
* Retrieves the ID of the most recent WooCommerce order.
*
* @return int|null The ID of the last order or null if no orders are found.
*/
public function get_last_order_id()
{
global $wpdb;
// Get all WooCommerce order statuses
$orderStatuses = array_keys(wc_get_order_statuses());
$formattedStatuses = implode("','", $orderStatuses);
// Construct the query to find the latest order ID
$query = "
SELECT MAX(ID) FROM {$wpdb->prefix}posts
WHERE post_type = 'shop_order'
AND post_status IN ('$formattedStatuses')
";
// Execute the query and get the result
$result = $wpdb->get_col($query);
// Return the first element in the result or null if empty
return reset($result);
}
/**
* Sends a test message to Slack about the latest WooCommerce order.
*
* This function checks the status of the latest order and sends a test message to Slack
* indicating if the order is completed or cancelled.
*/
public function test_slack()
{
// Retrieve the ID of the latest order
$latestOrderId = $this->get_last_order_id();
$order = wc_get_order($latestOrderId);
$orderStatus = $order->get_status();
// Determine the icon and status for the Slack message
if (in_array($orderStatus, ['processing', 'completed'])) {
$icon = get_option('wc_settings_tab_slack_woocommerce_slack_icon_completed');
$status = "completed";
} else {
$icon = get_option('wc_settings_tab_slack_woocommerce_slack_icon_cancelled');
$status = "cancelled";
}
// Get product details from the order
$productDetails = '';
$orderItems = $order->get_items();
if (count($orderItems) == 1) {
foreach ($orderItems as $item) {
$productDetails = $item->get_data();
}
}
// Construct the Slack message
$customerName = $order->data['billing']['first_name'] . " " . $order->data['billing']['last_name'];
$formattedTotal = number_format($order->data['total'], 2);
$message = "";
if (isset($productDetails['name'])) {
$message = "{$productDetails['name']}\n";
}
$message .= "Order *#{$order->ID}* by *{$customerName}* for *{$formattedTotal}* has been {$status}";
// Retrieve Slack channel setting and send the message
$channel = "#" . get_option('wc_settings_tab_slack_woocommerce_channel');
$this->slack_message($message, "Order " . ucfirst($orderStatus) . " TEST", $channel, $icon);
// Terminate execution
wp_die();
}
/**
* Updates the order status to 'completed' if certain conditions are met.
*
* @param string $current_status The current status of the order.
* @param int $order_id The ID of the WooCommerce order.
* @return string The updated order status.
*/
public function rfvc_update_order_status($current_status, $order_id)
{
// Create an instance of the WooCommerce Order
$order = new WC_Order($order_id);
// Define the statuses that allow changing to 'completed'
$allowed_statuses = ['on-hold', 'pending', 'failed'];
// Check if the current status is 'processing' and the order's status is one of the allowed statuses
if ($current_status === 'processing' && in_array($order->status, $allowed_statuses)) {
// Update status to 'completed'
return 'completed';
}
// Return the original status if conditions are not met
return $current_status;
}
/**
* Sends a message to a specified Slack channel.
*
* @param string $message The message to be sent to Slack.
* @param string $username The username to be displayed in Slack.
* @param string $channel The channel where the message will be posted.
* @param string $icon Emoji icon to represent the user (default is robot face emoji).
* @return mixed The result of the Slack API call.
*/
public static function slack_message($message, $username, $channel, $icon = ":robot_face:")
{
$slackToken = get_option('wc_settings_tab_slack_token');
$slackUrl = "https://slack.com/api/chat.postMessage";
// Prepare the data for POST request
$postData = http_build_query([
"token" => $slackToken,
"channel" => $channel,
"text" => $message,
"username" => $username,
"icon_emoji" => $icon,
]);
// Initialize cURL session
$curl = curl_init($slackUrl);
// Set cURL options
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
// Execute cURL session and close
$result = curl_exec($curl);
if ($result === false) {
$result = 'cURL Error: ' . curl_error($curl);
}
curl_close($curl);
return $result;
}
public function mysite_woocommerce_order_status_completed($order_id)
{
$this->woocommerce_order_status_report($order_id, 'completed');
}
public function mysite_woocommerce_order_status_cancelled($order_id)
{
$this->woocommerce_order_status_report($order_id, 'cancelled');
}
public function mysite_woocommerce_order_status_failed($order_id)
{
$this->woocommerce_order_status_report($order_id, 'failed');
}
/**
* Sends a report to Slack about WooCommerce order status.
*
* @param int $order_id The ID of the WooCommerce order.
* @param string $status The new status of the order.
* @return void
*/
public function woocommerce_order_status_report($order_id, $status)
{
// Retrieve order and order items
$order = wc_get_order($order_id);
$order_items = $order->get_items();
// Initialize product name
$product_name = "";
// Extract product name if only one item in order
if (count($order_items) == 1) {
foreach ($order_items as $item) {
$product_data = $item->get_data();
$product_name = preg_replace("# - Other#", "", $product_data['name']);
}
}
// Edge case: if no product is found, return or handle accordingly
if (empty($product_name)) {
return; // or handle as needed
}
// Determine the status phrasing
$hasbeen = $status == 'failed' ? 'has' : 'has been';
// Format the order total
$formatted_total = number_format($order->data['total'], 2);
// Construct the message
$customer_name = $order->data['billing']['first_name'] . " " . $order->data['billing']['last_name'];
$message = "{$product_name}\nOrder *#{$order->ID}* by *{$customer_name}* for *${formatted_total}* {$hasbeen} {$status}";
// Retrieve Slack channel and icon settings
$channel = "#" . get_option('wc_settings_tab_slack_woocommerce_channel');
$icon = get_option('wc_settings_tab_slack_woocommerce_slack_icon_' . $status);
// Send the message to Slack
$this->slack_message($message, "Order " . ucfirst($status), $channel, $icon);
}
}
$wp_slack_woocommerce = new wp_slack_woocommerce;
$wp_slack_woocommerce->init();