1554 lines
48 KiB
PHP
1554 lines
48 KiB
PHP
<?php
|
||
/**
|
||
* Sensor: WooCommerce
|
||
*
|
||
* WooCommerce sensor file.
|
||
*
|
||
* @package Wsal
|
||
*/
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace WSAL\WP_Sensors;
|
||
|
||
use WC_Coupon;
|
||
use WC_Product;
|
||
use WSAL\Helpers\Settings_Helper;
|
||
use WSAL\Controllers\Alert_Manager;
|
||
use WSAL\WP_Sensors\Helpers\Woocommerce_Helper;
|
||
use WSAL\WP_Sensors_Helpers\WooCommerce_Sensor_Helper;
|
||
use WSAL\WP_Sensors_Helpers\WooCommerce_Sensor_Helper_Third;
|
||
use WSAL\WP_Sensors_Helpers\WooCommerce_Sensor_Helper_Second;
|
||
|
||
// Exit if accessed directly.
|
||
if ( ! defined( 'ABSPATH' ) ) {
|
||
exit;
|
||
}
|
||
|
||
if ( ! class_exists( '\WSAL\Plugin_Sensors\WooCommerce_Sensor' ) ) {
|
||
|
||
/**
|
||
* Support for WooCommerce Plugin.
|
||
*
|
||
* @package Wsal
|
||
*/
|
||
class WooCommerce_Sensor {
|
||
|
||
/**
|
||
* WooCommerce Product Object.
|
||
*
|
||
* @var WC_Product
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static $old_product = null;
|
||
|
||
/**
|
||
* Old Post.
|
||
*
|
||
* @var \WP_Post
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static $old_post = null;
|
||
|
||
/**
|
||
* Old Order.
|
||
*
|
||
* @var \WC_Order
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static $_old_order = null;
|
||
|
||
/**
|
||
* Old Status.
|
||
*
|
||
* @var string
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static $old_status = null;
|
||
|
||
/**
|
||
* Old Post Link.
|
||
*
|
||
* @var string
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static $_old_link = null;
|
||
|
||
/**
|
||
* Old Post Categories.
|
||
*
|
||
* @var array
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static $_old_cats = null;
|
||
|
||
/**
|
||
* Old Product Data.
|
||
*
|
||
* @var array
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static $old_data = null;
|
||
|
||
/**
|
||
* New Product Data.
|
||
*
|
||
* @var array
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static $new_data = null;
|
||
|
||
/**
|
||
* Old Meta Product Data.
|
||
*
|
||
* @var array
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static $_old_meta_data = null;
|
||
|
||
/**
|
||
* Old Product attachment Data.
|
||
*
|
||
* @var array
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static $_old_attachment_metadata = null;
|
||
|
||
/**
|
||
* Old Attribute Data.
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @var stdClass
|
||
*/
|
||
private static $old_attr_data;
|
||
|
||
/**
|
||
* Old store location data.
|
||
*
|
||
* @since 1.4.0
|
||
*
|
||
* @var string
|
||
*/
|
||
private static $old_location_data;
|
||
|
||
/**
|
||
* Most recent store location data.
|
||
*
|
||
* @since 1.4.0
|
||
*
|
||
* @var string
|
||
*/
|
||
private static $new_location_data;
|
||
|
||
/**
|
||
* Coupon Meta Data Keys.
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @var array
|
||
*/
|
||
private static $coupon_meta = array(
|
||
'discount_type',
|
||
'coupon_amount',
|
||
'individual_use',
|
||
'product_ids',
|
||
'exclude_product_ids',
|
||
'usage_limit',
|
||
'usage_limit_per_user',
|
||
'limit_usage_to_x_items',
|
||
'usage_count',
|
||
'date_expires',
|
||
'expiry_date',
|
||
'free_shipping',
|
||
'product_categories',
|
||
'exclude_product_categories',
|
||
'exclude_sale_items',
|
||
'minimum_amount',
|
||
'maximum_amount',
|
||
'customer_email',
|
||
);
|
||
|
||
/**
|
||
* WC User Meta.
|
||
*
|
||
* @since 3.4
|
||
*
|
||
* @var array
|
||
*/
|
||
private static $wc_user_meta = array();
|
||
|
||
/**
|
||
* Stores $_REQUEST global variable data.
|
||
*
|
||
* @var array
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static $request_data = array();
|
||
|
||
/**
|
||
* That needs to be registered as a frontend sensor, when the admin sets the plugin to monitor the login from 3rd parties.
|
||
*
|
||
* @return boolean
|
||
*
|
||
* @since 4.5.1
|
||
*/
|
||
public static function is_frontend_sensor(): bool {
|
||
$frontend_events = Settings_Helper::get_frontend_events();
|
||
$should_load = ( isset( $frontend_events['woocommerce'] ) && $frontend_events['woocommerce'] );
|
||
|
||
if ( $should_load ) {
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* Listening to events using WP hooks.
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function init() {
|
||
}
|
||
|
||
/**
|
||
* Loads all the plugin dependencies early.
|
||
*
|
||
* @return void
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function early_init() {
|
||
\add_filter(
|
||
'wsal_event_objects',
|
||
array( Woocommerce_Helper::class, 'wsal_woocommerce_extension_add_custom_event_objects' )
|
||
);
|
||
|
||
if ( Woocommerce_Helper::is_woocommerce_active() ) {
|
||
\add_filter(
|
||
'wsal_save_settings_disabled_events',
|
||
array(
|
||
Woocommerce_Helper::class,
|
||
'save_settings_disabled_events',
|
||
),
|
||
10,
|
||
4
|
||
);
|
||
\add_action(
|
||
'init',
|
||
function () {
|
||
|
||
if ( \current_user_can( 'edit_posts' ) ) {
|
||
\add_action( 'admin_init', array( __CLASS__, 'event_admin_init' ) );
|
||
|
||
}
|
||
\add_action( 'woocommerce_update_option', array( __CLASS__, 'woo_option_update' ) );
|
||
|
||
\add_action( 'pre_post_update', array( __CLASS__, 'get_before_post_edit_data' ), 10, 2 );
|
||
|
||
\add_action( 'woocommerce_before_order_object_save', array( __CLASS__, 'get_order_post_edit_data' ), 10, 2 );
|
||
|
||
\add_action( 'woocommerce_admin_process_product_object', array( __CLASS__, 'inline_product_changed' ), 10 );
|
||
\add_action( 'woocommerce_after_order_object_save', array( __CLASS__, 'inline_product_changed' ), 10, 2 );
|
||
add_action( 'delete_post', array( WooCommerce_Sensor_Helper::class, 'event_deleted' ), 10, 1 );
|
||
add_action( 'woocommerce_before_delete_order', array( WooCommerce_Sensor_Helper::class, 'event_deleted' ), 10, 1 );
|
||
add_action( 'wp_trash_post', array( WooCommerce_Sensor_Helper::class, 'event_trashed' ), 10, 1 );
|
||
add_action( 'woocommerce_trash_order', array( WooCommerce_Sensor_Helper::class, 'event_trashed' ), 10, 1 );
|
||
add_action( 'untrash_post', array( WooCommerce_Sensor_Helper::class, 'event_untrashed' ) );
|
||
add_action( 'woocommerce_untrash_order', array( WooCommerce_Sensor_Helper::class, 'event_untrashed' ) );
|
||
add_action( 'wp_head', array( WooCommerce_Sensor_Helper::class, 'viewing_product' ), 10 );
|
||
add_action( 'create_product_cat', array( __CLASS__, 'event_category_creation' ), 10, 1 );
|
||
add_filter( 'post_edit_form_tag', array( WooCommerce_Sensor_Helper_Second::class, 'editing_product' ), 10, 1 );
|
||
add_action( 'woocommerce_order_status_changed', array( WooCommerce_Sensor_Helper_Second::class, 'event_order_status_changed' ), 10, 4 );
|
||
add_action( 'woocommerce_order_refunded', array( WooCommerce_Sensor_Helper_Second::class, 'event_order_refunded' ), 10, 2 );
|
||
add_action( 'woocommerce_bulk_action_ids', array( WooCommerce_Sensor_Helper_Second::class, 'event_bulk_order_actions' ), 10, 2 );
|
||
add_action( 'woocommerce_attribute_added', array( WooCommerce_Sensor_Helper_Second::class, 'event_attribute_added' ), 10, 2 );
|
||
add_action( 'woocommerce_before_attribute_delete', array( WooCommerce_Sensor_Helper_Second::class, 'event_attribute_deleted' ), 10, 3 );
|
||
add_action( 'woocommerce_attribute_updated', array( WooCommerce_Sensor_Helper_Second::class, 'event_attribute_updated' ), 10, 3 );
|
||
add_action( 'wp_update_term_data', array( WooCommerce_Sensor_Helper_Second::class, 'event_product_cat_updated' ), 10, 4 );
|
||
add_action( 'update_term_meta', array( WooCommerce_Sensor_Helper_Second::class, 'event_cat_display_updated' ), 10, 4 );
|
||
add_action( 'delete_product_cat', array( WooCommerce_Sensor_Helper_Second::class, 'event_product_cat_deleted' ), 10, 4 );
|
||
add_action( 'delete_product_tag', array( WooCommerce_Sensor_Helper_Second::class, 'event_product_tag_deleted' ), 10, 4 );
|
||
add_action( 'wsal_before_post_meta_create_event', array( WooCommerce_Sensor_Helper_Second::class, 'log_coupon_meta_created_event' ), 10, 4 );
|
||
add_action( 'wsal_before_post_meta_update_event', array( WooCommerce_Sensor_Helper_Second::class, 'log_coupon_meta_update_events' ), 10, 5 );
|
||
add_action( 'wsal_before_post_meta_delete_event', array( WooCommerce_Sensor_Helper_Second::class, 'log_coupon_meta_delete_event' ), 10, 4 );
|
||
add_action( 'update_user_meta', array( WooCommerce_Sensor_Helper_Second::class, 'before_wc_user_meta_update' ), 10, 3 );
|
||
add_action( 'added_user_meta', array( WooCommerce_Sensor_Helper_Second::class, 'wc_user_meta_updated' ), 10, 4 );
|
||
add_action( 'updated_user_meta', array( WooCommerce_Sensor_Helper_Second::class, 'wc_user_meta_updated' ), 10, 4 );
|
||
add_action( 'woocommerce_before_product_object_save', array( WooCommerce_Sensor_Helper_Second::class, 'check_product_changes_before_save' ), 10, 2 );
|
||
add_action( 'woocommerce_after_product_object_save', array( __CLASS__, 'check_product_changes_after_save' ), 10, 1 );
|
||
add_action( 'woocommerce_product_quick_edit_save', array( __CLASS__, 'inline_product_changed' ), 10, 1 );
|
||
add_action( 'updated_option', array( WooCommerce_Sensor_Helper::class, 'settings_updated' ), 10, 3 );
|
||
add_action( 'create_product_tag', array( __CLASS__, 'event_tag_creation' ), 10, 1 );
|
||
add_action( 'update_postmeta', array( WooCommerce_Sensor_Helper_Second::class, 'detect_stock_level_change' ), 10, 4 );
|
||
add_action( 'woocommerce_before_shipping_zone_object_save', array( __CLASS__, 'detect_shipping_zone_change' ), 10, 2 );
|
||
add_action( 'woocommerce_new_webhook', array( __CLASS__, 'webhook_added' ), 10, 2 );
|
||
add_action( 'woocommerce_webhook_deleted', array( __CLASS__, 'webhook_deleted' ), 10, 2 );
|
||
add_action( 'woocommerce_before_shipping_zone_object_save', array( __CLASS__, 'detect_shipping_zone_change' ), 10, 2 );
|
||
|
||
// Orders.
|
||
add_action( 'woocommerce_new_order_item', array( WooCommerce_Sensor_Helper_Second::class, 'event_order_items_added' ), 10, 3 );
|
||
add_action( 'woocommerce_before_delete_order_item', array( WooCommerce_Sensor_Helper_Second::class, 'event_order_items_removed' ), 10, 1 );
|
||
add_action( 'woocommerce_before_save_order_items', array( WooCommerce_Sensor_Helper_Second::class, 'event_order_items_quantity_changed' ), 10, 2 );
|
||
add_action( 'woocommerce_refund_deleted', array( WooCommerce_Sensor_Helper_Second::class, 'event_order_refund_removed' ), 10, 2 );
|
||
add_action( 'admin_action_edit', array( __CLASS__, 'order_opened_for_editing' ), 10 );
|
||
|
||
add_action( 'woocommerce_page_wc-orders', array( __CLASS__, 'orders_actions' ) );
|
||
|
||
add_action( 'woocommerce_before_data_object_save', array( __CLASS__, 'data_store' ), 10, 2 );
|
||
|
||
\add_action( 'woocommerce_coupon_options_save', array( __CLASS__, 'inline_product_changed' ), 10 );
|
||
|
||
\add_action( 'woocommerce_order_note_deleted', array( __CLASS__, 'order_note_deleted' ), 10, 2 );
|
||
// \add_action( 'woocommerce_new_customer_note', array( __CLASS__, 'new_customer_note' ), 10, 2 );
|
||
\add_action( 'woocommerce_order_note_added', array( __CLASS__, 'order_note_added' ), 10, 2 );
|
||
|
||
\add_action( 'woocommerce_product_duplicate', array( __CLASS__, 'duplicate_product_action' ), 10, 2 );
|
||
},
|
||
10,
|
||
2
|
||
);
|
||
/**
|
||
* Add our filters.
|
||
*/
|
||
\add_filter(
|
||
'wsal_event_type_data',
|
||
array( Woocommerce_Helper::class, 'wsal_woocommerce_extension_add_custom_event_type' ),
|
||
10,
|
||
2
|
||
);
|
||
\add_filter(
|
||
'wsal_format_custom_meta',
|
||
array( Woocommerce_Helper::class, 'wsal_woocommerce_extension_add_custom_meta_format' ),
|
||
10,
|
||
4
|
||
);
|
||
\add_filter(
|
||
'wsal_ignored_custom_post_types',
|
||
array( Woocommerce_Helper::class, 'wsal_woocommerce_extension_add_custom_ignored_cpt' )
|
||
);
|
||
\add_filter(
|
||
'wsal_load_public_sensors',
|
||
array( Woocommerce_Helper::class, 'wsal_woocommerce_extension_load_public_sensors' )
|
||
);
|
||
\add_filter(
|
||
'wsal_togglealerts_sub_category_events',
|
||
array( Woocommerce_Helper::class, 'wsal_woocommerce_extension_togglealerts_sub_category_events' )
|
||
);
|
||
\add_filter(
|
||
'wsal_togglealerts_sub_category_titles',
|
||
array( Woocommerce_Helper::class, 'wsal_woocommerce_extension_togglealerts_sub_category_titles' ),
|
||
10,
|
||
2
|
||
);
|
||
\add_action(
|
||
'wsal_togglealerts_append_content_to_toggle',
|
||
array( Woocommerce_Helper::class, 'wsal_woocommerce_extension_append_content_to_toggle' )
|
||
);
|
||
\add_action(
|
||
'wsal_togglealerts_process_save_settings',
|
||
array( Woocommerce_Helper::class, 'wsal_woocommerce_extension_togglealerts_process_save_settings' ),
|
||
10,
|
||
1
|
||
);
|
||
\add_filter(
|
||
'wsal_togglealerts_obsolete_events',
|
||
array( Woocommerce_Helper::class, 'wsal_woocommerce_extension_togglealerts_obsolete_events' )
|
||
);
|
||
|
||
\add_action(
|
||
'admin_footer',
|
||
array( Woocommerce_Helper::class, 'wsal_woocommerce_extension_togglealerts_js_code' )
|
||
);
|
||
|
||
// Special events.
|
||
\add_action(
|
||
'woocommerce_download_product',
|
||
array( Woocommerce_Helper::class, 'wsal_woocommerce_extension_detect_file_download' ),
|
||
10,
|
||
6
|
||
);
|
||
|
||
WooCommerce_Sensor_Helper_Third::init();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Called on WOO options update. Checks if the current is a payment gateway settings update. If it does, it adds a filter to listen to changes in the gateway settings and logs them.
|
||
*
|
||
* @param array $option_array - Options to update.
|
||
*
|
||
* @return void
|
||
*
|
||
* @since 5.3.0
|
||
*/
|
||
public static function woo_option_update( $option_array ) {
|
||
|
||
if ( ! is_array( $option_array ) || empty( $option_array ) || ! isset( $option_array['id'] ) ) {
|
||
return;
|
||
}
|
||
|
||
$payment_gateways = \WC()->payment_gateways->payment_gateways();
|
||
|
||
if ( ! empty( $payment_gateways ) ) {
|
||
// Get gateway ID.
|
||
$gateway_id = $option_array['id'];
|
||
foreach ( $payment_gateways as $gateway ) {
|
||
|
||
// Check if the gateway id matches any available gateway ids.
|
||
// The ID provided is in format woocommerce_{gateway_id}_settings. So the check is made by adding the prefix and suffix.
|
||
if ( 'woocommerce_' . $gateway->id . '_settings' !== $gateway_id ) {
|
||
continue;
|
||
} else {
|
||
\add_filter( 'woocommerce_settings_api_sanitized_fields_' . $gateway->id, array( __CLASS__, 'gateway_changes' ) );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* That monitors gateway changes - unfortunately we don't have the gateway ID, so we are using the global name set by WOO and called $current_section.
|
||
*
|
||
* @param array $gateway_settings - The new settings for the gateway.
|
||
*
|
||
* @return array $gateway_settings - The sanitized settings for the gateway.
|
||
*
|
||
* @since 5.3.0
|
||
*/
|
||
public static function gateway_changes( $gateway_settings ) {
|
||
global $current_tab, $current_section;
|
||
|
||
// Get old gateway settings.
|
||
$old_gateway_settings = (array) WooCommerce_Sensor_Helper_Second::get_config( $current_section . '_settings' );
|
||
|
||
$old_gateway_status = isset( $old_gateway_settings['enabled'] ) ? $old_gateway_settings['enabled'] : false;
|
||
$new_gateway_status = isset( $gateway_settings['enabled'] ) ? $gateway_settings['enabled'] : false;
|
||
|
||
// Check status change.
|
||
if ( $old_gateway_status !== $new_gateway_status ) {
|
||
// Gateway enabled.
|
||
Alert_Manager::trigger_event(
|
||
9074,
|
||
array(
|
||
'GatewayID' => sanitize_text_field( $current_section ),
|
||
'GatewayName' => isset( $gateway_settings['title'] ) ? $gateway_settings['title'] : false,
|
||
'EventType' => 'yes' === $new_gateway_status ? 'enabled' : 'disabled',
|
||
)
|
||
);
|
||
}
|
||
|
||
return $gateway_settings;
|
||
}
|
||
|
||
/**
|
||
* Triggers when Order note (comment) is added
|
||
*
|
||
* @param int $note_id - The note ID.
|
||
* @param \WC_Order $order - The order object.
|
||
*
|
||
* @return void
|
||
*
|
||
* @since 5.1.0
|
||
*/
|
||
public static function order_note_added( $note_id, $order ) {
|
||
$edit_link = WooCommerce_Sensor_Helper_Second::get_editor_link( $order );
|
||
$note = \wc_get_order_note( $note_id );
|
||
|
||
$comment = \get_comment( $note_id );
|
||
|
||
$user = \get_user_by( 'email', $comment->comment_author_email );
|
||
|
||
Alert_Manager::trigger_event(
|
||
9155,
|
||
array(
|
||
'OrderID' => \esc_attr( $note->order_id ),
|
||
'OrderTitle' => \sanitize_text_field( Woocommerce_Helper::wsal_woocommerce_extension_get_order_title( $order ) ),
|
||
'OrderStatus' => \wc_get_order_status_name( $order->get_status() ),
|
||
'OrderStatusSlug' => $order->get_status(),
|
||
'PostStatus' => 'wc-' . $order->get_status(),
|
||
$edit_link['name'] => $edit_link['value'],
|
||
'NoteID' => $note_id,
|
||
'NoteType' => ( $note->customer_note ) ? __( 'Customer note', 'wp-security-audit-log' ) : __( 'Private', 'wp-security-audit-log' ),
|
||
'Content' => $note->content,
|
||
'CurrentUserID' => ( is_a( $user, '\WP_User' ) ) ? $user->ID : 0,
|
||
'Username' => ( is_a( $user, '\WP_User' ) ) ? $user->user_login : 'WooCommerce System',
|
||
)
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Triggers when product is duplicated.
|
||
*
|
||
* @param \WC_Product $duplicate - Duplicated product.
|
||
* @param \WC_Product $product - Original product.
|
||
*
|
||
* @return void
|
||
*
|
||
* @since 5.3.0
|
||
*/
|
||
public static function duplicate_product_action( $duplicate, $product ) {
|
||
$editor_link = WooCommerce_Public_Sensor::get_editor_link( $duplicate );
|
||
Alert_Manager::trigger_event(
|
||
9138,
|
||
array(
|
||
'ProductTitle' => $duplicate->get_title(),
|
||
'ProductUrl' => get_post_permalink( $duplicate->get_id() ),
|
||
'ProductID' => $duplicate->get_id(),
|
||
'SKU' => $duplicate->get_sku(),
|
||
'ProductStatus' => $duplicate->get_status(),
|
||
'PostStatus' => $duplicate->get_status(),
|
||
$editor_link['name'] => $editor_link['value'],
|
||
'OriginalProductTitle' => $product->get_title(),
|
||
'OriginalProductUrl' => get_post_permalink( $product->get_id() ),
|
||
'OriginalProductID' => $product->get_id(),
|
||
'OriginalSKU' => $product->get_sku(),
|
||
'OriginalProductStatus' => $product->get_status(),
|
||
'OriginalPostStatus' => $product->get_status(),
|
||
)
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Triggers when Order note (comment) is deleted
|
||
*
|
||
* @param int $note_id - The note ID.
|
||
* @param \WP_Comment $note - The note object.
|
||
*
|
||
* @return void
|
||
*
|
||
* @since 5.1.0
|
||
*/
|
||
public static function order_note_deleted( $note_id, $note ) {
|
||
$order = \wc_get_order( $note->order_id ); // Get order post object.
|
||
$edit_link = WooCommerce_Sensor_Helper_Second::get_editor_link( $order );
|
||
|
||
Alert_Manager::trigger_event(
|
||
9156,
|
||
array(
|
||
'OrderID' => \esc_attr( $note->order_id ),
|
||
'OrderTitle' => \sanitize_text_field( Woocommerce_Helper::wsal_woocommerce_extension_get_order_title( $order ) ),
|
||
'OrderStatus' => \wc_get_order_status_name( $order->get_status() ),
|
||
'OrderStatusSlug' => $order->get_status(),
|
||
'PostStatus' => 'wc-' . $order->get_status(),
|
||
$edit_link['name'] => $edit_link['value'],
|
||
'NoteID' => $note_id,
|
||
'NoteType' => ( $note->customer_note ) ? __( 'Customer note', 'wp-security-audit-log' ) : __( 'Private', 'wp-security-audit-log' ),
|
||
'Content' => $note->content,
|
||
)
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Called when Woo saves data (update)
|
||
*
|
||
* @param \WC_Webhook $wc_data - The modified webhook.
|
||
* @param \WC_Data_Store $data_store - The Woo data store.
|
||
*
|
||
* @return void
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function data_store( $wc_data, $data_store ) {
|
||
if ( 'WC_Webhook_Data_Store' === $data_store->get_current_class_name() ) {
|
||
if ( $wc_data->get_id() ) {
|
||
$changes = $wc_data->get_changes();
|
||
if ( ! empty( $changes ) ) {
|
||
|
||
$old_webhook = wc_get_webhook( $wc_data->get_id() );
|
||
|
||
$editor_link = Woocommerce_Helper::create_webhook_editor_link( $wc_data->get_id() );
|
||
|
||
$event_id = 9122;
|
||
|
||
if ( \is_array( $changes ) && count( $changes ) === 1 && \key_exists( 'status', $changes ) ) {
|
||
$event_id = 9178;
|
||
}
|
||
Alert_Manager::trigger_event(
|
||
$event_id,
|
||
array(
|
||
'HookName' => $wc_data->get_name( 'edit' ),
|
||
'OldHookName' => $old_webhook->get_name(),
|
||
'DeliveryURL' => $wc_data->get_delivery_url( 'edit' ),
|
||
'OldDeliveryURL' => $old_webhook->get_delivery_url(),
|
||
'Topic' => $wc_data->get_topic( 'edit' ),
|
||
'OldTopic' => $old_webhook->get_topic(),
|
||
'Status' => $wc_data->get_status( 'edit' ),
|
||
'OldStatus' => $old_webhook->get_status(),
|
||
'Secret' => $wc_data->get_secret( 'edit' ),
|
||
'OldSecret' => $old_webhook->get_secret(),
|
||
'EditorLinkWebhook' => $editor_link,
|
||
)
|
||
);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Covers order actions
|
||
*
|
||
* @return void
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function orders_actions() {
|
||
|
||
if ( isset( $_GET['action'] ) ) {
|
||
if ( 'edit' === \sanitize_text_field( \wp_unslash( $_GET['action'] ) ) && isset( $_GET['id'] ) && 0 < (int) $_GET['id'] ) {
|
||
// Get post.
|
||
$post = wc_get_order( \sanitize_text_field( \wp_unslash( $_GET['id'] ) ) );
|
||
|
||
// Log event.
|
||
if ( $post ) {
|
||
self::order_opened_in_editor( $post );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Alert for Editing of Posts and Custom Post Types in Gutenberg.
|
||
*
|
||
* @since 3.2.4
|
||
*/
|
||
public static function order_opened_for_editing() {
|
||
global $pagenow;
|
||
|
||
if ( 'post.php' !== $pagenow ) {
|
||
return;
|
||
}
|
||
|
||
$post_id = isset( $_GET['post'] ) ? (int) sanitize_text_field( wp_unslash( $_GET['post'] ) ) : false; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||
|
||
// Check post id.
|
||
if ( empty( $post_id ) ) {
|
||
return;
|
||
}
|
||
|
||
if ( is_user_logged_in() && is_admin() ) {
|
||
// Get post.
|
||
$post = wc_get_order( $post_id );
|
||
|
||
// Log event.
|
||
if ( $post ) {
|
||
self::order_opened_in_editor( $post );
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Order Opened for Editing in WP Editors.
|
||
*
|
||
* @param WP_Post $post – Post object.
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function order_opened_in_editor( $post ) {
|
||
if ( empty( $post ) ) {
|
||
return;
|
||
}
|
||
|
||
$current_path = isset( $_SERVER['SCRIPT_NAME'] ) ? esc_url_raw( wp_unslash( $_SERVER['SCRIPT_NAME'] ) ) . '?post=' . $post->get_id() : false;
|
||
$referrer = isset( $_SERVER['HTTP_REFERER'] ) ? esc_url_raw( wp_unslash( $_SERVER['HTTP_REFERER'] ) ) : false;
|
||
|
||
// Check referrer URL.
|
||
if ( ! empty( $referrer ) ) {
|
||
// Parse the referrer.
|
||
$parsed_url = wp_parse_url( $referrer );
|
||
|
||
// If the referrer is post-new then we can ignore this one.
|
||
if ( isset( $parsed_url['path'] ) && 'post-new' === basename( $parsed_url['path'], '.php' ) ) {
|
||
return $post;
|
||
}
|
||
}
|
||
|
||
if ( ! empty( $referrer ) && strpos( $referrer, $current_path ) !== false ) {
|
||
// Ignore this if we were on the same page so we avoid double audit entries.
|
||
return $post;
|
||
}
|
||
|
||
if ( ! Alert_Manager::was_triggered_recently( 9154 ) ) {
|
||
$event = 9154;
|
||
$editor_link = WooCommerce_Sensor_Helper_Second::get_editor_link( $post );
|
||
|
||
Alert_Manager::trigger_event(
|
||
$event,
|
||
array(
|
||
'PostID' => $post->get_id(),
|
||
'PostTitle' => Woocommerce_Helper::wsal_woocommerce_extension_get_order_title( $post->get_id() ),
|
||
'PostStatus' => \wc_get_order_status_name( $post->get_status() ),
|
||
'PostStatusSlug' => $post->get_status(),
|
||
'PostUrl' => get_permalink( $post->get_id() ),
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Detect changes made directly to WC product data.
|
||
*
|
||
* @param WC_Product $product - WC porduct object.
|
||
* @return void
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function check_product_changes_after_save( $product ) {
|
||
// We know this hook is only fired when updating, but we need to be sure this is an automatic (not post edit etc) change.
|
||
if ( ! isset( $_POST['action'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||
$product_data = WooCommerce_Sensor_Helper_Second::get_product_data( $product );
|
||
if ( empty( $product_data ) ) {
|
||
return;
|
||
}
|
||
|
||
self::$new_data = $product_data;
|
||
$old_product_data = self::$old_data;
|
||
|
||
if ( empty( $old_product_data ) ) {
|
||
return;
|
||
}
|
||
|
||
$values_to_lookup = array(
|
||
'sku',
|
||
'stock_status',
|
||
'stock',
|
||
'tax_status',
|
||
'weight',
|
||
'regular_price',
|
||
'sale_price',
|
||
);
|
||
|
||
foreach ( $values_to_lookup as $lookup_key ) {
|
||
if ( isset( self::$new_data[ $lookup_key ] ) && $old_product_data[ $lookup_key ] !== self::$new_data[ $lookup_key ] || isset( self::$old_data[ $lookup_key ] ) && self::$new_data[ $lookup_key ] !== $old_product_data[ $lookup_key ] ) {
|
||
if ( 'regular_price' === $lookup_key || 'sale_price' === $lookup_key ) {
|
||
WooCommerce_Sensor_Helper::check_price_change( self::$old_post );
|
||
} elseif ( 'stock_status' === $lookup_key ) {
|
||
WooCommerce_Sensor_Helper::check_stock_status_change( self::$old_post );
|
||
} elseif ( 'stock' === $lookup_key ) {
|
||
WooCommerce_Sensor_Helper::check_stock_quantity_change( self::$old_post );
|
||
} elseif ( 'sku' === $lookup_key ) {
|
||
WooCommerce_Sensor_Helper::check_sku_change( self::$old_post );
|
||
} elseif ( 'weight' === $lookup_key ) {
|
||
WooCommerce_Sensor_Helper::check_weight_change( self::$old_post );
|
||
} elseif ( 'tax_status' === $lookup_key ) {
|
||
WooCommerce_Sensor_Helper_Second::check_tax_status_change( self::$old_post, self::$_old_meta_data, self::$new_data );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Trigger alert when new webhook is added.
|
||
*
|
||
* @param int $webhook_id - WC Webhook ID.
|
||
* @param object $webhook - WC Webhook data.
|
||
* @return int $webhook_id
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function webhook_added( $webhook_id, $webhook ) {
|
||
$editor_link = Woocommerce_Helper::create_webhook_editor_link( $webhook_id );
|
||
Alert_Manager::trigger_event(
|
||
9120,
|
||
array(
|
||
'HookName' => sanitize_text_field( $webhook->get_name() ),
|
||
'DeliveryURL' => sanitize_text_field( $webhook->get_delivery_url() ),
|
||
'Topic' => sanitize_text_field( $webhook->get_topic() ),
|
||
'Status' => sanitize_text_field( $webhook->get_status() ),
|
||
'EditorLinkWebhook' => $editor_link,
|
||
)
|
||
);
|
||
return $webhook_id;
|
||
}
|
||
|
||
/**
|
||
* Trigger alert when new webhook is deleted.
|
||
*
|
||
* @param int $webhook_id - WC Webhook ID.
|
||
* @param object $webhook - WC Webhook data.
|
||
* @return int $webhook_id
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function webhook_deleted( $webhook_id, $webhook ) {
|
||
Alert_Manager::trigger_event(
|
||
9121,
|
||
array(
|
||
'HookName' => sanitize_text_field( $webhook->get_name() ),
|
||
'DeliveryURL' => sanitize_text_field( $webhook->get_delivery_url() ),
|
||
'Topic' => sanitize_text_field( $webhook->get_topic() ),
|
||
'Status' => sanitize_text_field( $webhook->get_status() ),
|
||
)
|
||
);
|
||
return $webhook_id;
|
||
}
|
||
|
||
/**
|
||
* Trigger 9082 when a shipping zone is created or modified.
|
||
*
|
||
* @param WC_Shipping_Zone $instance - Zone object.
|
||
* @param WC_Shipping_Zone_Data_Store_Interface $this_data_store - WC Data store.
|
||
*
|
||
* @return object $instance - Zone object.
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function detect_shipping_zone_change( $instance, $this_data_store ) {
|
||
$zone_name = $instance->get_zone_name();
|
||
Alert_Manager::trigger_event(
|
||
9082,
|
||
array(
|
||
'EventType' => $instance->get_id() ? 'modified' : 'created',
|
||
'ShippingZoneName' => sanitize_text_field( $zone_name ),
|
||
)
|
||
);
|
||
|
||
return $instance;
|
||
}
|
||
|
||
/**
|
||
* Trigger inline product change events.
|
||
*
|
||
* @param WC_Product $product - WooCommerce product.
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function inline_product_changed( $product ) {
|
||
unset( self::$request_data['woocommerce_quick_edit'] );
|
||
if ( ! isset( self::$old_post ) && ! isset( self::$_old_order ) ) {
|
||
return;
|
||
}
|
||
if ( is_int( $product ) ) {
|
||
$product = get_post( $product );
|
||
|
||
if ( 'shop_coupon' === $product->post_type ) {
|
||
$product = new WC_Coupon( $product->ID );
|
||
} else {
|
||
$product = new WC_Product( $product->ID );
|
||
}
|
||
}
|
||
|
||
self::event_changed( $product, true );
|
||
}
|
||
|
||
/**
|
||
* Triggered when a user accesses the admin area.
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function event_admin_init() {
|
||
WooCommerce_Sensor_Helper::check_settings_change();
|
||
WooCommerce_Sensor_Helper_Second::retrieve_attribute_data();
|
||
WooCommerce_Sensor_Helper_Second::check_wc_ajax_change_events();
|
||
}
|
||
|
||
|
||
/**
|
||
* Retrieve Old data.
|
||
*
|
||
* @param integer $order - WOO Order.
|
||
*
|
||
* @since 5.3.0
|
||
*/
|
||
public static function get_order_post_edit_data( $order ) {
|
||
if ( \is_object( $order ) && ( $order instanceof \WC_Order || $order instanceof \WC_Order_Refund ) ) {
|
||
self::$_old_order = $order;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Retrieve Old data.
|
||
*
|
||
* @param integer $post_id - Product ID.
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function get_before_post_edit_data( $post_id ) {
|
||
$post_id = (int) $post_id; // Making sure that the post id is integer.
|
||
$post = get_post( $post_id ); // Get post.
|
||
$thumb_id = get_post_thumbnail_id( $post->ID );
|
||
|
||
if ( ! empty( $post ) && $post instanceof \WP_Post && in_array( $post->post_type, array( 'product', 'shop_order', 'shop_coupon' ), true ) ) {
|
||
self::$old_post = $post;
|
||
self::$old_product = 'product' === $post->post_type ? wc_get_product( $post->ID ) : null;
|
||
self::$_old_order = 'shop_order' === $post->post_type ? wc_get_order( $post->ID ) : null;
|
||
self::$old_status = $post->post_status;
|
||
self::$_old_link = get_post_permalink( $post_id, false, true );
|
||
self::$_old_cats = 'product' === $post->post_type ? WooCommerce_Sensor_Helper::get_product_categories( self::$old_post ) : null;
|
||
self::$old_data = 'product' === $post->post_type ? WooCommerce_Sensor_Helper_Second::get_product_data( self::$old_product ) : null;
|
||
// self::$old_product_attributes = get_post_meta( $post->ID, '_product_attributes' );
|
||
self::$_old_meta_data = get_post_meta( $post->ID, '', false );
|
||
self::$_old_attachment_metadata = wp_get_attachment_metadata( $thumb_id );
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Checks if the product update is inline-edit or not.
|
||
*
|
||
* @return bool
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function check_inline_edit() {
|
||
if ( empty( self::$request_data ) ) {
|
||
self::$request_data = $_REQUEST; // phpcs:ignore
|
||
}
|
||
return ! empty( self::$request_data['woocommerce_quick_edit'] );
|
||
}
|
||
|
||
/**
|
||
* WooCommerce Product Updated.
|
||
*
|
||
* @param WP_Post $post - WC Product CPT object.
|
||
* @param integer $update - True if product update, false if product is new.
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function event_changed( $post, $update ) {
|
||
if ( ! $update ) {
|
||
self::event_creation( self::$old_post, $post );
|
||
return;
|
||
}
|
||
|
||
if ( ! isset( $post ) ) {
|
||
return;
|
||
}
|
||
|
||
$object = $post;
|
||
|
||
$post = get_post( $post->get_id() );
|
||
|
||
if ( 'product' === $post->post_type ) {
|
||
if (
|
||
( isset( self::$old_post ) && 'auto-draft' === self::$old_post->post_status && 'draft' === $post->post_status ) // Saving draft.
|
||
|| isset( self::$old_post ) && ( 'draft' === self::$old_post->post_status && 'publish' === $post->post_status ) // Publishing post.
|
||
|| isset( self::$old_post ) && ( 'auto-draft' === self::$old_post->post_status && 'publish' === $post->post_status )
|
||
) {
|
||
self::event_creation( self::$old_post, $post );
|
||
} else {
|
||
|
||
// Get new woocommerce product object.
|
||
$new_product = $object;
|
||
self::$new_data = WooCommerce_Sensor_Helper_Second::get_product_data( $new_product );
|
||
if ( empty( self::$new_data ) ) {
|
||
return;
|
||
}
|
||
|
||
$changes = 0;
|
||
$changes = WooCommerce_Sensor_Helper::check_categories_change( self::$_old_cats, WooCommerce_Sensor_Helper::get_product_categories( $post ), self::$old_post, $post )
|
||
+ WooCommerce_Sensor_Helper::check_short_description_change( self::$old_post, $post )
|
||
+ WooCommerce_Sensor_Helper::check_text_change( self::$old_post, $post )
|
||
+ WooCommerce_Sensor_Helper::check_date_change( self::$old_post, $post )
|
||
+ WooCommerce_Sensor_Helper::check_visibility_change( self::$old_post, $post )
|
||
+ WooCommerce_Sensor_Helper::check_status_change( self::$old_post, $post )
|
||
+ WooCommerce_Sensor_Helper::check_title_change( self::$old_post, $post )
|
||
+ WooCommerce_Sensor_Helper::check_product_type_change( self::$old_post )
|
||
+ WooCommerce_Sensor_Helper::check_catalog_visibility_change( self::$old_post )
|
||
+ WooCommerce_Sensor_Helper::check_featured_product( self::$old_post )
|
||
+ WooCommerce_Sensor_Helper::check_price_change( self::$old_post )
|
||
+ WooCommerce_Sensor_Helper::check_sku_change( self::$old_post )
|
||
+ WooCommerce_Sensor_Helper::check_stock_status_change( self::$old_post )
|
||
+ WooCommerce_Sensor_Helper::check_sold_individualy_change( self::$old_product )
|
||
+ WooCommerce_Sensor_Helper::check_stock_quantity_change( self::$old_post )
|
||
+ WooCommerce_Sensor_Helper::check_type_change( self::$old_post, $post )
|
||
+ WooCommerce_Sensor_Helper::check_weight_change( self::$old_post )
|
||
+ WooCommerce_Sensor_Helper::check_dimensions_change( self::$old_post )
|
||
+ WooCommerce_Sensor_Helper::check_downloadable_file_change( self::$old_post )
|
||
+ WooCommerce_Sensor_Helper::check_backorders_setting( self::$old_post )
|
||
+ WooCommerce_Sensor_Helper::check_upsells_change( self::$old_post )
|
||
+ WooCommerce_Sensor_Helper::check_cross_sell_change( self::$old_post )
|
||
+ WooCommerce_Sensor_Helper_Second::check_attributes_change( self::$old_post )
|
||
+ WooCommerce_Sensor_Helper_Second::check_image_change( self::$old_post )
|
||
+ WooCommerce_Sensor_Helper_Second::check_download_limit_change( self::$_old_meta_data )
|
||
+ WooCommerce_Sensor_Helper_Second::check_tax_status_change( self::$old_post, self::$_old_meta_data, self::$new_data )
|
||
+ WooCommerce_Sensor_Helper_Second::check_low_stock_threshold_change( self::$old_post, self::$_old_meta_data, self::$new_data );
|
||
|
||
if ( ! $changes ) {
|
||
// Change Permalink.
|
||
$changes = WooCommerce_Sensor_Helper::check_permalink_change( self::$_old_link, get_post_permalink( $post->ID, false, true ), $post );
|
||
if ( ! $changes ) {
|
||
// If no one of the above changes happen.
|
||
WooCommerce_Sensor_Helper::check_modify_change( self::$old_post, $post );
|
||
}
|
||
}
|
||
}
|
||
} elseif ( 'shop_order' === $post->post_type ) {
|
||
// Check order events.
|
||
WooCommerce_Sensor_Helper_Second::check_order_modify_change( $post->ID, self::$old_post, $post );
|
||
} elseif ( 'shop_order_placehold' === $post->post_type ) {
|
||
// Check order events.
|
||
WooCommerce_Sensor_Helper_Second::check_order_modify_change( $post->ID, self::$_old_order, $post );
|
||
} elseif ( 'shop_coupon' === $post->post_type ) {
|
||
if (
|
||
( isset( self::$old_post ) && 'auto-draft' === self::$old_post->post_status && 'draft' === $post->post_status ) // Saving draft.
|
||
|| isset( self::$old_post ) && ( 'draft' === self::$old_post->post_status && 'publish' === $post->post_status ) // Publishing post.
|
||
|| isset( self::$old_post ) && ( 'auto-draft' === self::$old_post->post_status && 'publish' === $post->post_status )
|
||
) {
|
||
self::event_creation( self::$old_post, $post );
|
||
} else {
|
||
|
||
WooCommerce_Sensor_Helper::check_short_description_change( self::$old_post, $post );
|
||
WooCommerce_Sensor_Helper::check_status_change( self::$old_post, $post );
|
||
WooCommerce_Sensor_Helper::check_title_change( self::$old_post, $post );
|
||
WooCommerce_Sensor_Helper::check_date_change( self::$old_post, $post );
|
||
WooCommerce_Sensor_Helper::check_visibility_change( self::$old_post, $post );
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Return Coupon Event Data.
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @param WP_Post $coupon - Coupon event data.
|
||
* @return array
|
||
*/
|
||
public static function get_coupon_event_data( $coupon ) {
|
||
if ( empty( $coupon ) || ! $coupon instanceof \WP_Post ) {
|
||
return array();
|
||
}
|
||
|
||
$editor_link = WooCommerce_Sensor_Helper_Second::get_editor_link( $coupon );
|
||
return array(
|
||
'CouponID' => $coupon->ID,
|
||
'CouponName' => $coupon->post_title,
|
||
'CouponStatus' => $coupon->post_status,
|
||
'PostStatus' => $coupon->post_status,
|
||
'CouponExcerpt' => $coupon->post_excerpt,
|
||
$editor_link['name'] => $editor_link['value'],
|
||
);
|
||
}
|
||
|
||
/**
|
||
* WooCommerce Product/Coupon Created.
|
||
*
|
||
* Trigger events 9000, 9001, 9063.
|
||
*
|
||
* @param object $old_post - Old Post.
|
||
* @param object $new_post - New Post.
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function event_creation( $old_post, $new_post ) {
|
||
if ( ! $old_post instanceof \WP_Post || ! $new_post instanceof \WP_Post ) {
|
||
return;
|
||
}
|
||
|
||
if ( 'product' === $old_post->post_type ) {
|
||
$editor_link = WooCommerce_Sensor_Helper_Second::get_editor_link( $new_post );
|
||
if ( 'publish' === $new_post->post_status ) {
|
||
Alert_Manager::trigger_event(
|
||
9001,
|
||
array(
|
||
'ProductTitle' => sanitize_text_field( $new_post->post_title ),
|
||
'ProductUrl' => get_post_permalink( $new_post->ID ),
|
||
'PostID' => esc_attr( $new_post->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $new_post->ID ) ),
|
||
'ProductStatus' => sanitize_text_field( $new_post->post_status ),
|
||
'PostStatus' => sanitize_text_field( $new_post->post_status ),
|
||
'OldStatus' => sanitize_text_field( $old_post->post_status ),
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
return 1;
|
||
} else {
|
||
Alert_Manager::trigger_event(
|
||
9000,
|
||
array(
|
||
'ProductTitle' => sanitize_text_field( $new_post->post_title ),
|
||
'PostID' => esc_attr( $new_post->ID ),
|
||
'ProductStatus' => sanitize_text_field( $new_post->post_status ),
|
||
'PostStatus' => sanitize_text_field( $new_post->post_status ),
|
||
'OldStatus' => sanitize_text_field( $old_post->post_status ),
|
||
'SKU' => esc_attr( self::get_product_sku( $new_post->ID ) ),
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
return 1;
|
||
}
|
||
} elseif ( 'shop_coupon' === $old_post->post_type ) {
|
||
$coupon_data = self::get_coupon_event_data( $new_post );
|
||
Alert_Manager::trigger_event(
|
||
9063,
|
||
$coupon_data
|
||
);
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Get a SKU for a given product ID.
|
||
*
|
||
* @param int $product_id - Id to lookup.
|
||
*
|
||
* @return int|string - Result.
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function get_product_sku( $product_id ) {
|
||
$product = wc_get_product( $product_id );
|
||
// If this is not an object, return.
|
||
if ( ! is_object( $product ) ) {
|
||
return;
|
||
}
|
||
$sku = $product->get_sku();
|
||
|
||
if ( isset( $_POST['variable_sku'] ) && isset( $_POST['variable_sku'][0] ) && ! empty( $_POST['variable_sku'][0] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||
$sku = sanitize_text_field( \wp_unslash( $_POST['variable_sku'][0] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||
}
|
||
|
||
/**
|
||
* For some reason the above could return empty string even if there is a SKU.
|
||
* Happens when product is created (first time) or when product is in draft but the user want to use preview option.
|
||
* Usually in that case the correct SKU is in the post array, so that code tries to extract that data from there - more debugging is needed here probably?
|
||
*/
|
||
if ( empty( $sku ) && isset( $_POST['_sku'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||
$sku = sanitize_text_field( \wp_unslash( $_POST['_sku'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||
} elseif ( empty( $sku ) ) {
|
||
$sku = __( 'Not provided', 'wp-security-audit-log' );
|
||
}
|
||
|
||
return $sku;
|
||
}
|
||
|
||
/**
|
||
* Trigger events 9002
|
||
*
|
||
* @param int|WP_Term $term_id - Term ID.
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function event_category_creation( $term_id = null ) {
|
||
$term = get_term( $term_id );
|
||
if ( ! empty( $term ) ) {
|
||
Alert_Manager::trigger_event(
|
||
9002,
|
||
array(
|
||
'CategoryName' => sanitize_text_field( $term->name ),
|
||
'Slug' => sanitize_text_field( $term->slug ),
|
||
'ProductCatLink' => Woocommerce_Helper::get_taxonomy_edit_link( $term_id ),
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Trigger events 9001
|
||
*
|
||
* @param int|WP_Term $term_id - Term ID.
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function event_tag_creation( $term_id = null ) {
|
||
$term = get_term( $term_id );
|
||
if ( ! empty( $term ) ) {
|
||
Alert_Manager::trigger_event(
|
||
9101,
|
||
array(
|
||
'CategoryName' => sanitize_text_field( $term->name ),
|
||
'Slug' => sanitize_text_field( $term->slug ),
|
||
'ProductTagLink' => Woocommerce_Helper::get_taxonomy_edit_link( $term_id, 'product_tag' ),
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Class property getter
|
||
*
|
||
* @return array
|
||
*
|
||
* @since 5.3.0
|
||
*/
|
||
public static function get_old_data() {
|
||
return self::$old_data;
|
||
}
|
||
|
||
/**
|
||
* Class property setter
|
||
*
|
||
* @param array $old_data - The array with data.
|
||
*
|
||
* @return void
|
||
*
|
||
* @since 5.3.0
|
||
*/
|
||
public static function set_old_data( $old_data ) {
|
||
self::$old_data = $old_data;
|
||
}
|
||
|
||
/**
|
||
* Class property getter
|
||
*
|
||
* @return array
|
||
*
|
||
* @since 5.3.0
|
||
*/
|
||
public static function get_new_data() {
|
||
return self::$new_data;
|
||
}
|
||
|
||
/**
|
||
* Class property getter
|
||
*
|
||
* @return stdClass
|
||
*
|
||
* @since 5.3.0
|
||
*/
|
||
public static function get_old_attr_data() {
|
||
return self::$old_attr_data;
|
||
}
|
||
|
||
/**
|
||
* Class property setter
|
||
*
|
||
* @param array $old_attr_data - The array with data.
|
||
*
|
||
* @return void
|
||
*
|
||
* @since 5.3.0
|
||
*/
|
||
public static function set_old_attr_data( $old_attr_data ) {
|
||
self::$old_attr_data = $old_attr_data;
|
||
}
|
||
|
||
/**
|
||
* Class property getter
|
||
*
|
||
* @return array
|
||
*
|
||
* @since 5.3.0
|
||
*/
|
||
public static function get_old_meta_data() {
|
||
return self::$_old_meta_data;
|
||
}
|
||
|
||
/**
|
||
* Class property setter
|
||
*
|
||
* @param array $old_meta_data - The array with data.
|
||
*
|
||
* @return void
|
||
*
|
||
* @since 5.3.0
|
||
*/
|
||
public static function set_old_meta_data( $old_meta_data ) {
|
||
self::$_old_meta_data = $old_meta_data;
|
||
}
|
||
|
||
/**
|
||
* Class property getter
|
||
*
|
||
* @return array
|
||
*
|
||
* @since 5.3.0
|
||
*/
|
||
public static function get_old_product() {
|
||
return self::$old_product;
|
||
}
|
||
|
||
/**
|
||
* Class property setter
|
||
*
|
||
* @param \WP_Post|null $old_product - The Product with data.
|
||
*
|
||
* @return void
|
||
*
|
||
* @since 5.3.0
|
||
*/
|
||
public static function set_old_product( $old_product ) {
|
||
self::$old_product = $old_product;
|
||
}
|
||
|
||
/**
|
||
* Class property getter
|
||
*
|
||
* @return \WP_Post|null
|
||
*
|
||
* @since 5.3.0
|
||
*/
|
||
public static function get_old_post() {
|
||
return self::$old_post;
|
||
}
|
||
|
||
/**
|
||
* Class property setter
|
||
*
|
||
* @param \WP_POST|null $old_post - The Postrray with data.
|
||
*
|
||
* @return void
|
||
*
|
||
* @since 5.3.0
|
||
*/
|
||
public static function set_old_post( $old_post ) {
|
||
self::$old_post = $old_post;
|
||
}
|
||
|
||
/**
|
||
* Class property getter
|
||
*
|
||
* @return array
|
||
*
|
||
* @since 5.3.0
|
||
*/
|
||
public static function get_new_location_data() {
|
||
return self::$new_location_data;
|
||
}
|
||
|
||
/**
|
||
* Class property setter
|
||
*
|
||
* @param array $new_location_data - The array with data.
|
||
*
|
||
* @return void
|
||
*
|
||
* @since 5.3.0
|
||
*/
|
||
public static function set_new_location_data( $new_location_data ) {
|
||
self::$new_location_data = $new_location_data;
|
||
}
|
||
|
||
/**
|
||
* Class property getter
|
||
*
|
||
* @return array
|
||
*
|
||
* @since 5.3.0
|
||
*/
|
||
public static function get_old_location_data() {
|
||
return self::$old_location_data;
|
||
}
|
||
|
||
/**
|
||
* Class property setter
|
||
*
|
||
* @param array $old_location_data - The array with data.
|
||
*
|
||
* @return void
|
||
*
|
||
* @since 5.3.0
|
||
*/
|
||
public static function set_old_location_data( $old_location_data ) {
|
||
self::$old_location_data = $old_location_data;
|
||
}
|
||
|
||
/**
|
||
* Class property getter
|
||
*
|
||
* @return string
|
||
*
|
||
* @since 5.3.0
|
||
*/
|
||
public static function get_old_status() {
|
||
return self::$old_status;
|
||
}
|
||
|
||
/**
|
||
* Class property getter
|
||
*
|
||
* @return \WC_Order|null
|
||
*
|
||
* @since 5.3.0
|
||
*/
|
||
public static function get_old_order() {
|
||
return self::$_old_order;
|
||
}
|
||
|
||
/**
|
||
* Class property getter
|
||
*
|
||
* @return array
|
||
*
|
||
* @since 5.3.0
|
||
*/
|
||
public static function get_old_attachment_metadata() {
|
||
return self::$_old_attachment_metadata;
|
||
}
|
||
|
||
/**
|
||
* Class property getter
|
||
*
|
||
* @return array
|
||
*
|
||
* @since 5.3.0
|
||
*/
|
||
public static function get_coupon_meta() {
|
||
return self::$coupon_meta;
|
||
}
|
||
|
||
/**
|
||
* Class property getter
|
||
*
|
||
* @return array
|
||
*
|
||
* @since 5.3.0
|
||
*/
|
||
public static function get_wc_user_meta() {
|
||
return self::$wc_user_meta;
|
||
}
|
||
|
||
/**
|
||
* Class property setter
|
||
*
|
||
* @param string $meta_key - The array key.
|
||
* @param mixed $value - The value to set.
|
||
*
|
||
* @return void
|
||
*
|
||
* @since 5.3.0
|
||
*/
|
||
public static function set_wc_user_meta( $meta_key, $value ) {
|
||
self::$wc_user_meta[ $meta_key ] = $value;
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
// Get Order ID and Key
|
||
$order->get_id();
|
||
$order->get_order_key();
|
||
|
||
// Get Order Totals $0.00
|
||
$order->get_formatted_order_total();
|
||
$order->get_cart_tax();
|
||
$order->get_currency();
|
||
$order->get_discount_tax();
|
||
$order->get_discount_to_display();
|
||
$order->get_discount_total();
|
||
$order->get_total_fees();
|
||
$order->get_formatted_line_subtotal();
|
||
$order->get_shipping_tax();
|
||
$order->get_shipping_total();
|
||
$order->get_subtotal();
|
||
$order->get_subtotal_to_display();
|
||
$order->get_tax_location();
|
||
$order->get_tax_totals();
|
||
$order->get_taxes();
|
||
$order->get_total();
|
||
$order->get_total_discount();
|
||
$order->get_total_tax();
|
||
$order->get_total_refunded();
|
||
$order->get_total_tax_refunded();
|
||
$order->get_total_shipping_refunded();
|
||
$order->get_item_count_refunded();
|
||
$order->get_total_qty_refunded();
|
||
$order->get_qty_refunded_for_item();
|
||
$order->get_total_refunded_for_item();
|
||
$order->get_tax_refunded_for_item();
|
||
$order->get_total_tax_refunded_by_rate_id();
|
||
$order->get_remaining_refund_amount();
|
||
|
||
// Get and Loop Over Order Items
|
||
foreach ( $order->get_items() as $item_id => $item ) {
|
||
$product_id = $item->get_product_id();
|
||
$variation_id = $item->get_variation_id();
|
||
$product = $item->get_product(); // see link above to get $product info
|
||
$product_name = $item->get_name();
|
||
$quantity = $item->get_quantity();
|
||
$subtotal = $item->get_subtotal();
|
||
$total = $item->get_total();
|
||
$tax = $item->get_subtotal_tax();
|
||
$tax_class = $item->get_tax_class();
|
||
$tax_status = $item->get_tax_status();
|
||
$allmeta = $item->get_meta_data();
|
||
$somemeta = $item->get_meta( '_whatever', true );
|
||
$item_type = $item->get_type(); // e.g. "line_item", "fee"
|
||
}
|
||
|
||
// Other Secondary Items Stuff
|
||
$order->get_items_key();
|
||
$order->get_items_tax_classes();
|
||
$order->get_item_count();
|
||
$order->get_item_total();
|
||
$order->get_downloadable_items();
|
||
$order->get_coupon_codes();
|
||
|
||
// Get Order Lines
|
||
$order->get_line_subtotal();
|
||
$order->get_line_tax();
|
||
$order->get_line_total();
|
||
|
||
// Get Order Shipping
|
||
$order->get_shipping_method();
|
||
$order->get_shipping_methods();
|
||
$order->get_shipping_to_display();
|
||
|
||
// Get Order Dates
|
||
$order->get_date_created();
|
||
$order->get_date_modified();
|
||
$order->get_date_completed();
|
||
$order->get_date_paid();
|
||
|
||
// Get Order User, Billing & Shipping Addresses
|
||
$order->get_customer_id();
|
||
$order->get_user_id();
|
||
$order->get_user();
|
||
$order->get_customer_ip_address();
|
||
$order->get_customer_user_agent();
|
||
$order->get_created_via();
|
||
$order->get_customer_note();
|
||
$order->get_address_prop();
|
||
$order->get_billing_first_name();
|
||
$order->get_billing_last_name();
|
||
$order->get_billing_company();
|
||
$order->get_billing_address_1();
|
||
$order->get_billing_address_2();
|
||
$order->get_billing_city();
|
||
$order->get_billing_state();
|
||
$order->get_billing_postcode();
|
||
$order->get_billing_country();
|
||
$order->get_billing_email();
|
||
$order->get_billing_phone();
|
||
$order->get_shipping_first_name();
|
||
$order->get_shipping_last_name();
|
||
$order->get_shipping_company();
|
||
$order->get_shipping_address_1();
|
||
$order->get_shipping_address_2();
|
||
$order->get_shipping_city();
|
||
$order->get_shipping_state();
|
||
$order->get_shipping_postcode();
|
||
$order->get_shipping_country();
|
||
$order->get_address();
|
||
$order->get_shipping_address_map_url();
|
||
$order->get_formatted_billing_full_name();
|
||
$order->get_formatted_shipping_full_name();
|
||
$order->get_formatted_billing_address();
|
||
$order->get_formatted_shipping_address();
|
||
|
||
// Get Order Payment Details
|
||
$order->get_payment_method();
|
||
$order->get_payment_method_title();
|
||
$order->get_transaction_id();
|
||
|
||
// Get Order URLs
|
||
$order->get_checkout_payment_url();
|
||
$order->get_checkout_order_received_url();
|
||
$order->get_cancel_order_url();
|
||
$order->get_cancel_order_url_raw();
|
||
$order->get_cancel_endpoint();
|
||
$order->get_view_order_url();
|
||
$order->get_edit_order_url();
|
||
|
||
// Get Order Status
|
||
$order->get_status();
|
||
|
||
// Get Thank You Page URL
|
||
$order->get_checkout_order_received_url();
|
||
*/
|