diff --git a/CHANGELOG.md b/CHANGELOG.md
index 12ed675..538d4c1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]
+### Added
+- Added WooCommerce integration with product and cart synchronization
+
### Changed
- Changed plugin to sync subscribers using background tasks avoiding errors if API isn't available
diff --git a/css/style.css b/css/style.css
index 8b4910a..733efe4 100644
--- a/css/style.css
+++ b/css/style.css
@@ -69,3 +69,39 @@
padding: 16px 8px;
}
}
+
+/* Sync Status Box Styling */
+.mailrelay-sync-status {
+ margin: 20px 0;
+ display: flex;
+ flex-wrap: wrap;
+}
+
+.mailrelay-sync-box {
+ background: #fff;
+ border: 1px solid #ddd;
+ border-radius: 6px;
+ padding: 20px;
+ text-align: center;
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
+ min-width: 180px;
+ margin-bottom: 20px;
+ transition: all 0.3s ease;
+}
+
+.mailrelay-sync-box:hover {
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+ border-color: #0073aa;
+}
+
+.mailrelay-sync-count {
+ font-size: 32px;
+ font-weight: bold;
+ color: #23282d;
+ margin: 5px 0;
+}
+
+.mailrelay-sync-label {
+ color: #646970;
+ font-size: 14px;
+}
diff --git a/inc/class-mailrelay-api-request-exception.php b/inc/class-mailrelay-api-request-exception.php
new file mode 100644
index 0000000..1726aeb
--- /dev/null
+++ b/inc/class-mailrelay-api-request-exception.php
@@ -0,0 +1,8 @@
+process_save_settings();
} elseif ( 'mailrelay_manual_sync' === $_POST['action'] ) {
$response = $this->process_manual_sync();
+ } elseif ( 'mailrelay_save_woocommerce_sync_settings' === $_POST['action'] ) {
+ $response = $this->process_save_woocommerce_sync_settings();
+ } elseif ( 'mailrelay_manual_woocommerce_sync' === $_POST['action'] ) {
+ $response = $this->process_manual_woocommerce_sync();
+ } elseif ( 'mailrelay_connect_woocommerce_store' === $_POST['action'] ) {
+ $response = $this->process_connect_woocommerce_store();
}
if ( isset( $response ) ) {
@@ -79,6 +85,8 @@ public function render_admin_page() {
$authenticated = false;
}
+ $display_woocommerce_tab = ! $disconnected && mailrelay_woo_commerce_installed();
+
$tab = isset( $_GET['tab'] ) ? wp_unslash( $_GET['tab'] ) : $default_tab; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
?>
@@ -102,6 +110,9 @@ public function render_admin_page() {
+
+
+
@@ -122,6 +133,11 @@ public function render_admin_page() {
$link = admin_url( '/admin.php?page=mailrelay&tab=Authentication' );
include_once __DIR__ . '/partials/tab-settings.php';
break;
+
+ case 'WooCommerce':
+ $this->setup_woocommerce_page_fields();
+ include_once __DIR__ . '/partials/tab-woocommerce.php';
+ break;
endswitch;
?>
@@ -490,4 +506,139 @@ public function process_manual_sync() {
'message' => $message,
);
}
+
+ public function setup_woocommerce_page_fields() {
+ add_settings_section(
+ 'mailrelay_woocommerce_sync_section', // id
+ '', // title
+ function () { }, // callback
+ 'mailrelay-woocommerce-sync-page' // page
+ );
+
+ $store_id = MailrelayWoocommerce::instance()->get_store_id();
+
+ if ( $store_id ) {
+ add_settings_field(
+ 'woocommerce_auto_sync', // id
+ __( 'Automatically sync WooCommerce with Mailrelay', 'mailrelay' ), // title
+ array( $this, 'woocommerce_auto_sync_callback' ), // callback
+ 'mailrelay-woocommerce-sync-page', // page
+ 'mailrelay_woocommerce_sync_section'// section
+ );
+
+ add_settings_field(
+ 'action', // id
+ '', // title
+ array( $this, 'action_woocommerce_settings_callback' ), // callback
+ 'mailrelay-woocommerce-sync-page', // page
+ 'mailrelay_woocommerce_sync_section', // section
+ array(
+ 'class' => 'hidden',
+ )
+ );
+ }
+ }
+
+ public function action_woocommerce_settings_callback() {
+ printf(
+ ''
+ );
+ }
+
+ public function woocommerce_auto_sync_callback() {
+ // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Reason: Nonce verification happens at render_admin_page.
+ $value = isset( $_POST['mailrelay_woocommerce_auto_sync'] ) ? filter_var( wp_unslash( $_POST['mailrelay_woocommerce_auto_sync'] ), FILTER_SANITIZE_NUMBER_INT ) : get_option( 'mailrelay_woocommerce_auto_sync' );
+ ?>
+ />
+
+ enqueue_sync_all_products();
+ }
+
+ return array(
+ 'valid' => true,
+ 'message' => __( 'WooCommerce Sync settings saved successfully.', 'mailrelay' ),
+ );
+ }
+
+ public function process_connect_woocommerce_store() {
+ // First, try to find a store with the same URL as the current site
+ $site_url = home_url();
+
+ $query_parameters = array(
+ 'q' => array(
+ 'url_eq' => $site_url,
+ ),
+ );
+
+ $response = mailrelay_api_request( 'GET', 'ecommerce/stores?' . http_build_query( $query_parameters ) );
+
+ if ( $response['wp_error'] || 200 !== $response['code'] ) {
+ return array(
+ 'valid' => false,
+ 'message' => __( 'Failed to connect to Mailrelay API. Please try again.', 'mailrelay' ),
+ );
+ }
+
+ $existing_store = $response['body'][0];
+
+ if ( $existing_store ) {
+ // Store found, save the ID
+ update_option( 'mailrelay_woocommerce_store_id', $existing_store['id'] );
+ return array(
+ 'valid' => true,
+ 'message' => __( 'Successfully connected to existing store in Mailrelay.', 'mailrelay' ),
+ );
+ } else {
+ // Create a new store
+ $store_data = array(
+ 'name' => get_bloginfo( 'name' ) . ' - WooCommerce',
+ 'url' => $site_url,
+ 'currency' => get_woocommerce_currency(),
+ );
+
+ $response = mailrelay_api_request(
+ 'POST',
+ 'ecommerce/stores',
+ array(
+ 'body' => wp_json_encode( $store_data ),
+ 'headers' => array( 'content-type' => 'application/json' ),
+ )
+ );
+
+ if ( $response['wp_error'] || ( 200 !== $response['code'] && 201 !== $response['code'] ) ) {
+ return array(
+ 'valid' => false,
+ 'message' => __( 'Failed to create store in Mailrelay. Please try again.', 'mailrelay' ),
+ );
+ }
+
+ update_option( 'mailrelay_woocommerce_store_id', $response['body']['id'] );
+ update_option( 'mailrelay_woocommerce_auto_sync', 1 );
+
+ MailrelayWoocommerce::instance()->enqueue_sync_all_products();
+
+ return array(
+ 'valid' => true,
+ 'message' => __( 'Successfully created and connected to a new store in Mailrelay.', 'mailrelay' ),
+ );
+ }
+ }
+
+ public function process_manual_woocommerce_sync() {
+ MailrelayWoocommerce::instance()->enqueue_sync_all_products();
+
+ return array(
+ 'valid' => true,
+ 'message' => __( 'Products are being synced to Mailrelay. It may take a few minutes to complete.', 'mailrelay' ),
+ );
+ }
}
diff --git a/inc/class-mailrelay-woocommerce-all-products.php b/inc/class-mailrelay-woocommerce-all-products.php
new file mode 100644
index 0000000..99d995a
--- /dev/null
+++ b/inc/class-mailrelay-woocommerce-all-products.php
@@ -0,0 +1,52 @@
+ 'product',
+ 'post_status' => 'publish',
+ 'posts_per_page' => self::BATCH_SIZE,
+ 'paged' => $page,
+ 'fields' => 'ids',
+ 'no_found_rows' => false, // We need total count for pagination
+ );
+
+ $query = new WP_Query( $args );
+ $products = $query->posts;
+
+ // Queue individual product sync jobs
+ foreach ( $products as $product_id ) {
+ as_enqueue_async_action(
+ 'mailrelay_sync_product_background',
+ array( $product_id ),
+ 'mailrelay'
+ );
+ }
+
+ // If there are more pages, schedule the next batch
+ if ( $page < $query->max_num_pages ) {
+ as_enqueue_async_action(
+ 'mailrelay_sync_all_products_background',
+ array( $page + 1 ),
+ 'mailrelay'
+ );
+ }
+
+ // Clean up memory
+ wp_reset_postdata();
+ }
+}
diff --git a/inc/class-mailrelay-woocommerce-cart.php b/inc/class-mailrelay-woocommerce-cart.php
new file mode 100644
index 0000000..9aa0462
--- /dev/null
+++ b/inc/class-mailrelay-woocommerce-cart.php
@@ -0,0 +1,85 @@
+transform( $cart_data );
+
+ $store_id = MailrelayWoocommerce::instance()->get_store_id();
+ $endpoint = "ecommerce/stores/{$store_id}/carts/sync";
+
+ $response = mailrelay_api_request(
+ 'POST',
+ $endpoint,
+ array(
+ 'body' => wp_json_encode( $data ),
+ 'headers' => array( 'content-type' => 'application/json' ),
+ )
+ );
+
+ if ( $response['wp_error'] || ( isset( $response['code'] ) && $response['code'] >= 500 ) ) {
+ throw new MailrelayApiRequestException( 'Mailrelay API request failed, will retry.' );
+ }
+
+ return $response;
+ }
+
+ public function set_completed( $cart_id, $email ) {
+ $store_id = MailrelayWoocommerce::instance()->get_store_id();
+ $endpoint = "ecommerce/stores/{$store_id}/carts/{$cart_id}";
+
+ $data = array(
+ 'email' => $email,
+ 'status' => 'completed',
+ );
+
+ $response = mailrelay_api_request(
+ 'PATCH',
+ $endpoint,
+ array(
+ 'body' => wp_json_encode( $data ),
+ 'headers' => array( 'content-type' => 'application/json' ),
+ )
+ );
+
+ if ( $response['wp_error'] || ( isset( $response['code'] ) && $response['code'] >= 500 ) ) {
+ throw new MailrelayApiRequestException( 'Mailrelay API request failed, will retry.' );
+ }
+
+ return $response;
+ }
+
+ public function transform( array $cart_data ) {
+ $cart_items_attributes = array();
+ if ( ! empty( $cart_data['cart_items'] ) ) {
+ foreach ( $cart_data['cart_items'] as $cart_item_key => $cart_item ) {
+ $cart_items_attributes[] = array(
+ 'cart_item_id' => $cart_item_key,
+ 'product_variant_id' => (string) ( ! empty( $cart_item['variation_id'] ) ? $cart_item['variation_id'] : $cart_item['product_id'] ),
+ 'quantity' => $cart_item['quantity'],
+ 'price' => MailrelayWoocommerceHelper::transform_price( $cart_item['product_price'] ),
+ );
+ }
+ }
+
+ return array(
+ 'cart_id' => $cart_data['cart_id'],
+ 'status' => 'pending',
+ 'checkout_url' => $cart_data['checkout_url'],
+ 'total' => MailrelayWoocommerceHelper::transform_price( $cart_data['cart_total'] ),
+ 'tax_total' => MailrelayWoocommerceHelper::transform_price( $cart_data['cart_tax_total'] ),
+ 'email' => $cart_data['email'],
+ 'cart_items_attributes' => $cart_items_attributes,
+ );
+ }
+}
diff --git a/inc/class-mailrelay-woocommerce-helper.php b/inc/class-mailrelay-woocommerce-helper.php
new file mode 100644
index 0000000..00e0e70
--- /dev/null
+++ b/inc/class-mailrelay-woocommerce-helper.php
@@ -0,0 +1,10 @@
+transform( $product );
+
+ $store_id = MailrelayWoocommerce::instance()->get_store_id();
+ $endpoint = "ecommerce/stores/{$store_id}/products/sync";
+
+ $response = mailrelay_api_request(
+ 'POST',
+ $endpoint,
+ array(
+ 'body' => wp_json_encode($data),
+ 'headers' => array( 'content-type' => 'application/json' ),
+ )
+ );
+
+ if ( $response['wp_error'] || ( isset( $response['code'] ) && $response['code'] >= 500 ) ) {
+ throw new MailrelayApiRequestException( 'Mailrelay API request failed, will retry.' );
+ }
+
+ // Clear cache after successful sync since product count may have changed
+ MailrelayWoocommerce::instance()->clear_synced_products_count_cache();
+
+ return $response;
+ }
+
+ public function transform( WC_Product $product ) {
+ if ( ! $product ) {
+ return array();
+ }
+
+ $product_image = $this->get_product_image($product);
+
+ $variants = array();
+ if ( $product->is_type('variable') ) {
+ foreach ( $product->get_children() as $child_id ) {
+ $variant = wc_get_product($child_id);
+ if ( $variant ) {
+ $variant_image = $this->get_product_image($variant);
+
+ $variants[] = array(
+ 'product_variant_id' => (string) $variant->get_id(),
+ 'name' => $variant->get_name(),
+ 'sku' => $variant->get_sku(),
+ 'price' => MailrelayWoocommerceHelper::transform_price( $variant->get_price() ),
+ 'url' => get_permalink($variant->get_id()),
+ 'image_url' => $variant_image ? $variant_image : $product_image,
+ );
+ }
+ }
+ }
+ if ( empty($variants) ) {
+ // No variants, add the product itself as a single variant
+ $variants[] = array(
+ 'product_variant_id' => (string) $product->get_id(),
+ 'name' => $product->get_name(),
+ 'sku' => $product->get_sku(),
+ 'price' => MailrelayWoocommerceHelper::transform_price( $product->get_price() ),
+ 'url' => get_permalink($product->get_id()),
+ 'image_url' => $product_image,
+ );
+ }
+ return array(
+ 'product_id' => (string) $product->get_id(),
+ 'name' => $product->get_name(),
+ 'url' => get_permalink($product->get_id()),
+ 'image_url' => $product_image,
+ 'product_variants_attributes' => $variants,
+ );
+ }
+
+ public function get_product_image( $product ) {
+ $id = is_a($product, 'WC_Product') ? $product->get_id() : $product->ID;
+ $meta = get_post_meta($id);
+ $key = '_thumbnail_id';
+ $image_key = $this->get_product_image_key();
+ if ( $meta && is_array($meta) && array_key_exists($key, $meta) && isset($meta[ $key ][0]) ) {
+ $img = wp_get_attachment_image_src($meta[ $key ][0], $image_key);
+ if ( ! empty($img[0]) ) {
+ if ( substr($img[0], 0, 4) !== 'http' ) {
+ return rtrim(home_url(), '/') . '/' . ltrim($img[0], '/');
+ }
+ return $img[0];
+ }
+ }
+ $url = get_the_post_thumbnail_url($id, $image_key);
+ if ( $url ) {
+ return $url;
+ } else {
+ return null;
+ }
+ }
+
+ public function get_product_image_key() {
+ return 'medium';
+ }
+}
diff --git a/inc/class-mailrelay-woocommerce.php b/inc/class-mailrelay-woocommerce.php
new file mode 100644
index 0000000..936c24b
--- /dev/null
+++ b/inc/class-mailrelay-woocommerce.php
@@ -0,0 +1,320 @@
+get_store_id() && $this->mailrelay_configured();
+ }
+
+ public function mailrelay_configured() {
+ return (bool) mailrelay_data();
+ }
+
+ public function setup_hooks() {
+ if ( ! mailrelay_woo_commerce_installed() ) {
+ return;
+ }
+
+ add_action( 'woocommerce_new_product', array( $this, 'handle_product_created' ), 10, 1 );
+ add_action( 'woocommerce_update_product', array( $this, 'handle_product_updated' ), 10, 1 );
+
+ // Cart hooks.
+ add_action( 'woocommerce_add_to_cart', array( $this, 'handle_cart_event' ), 20, 99 );
+ add_action( 'woocommerce_cart_updated', array( $this, 'handle_cart_event' ), 20, 99 );
+ add_action( 'woocommerce_remove_cart_item', array( $this, 'handle_cart_event' ), 20, 99 );
+ add_action( 'woocommerce_cart_emptied', array( $this, 'handle_cart_event' ), 20, 99 );
+ add_action( 'woocommerce_checkout_update_order_review', array( $this, 'capture_guest_email_from_checkout' ), 10, 1 );
+ add_action( 'woocommerce_new_order', array( $this, 'handle_new_order' ), 10, 2 );
+
+ // User session hooks.
+ add_action( 'wp_login', array( $this, 'handle_user_login' ), 10, 2 );
+ add_action( 'wp_logout', array( $this, 'handle_user_logout' ), 10, 1 );
+
+ add_action(
+ 'mailrelay_sync_product_background',
+ function ( int $post_ID ) {
+ $service = new MailrelayWoocommerceProduct();
+ $service->sync( $post_ID );
+ },
+ 10,
+ 1
+ );
+
+ add_action(
+ 'mailrelay_sync_all_products_background',
+ function ( $page = 1 ) {
+ $service = new MailrelayWoocommerceAllProducts();
+ $service->sync( $page );
+ },
+ 10,
+ 1
+ );
+
+ add_action(
+ 'mailrelay_sync_cart_background',
+ function ( $cart_data ) {
+ $service = new MailrelayWoocommerceCart();
+ $service->sync( $cart_data );
+ },
+ 10,
+ 1
+ );
+
+ add_action(
+ 'mailrelay_sync_cart_completed_background',
+ function ( $data ) {
+ $service = new MailrelayWoocommerceCart();
+ $service->set_completed( $data['cart_id'], $data['email'] );
+ },
+ 10,
+ 1
+ );
+ }
+
+ public function enqueue_sync_all_products() {
+ as_enqueue_async_action(
+ 'mailrelay_sync_all_products_background',
+ array(),
+ 'mailrelay',
+ true
+ );
+ }
+
+ /**
+ * Handle product save.
+ *
+ * @param int $post_ID Product ID.
+ */
+ public function handle_product_created( int $post_ID ) {
+ if ( 'product' !== get_post_type($post_ID) ) {
+ return;
+ }
+
+ if ( ! $this->auto_sync_enabled() ) {
+ return;
+ }
+
+ as_enqueue_async_action(
+ 'mailrelay_sync_product_background',
+ array( $post_ID ),
+ 'mailrelay'
+ );
+ }
+
+ /**
+ * Handle product update.
+ *
+ * @param int $post_ID Product ID.
+ */
+ public function handle_product_updated( int $post_ID ) {
+ if ( 'product' !== get_post_type($post_ID) ) {
+ return;
+ }
+
+ if ( ! $this->auto_sync_enabled() ) {
+ return;
+ }
+
+ if ( in_array(get_post_status($post_ID), array( 'trash', 'auto-draft' ), true) ) {
+ return;
+ }
+
+ as_enqueue_async_action(
+ 'mailrelay_sync_product_background',
+ array( $post_ID ),
+ 'mailrelay'
+ );
+ }
+
+ public function handle_new_order( $order_id, $order ) {
+ if ( ! $this->auto_sync_enabled() ) {
+ return;
+ }
+
+ if ( ! $order ) {
+ return;
+ }
+
+ $email = $order->get_billing_email();
+ // The cart_id is the user session.
+ $cart_id = WC()->session->get_customer_id();
+
+ if ( empty( $email ) || empty( $cart_id ) ) {
+ return;
+ }
+
+ as_enqueue_async_action(
+ 'mailrelay_sync_cart_completed_background',
+ array(
+ 'cart_id' => $cart_id,
+ 'email' => $email,
+ ),
+ 'mailrelay'
+ );
+ }
+
+ public function capture_guest_email_from_checkout() {
+ // phpcs:disable WordPress.Security.NonceVerification.Missing
+ if ( ! is_user_logged_in() && isset( $_POST['billing_email'] ) && is_email( wp_unslash( $_POST['billing_email'] ) ) ) {
+ $email = sanitize_email( wp_unslash( $_POST['billing_email'] ) );
+ if ( WC()->session ) {
+ WC()->session->set( 'mailrelay_cart_tracking_email', $email );
+ }
+ }
+ // phpcs:enable WordPress.Security.NonceVerification.Missing
+ }
+
+ private function get_tracking_email() {
+ if ( is_user_logged_in() ) {
+ $user = wp_get_current_user();
+ return $user->user_email;
+ }
+
+ if ( WC()->customer && WC()->customer->get_billing_email() ) {
+ return WC()->customer->get_billing_email();
+ }
+
+ return null;
+ }
+
+ public function handle_cart_event() {
+ if ( ! $this->auto_sync_enabled() ) {
+ return;
+ }
+
+ $email = $this->get_tracking_email();
+
+ if ( empty( $email ) ) {
+ return;
+ }
+
+ $cart = WC()->cart;
+
+ if ( is_null( $cart ) || $cart->is_empty() ) {
+ return;
+ }
+
+ // Prevent duplicate jobs using a transient based on cart hash.
+ $transient_name = 'mailrelay_cart_sync_' . $cart->get_cart_hash();
+ if ( get_transient( $transient_name ) ) {
+ return;
+ }
+ set_transient( $transient_name, true, MINUTE_IN_SECONDS * 5 );
+
+ $cart_contents_for_queue = array();
+ foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
+ $product = $cart_item['data'];
+ if ( ! $product ) {
+ continue;
+ }
+
+ $cart_contents_for_queue[ $cart_item_key ] = array(
+ 'product_id' => $cart_item['product_id'],
+ 'variation_id' => $cart_item['variation_id'],
+ 'quantity' => $cart_item['quantity'],
+ 'product_price' => $product->get_price(),
+ );
+ }
+
+ $cart_data = array(
+ 'email' => $email,
+ 'user_id' => get_current_user_id(),
+ 'cart_id' => WC()->session->get_customer_id(),
+ 'cart_total' => $cart->get_total( 'edit' ),
+ 'cart_tax_total' => $cart->get_total_tax(),
+ 'cart_items' => $cart_contents_for_queue,
+ 'checkout_url' => wc_get_checkout_url(),
+ 'is_empty' => $cart->is_empty(),
+ );
+
+ as_enqueue_async_action(
+ 'mailrelay_sync_cart_background',
+ array( 'cart_data' => $cart_data ),
+ 'mailrelay'
+ );
+ }
+
+ public function handle_user_login( $user_login, $user ) {
+ if ( WC()->session ) {
+ WC()->session->set( 'mailrelay_cart_tracking_email', $user->user_email );
+ }
+ $this->handle_cart_event();
+ }
+
+ public function handle_user_logout() {
+ if ( WC()->session ) {
+ WC()->session->set( 'mailrelay_cart_tracking_email', null );
+ }
+ }
+
+ public function get_synced_products_count() {
+ $store_id = $this->get_store_id();
+
+ if ( ! $store_id ) {
+ return 0;
+ }
+
+ // Check cache first
+ $cache_key = 'mailrelay_synced_products_count_' . $store_id;
+ $cached_count = get_transient( $cache_key );
+
+ if ( false !== $cached_count ) {
+ return (int) $cached_count;
+ }
+
+ $response = mailrelay_api_request( 'GET', "ecommerce/stores/{$store_id}/products?" . http_build_query( array( 'per_page' => 1 ) ) );
+
+ if ( $response['wp_error'] || 200 !== $response['code'] ) {
+ return 0;
+ }
+
+ $count = (int) $response['headers']['total'];
+
+ // Cache for 5 minutes
+ set_transient( $cache_key, $count, 5 * MINUTE_IN_SECONDS );
+
+ return $count;
+ }
+
+ /**
+ * Clear the synced products count cache
+ */
+ public function clear_synced_products_count_cache() {
+ $store_id = $this->get_store_id();
+ if ( $store_id ) {
+ $cache_key = 'mailrelay_synced_products_count_' . $store_id;
+ delete_transient( $cache_key );
+ }
+ }
+}
diff --git a/inc/common.php b/inc/common.php
index dd1a1a1..9eba61a 100644
--- a/inc/common.php
+++ b/inc/common.php
@@ -31,11 +31,14 @@ function mailrelay_api_request( $method, $url, $args = array(), $mailrelay_data
$response = wp_remote_request( $url, $args );
+ $headers = wp_remote_retrieve_headers( $response );
+
if ( is_wp_error( $response ) ) {
return array(
'wp_error' => true,
'error_message' => $response->get_error_message(),
'response' => $response,
+ 'headers' => $headers,
);
}
@@ -48,6 +51,7 @@ function mailrelay_api_request( $method, $url, $args = array(), $mailrelay_data
'code' => $code,
'body' => $body,
'response' => $response,
+ 'headers' => $headers,
);
}
}
diff --git a/inc/global-hooks.php b/inc/global-hooks.php
index 5eeca97..be4a510 100644
--- a/inc/global-hooks.php
+++ b/inc/global-hooks.php
@@ -14,8 +14,7 @@ function mailrelay_user_register_hook( $user_id ) {
as_enqueue_async_action(
'mailrelay_sync_user_background',
array( $user_id ),
- 'mailrelay',
- true
+ 'mailrelay'
);
}
add_action( 'user_register', 'mailrelay_user_register_hook' );
diff --git a/inc/partials/tab-woocommerce.php b/inc/partials/tab-woocommerce.php
new file mode 100644
index 0000000..75ac55b
--- /dev/null
+++ b/inc/partials/tab-woocommerce.php
@@ -0,0 +1,64 @@
+get_store_id();
+?>
+
+
+ get_synced_products_count();
+ ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/mailrelay.php b/mailrelay.php
index 200c814..f4e2b47 100644
--- a/mailrelay.php
+++ b/mailrelay.php
@@ -34,7 +34,18 @@
}
-function mailrelay_wpforms() {
- require_once __DIR__ . '/inc/class-mailrelay-wpforms.php';
-}
-add_action( 'wpforms_loaded', 'mailrelay_wpforms' );
+
+add_action(
+ 'wpforms_loaded',
+ function () {
+ require_once __DIR__ . '/inc/class-mailrelay-wpforms.php';
+ }
+);
+
+require_once __DIR__ . '/inc/class-mailrelay-woocommerce.php';
+add_action(
+ 'plugins_loaded',
+ function () {
+ MailrelayWoocommerce::instance()->setup_hooks();
+ }
+);