6158 lines
213 KiB
PHP
6158 lines
213 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;
|
||
|
||
// 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 {
|
||
|
||
/**
|
||
* Amount of seconds to check back for the given alert occurrence.
|
||
*
|
||
* @var integer
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static $seconds_to_check_back = 20;
|
||
|
||
/**
|
||
* 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 attributes Data.
|
||
*
|
||
* @var array
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static $old_product_attributes = 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();
|
||
|
||
/**
|
||
* Is Event 9067 Logged?
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @var boolean
|
||
*/
|
||
private static $is_9067_logged = false;
|
||
|
||
/**
|
||
* Is Event 9068 Logged?
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @var boolean
|
||
*/
|
||
private static $is_9068_logged = false;
|
||
|
||
/**
|
||
* Is Event 9016 Logged?
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @var array
|
||
*/
|
||
private static $last_9016_type = array();
|
||
|
||
/**
|
||
* Stores $_REQUEST global variable data.
|
||
*
|
||
* @var array
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static $request_data = array();
|
||
|
||
/**
|
||
* Count changed meta fields. Set to 1 as thats the minumum number of fields that can be changed.
|
||
*
|
||
* @var integer
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static $updated_field_count = 1;
|
||
|
||
/**
|
||
* Count changed shippinh meta fields. Set to 1 as thats the minumum number of fields that can be changed.
|
||
*
|
||
* @var integer
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static $updated_shipping_field_count = 1;
|
||
|
||
/**
|
||
* 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( '\WSAL\WP_Sensors\Helpers\Woocommerce_Helper', 'wsal_woocommerce_extension_add_custom_event_objects' )
|
||
);
|
||
|
||
if ( Woocommerce_Helper::is_woocommerce_active() ) {
|
||
add_filter(
|
||
'wsal_save_settings_disabled_events',
|
||
array(
|
||
'\WSAL\WP_Sensors\Helpers\Woocommerce_Helper',
|
||
'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( 'pre_post_update', array( __CLASS__, 'get_before_post_edit_data' ), 10, 2 );
|
||
|
||
\add_action( 'woocommerce_admin_process_product_object', array( __CLASS__, 'inline_product_changed' ), 10 );
|
||
\add_action( 'wp_after_insert_post', array( __CLASS__, 'order_updated' ), 10, 2 );
|
||
add_action( 'delete_post', array( __CLASS__, 'event_deleted' ), 10, 1 );
|
||
add_action( 'woocommerce_before_delete_order', array( __CLASS__, 'event_deleted' ), 10, 1 );
|
||
add_action( 'wp_trash_post', array( __CLASS__, 'event_trashed' ), 10, 1 );
|
||
add_action( 'woocommerce_trash_order', array( __CLASS__, 'event_trashed' ), 10, 1 );
|
||
add_action( 'untrash_post', array( __CLASS__, 'event_untrashed' ) );
|
||
add_action( 'woocommerce_untrash_order', array( __CLASS__, 'event_untrashed' ) );
|
||
add_action( 'wp_head', array( __CLASS__, 'viewing_product' ), 10 );
|
||
add_action( 'create_product_cat', array( __CLASS__, 'event_category_creation' ), 10, 1 );
|
||
add_filter( 'post_edit_form_tag', array( __CLASS__, 'editing_product' ), 10, 1 );
|
||
add_action( 'woocommerce_order_status_changed', array( __CLASS__, 'event_order_status_changed' ), 10, 4 );
|
||
add_action( 'woocommerce_order_refunded', array( __CLASS__, 'event_order_refunded' ), 10, 2 );
|
||
add_action( 'woocommerce_bulk_action_ids', array( __CLASS__, 'event_bulk_order_actions' ), 10, 2 );
|
||
add_action( 'woocommerce_attribute_added', array( __CLASS__, 'event_attribute_added' ), 10, 2 );
|
||
add_action( 'woocommerce_before_attribute_delete', array( __CLASS__, 'event_attribute_deleted' ), 10, 3 );
|
||
add_action( 'woocommerce_attribute_updated', array( __CLASS__, 'event_attribute_updated' ), 10, 3 );
|
||
add_action( 'wp_update_term_data', array( __CLASS__, 'event_product_cat_updated' ), 10, 4 );
|
||
add_action( 'update_term_meta', array( __CLASS__, 'event_cat_display_updated' ), 10, 4 );
|
||
add_action( 'delete_product_cat', array( __CLASS__, 'event_product_cat_deleted' ), 10, 4 );
|
||
add_action( 'delete_product_tag', array( __CLASS__, 'event_product_tag_deleted' ), 10, 4 );
|
||
add_action( 'wsal_before_post_meta_create_event', array( __CLASS__, 'log_coupon_meta_created_event' ), 10, 4 );
|
||
add_action( 'wsal_before_post_meta_update_event', array( __CLASS__, 'log_coupon_meta_update_events' ), 10, 5 );
|
||
add_action( 'wsal_before_post_meta_delete_event', array( __CLASS__, 'log_coupon_meta_delete_event' ), 10, 4 );
|
||
add_action( 'update_user_meta', array( __CLASS__, 'before_wc_user_meta_update' ), 10, 3 );
|
||
add_action( 'added_user_meta', array( __CLASS__, 'wc_user_meta_updated' ), 10, 4 );
|
||
add_action( 'updated_user_meta', array( __CLASS__, 'wc_user_meta_updated' ), 10, 4 );
|
||
add_action( 'woocommerce_before_product_object_save', array( __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( __CLASS__, 'settings_updated' ), 10, 3 );
|
||
add_action( 'create_product_tag', array( __CLASS__, 'event_tag_creation' ), 10, 1 );
|
||
add_action( 'update_postmeta', array( __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( __CLASS__, 'event_order_items_added' ), 10, 3 );
|
||
add_action( 'woocommerce_before_delete_order_item', array( __CLASS__, 'event_order_items_removed' ), 10, 1 );
|
||
add_action( 'woocommerce_before_save_order_items', array( __CLASS__, 'event_order_items_quantity_changed' ), 10, 2 );
|
||
add_action( 'woocommerce_refund_deleted', array( __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 );
|
||
},
|
||
10,
|
||
2
|
||
);
|
||
/**
|
||
* Add our filters.
|
||
*/
|
||
add_filter(
|
||
'wsal_event_type_data',
|
||
array( '\WSAL\WP_Sensors\Helpers\Woocommerce_Helper', 'wsal_woocommerce_extension_add_custom_event_type' ),
|
||
10,
|
||
2
|
||
);
|
||
add_filter(
|
||
'wsal_format_custom_meta',
|
||
array( '\WSAL\WP_Sensors\Helpers\Woocommerce_Helper', 'wsal_woocommerce_extension_add_custom_meta_format' ),
|
||
10,
|
||
4
|
||
);
|
||
add_filter(
|
||
'wsal_ignored_custom_post_types',
|
||
array( '\WSAL\WP_Sensors\Helpers\Woocommerce_Helper', 'wsal_woocommerce_extension_add_custom_ignored_cpt' )
|
||
);
|
||
add_filter(
|
||
'wsal_load_public_sensors',
|
||
array( '\WSAL\WP_Sensors\Helpers\Woocommerce_Helper', 'wsal_woocommerce_extension_load_public_sensors' )
|
||
);
|
||
add_filter(
|
||
'wsal_togglealerts_sub_category_events',
|
||
array( '\WSAL\WP_Sensors\Helpers\Woocommerce_Helper', 'wsal_woocommerce_extension_togglealerts_sub_category_events' )
|
||
);
|
||
add_filter(
|
||
'wsal_togglealerts_sub_category_titles',
|
||
array( '\WSAL\WP_Sensors\Helpers\Woocommerce_Helper', 'wsal_woocommerce_extension_togglealerts_sub_category_titles' ),
|
||
10,
|
||
2
|
||
);
|
||
add_action(
|
||
'wsal_togglealerts_append_content_to_toggle',
|
||
array( '\WSAL\WP_Sensors\Helpers\Woocommerce_Helper', 'wsal_woocommerce_extension_append_content_to_toggle' )
|
||
);
|
||
add_action(
|
||
'wsal_togglealerts_process_save_settings',
|
||
array( '\WSAL\WP_Sensors\Helpers\Woocommerce_Helper', 'wsal_woocommerce_extension_togglealerts_process_save_settings' ),
|
||
10,
|
||
1
|
||
);
|
||
add_filter(
|
||
'wsal_togglealerts_obsolete_events',
|
||
array( '\WSAL\WP_Sensors\Helpers\Woocommerce_Helper', 'wsal_woocommerce_extension_togglealerts_obsolete_events' )
|
||
);
|
||
|
||
add_action(
|
||
'admin_footer',
|
||
array( '\WSAL\WP_Sensors\Helpers\Woocommerce_Helper', 'wsal_woocommerce_extension_togglealerts_js_code' )
|
||
);
|
||
|
||
// Special events.
|
||
add_action(
|
||
'woocommerce_download_product',
|
||
array( '\WSAL\WP_Sensors\Helpers\Woocommerce_Helper', 'wsal_woocommerce_extension_detect_file_download' ),
|
||
10,
|
||
6
|
||
);
|
||
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 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() );
|
||
Alert_Manager::trigger_event(
|
||
9122,
|
||
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 = self::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' => $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 = self::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 ) {
|
||
self::check_price_change( self::$old_post );
|
||
} elseif ( 'stock_status' === $lookup_key ) {
|
||
self::check_stock_status_change( self::$old_post );
|
||
} elseif ( 'stock' === $lookup_key ) {
|
||
self::check_stock_quantity_change( self::$old_post );
|
||
} elseif ( 'sku' === $lookup_key ) {
|
||
self::check_sku_change( self::$old_post );
|
||
} elseif ( 'weight' === $lookup_key ) {
|
||
self::check_weight_change( self::$old_post );
|
||
} elseif ( 'tax_status' === $lookup_key ) {
|
||
self::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 ( 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() {
|
||
self::check_settings_change();
|
||
self::retrieve_attribute_data();
|
||
self::check_wc_ajax_change_events();
|
||
}
|
||
|
||
/**
|
||
* 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 ? self::get_product_categories( self::$old_post ) : null;
|
||
self::$old_data = 'product' === $post->post_type ? self::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 = self::get_product_data( $new_product );
|
||
if ( empty( self::$new_data ) ) {
|
||
return;
|
||
}
|
||
|
||
$changes = 0;
|
||
$changes = self::check_categories_change( self::$_old_cats, self::get_product_categories( $post ), self::$old_post, $post )
|
||
+ self::check_short_description_change( self::$old_post, $post )
|
||
+ self::check_text_change( self::$old_post, $post )
|
||
+ self::check_date_change( self::$old_post, $post )
|
||
+ self::check_visibility_change( self::$old_post, $post )
|
||
+ self::check_status_change( self::$old_post, $post )
|
||
+ self::check_title_change( self::$old_post, $post )
|
||
+ self::check_product_type_change( self::$old_post )
|
||
+ self::check_catalog_visibility_change( self::$old_post )
|
||
+ self::check_featured_product( self::$old_post )
|
||
+ self::check_price_change( self::$old_post )
|
||
+ self::check_sku_change( self::$old_post )
|
||
+ self::check_stock_status_change( self::$old_post )
|
||
+ self::check_stock_quantity_change( self::$old_post )
|
||
+ self::check_type_change( self::$old_post, $post )
|
||
+ self::check_weight_change( self::$old_post )
|
||
+ self::check_dimensions_change( self::$old_post )
|
||
+ self::check_downloadable_file_change( self::$old_post )
|
||
+ self::check_backorders_setting( self::$old_post )
|
||
+ self::check_upsells_change( self::$old_post )
|
||
+ self::check_cross_sell_change( self::$old_post )
|
||
+ self::check_attributes_change( self::$old_post )
|
||
+ self::check_image_change( self::$old_post )
|
||
+ self::check_download_limit_change( self::$_old_meta_data )
|
||
+ self::check_tax_status_change( self::$old_post, self::$_old_meta_data, self::$new_data )
|
||
+ self::check_low_stock_threshold_change( self::$old_post, self::$_old_meta_data, self::$new_data );
|
||
|
||
if ( ! $changes ) {
|
||
// Change Permalink.
|
||
$changes = self::check_permalink_change( self::$_old_link, get_post_permalink( $post->ID, false, true ), $post );
|
||
if ( ! $changes ) {
|
||
// If no one of the above changes happen.
|
||
self::check_modify_change( self::$old_post, $post );
|
||
}
|
||
}
|
||
}
|
||
} elseif ( 'shop_order' === $post->post_type ) {
|
||
// Check order events.
|
||
self::check_order_modify_change( $post->ID, self::$old_post, $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 {
|
||
// Check coupon events.
|
||
// $changes = 0 + self::event_creation( self::$old_post, $post );
|
||
|
||
// if ( ! $changes ) {
|
||
self::check_short_description_change( self::$old_post, $post );
|
||
self::check_status_change( self::$old_post, $post );
|
||
self::check_title_change( self::$old_post, $post );
|
||
self::check_date_change( self::$old_post, $post );
|
||
self::check_visibility_change( self::$old_post, $post );
|
||
// }
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Return Coupon Event Data.
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @param WP_Post $coupon - Coupon event data.
|
||
* @return array
|
||
*/
|
||
private static function get_coupon_event_data( $coupon ) {
|
||
if ( empty( $coupon ) || ! $coupon instanceof \WP_Post ) {
|
||
return array();
|
||
}
|
||
|
||
$editor_link = self::get_editor_link( $coupon );
|
||
return array(
|
||
'CouponID' => $coupon->ID,
|
||
'CouponName' => $coupon->post_title,
|
||
'CouponStatus' => $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 = self::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 ),
|
||
$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 ),
|
||
'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
|
||
*/
|
||
private 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();
|
||
|
||
/**
|
||
* 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' ),
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Trigger events 9003
|
||
*
|
||
* @param array $old_cats - Old Categories.
|
||
* @param array $new_cats - New Categories.
|
||
* @param object $oldpost - Old product object.
|
||
* @param object $newpost - New product object.
|
||
* @return int
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function check_categories_change( $old_cats, $new_cats, $oldpost, $newpost ) {
|
||
if ( 'trash' === $newpost->post_status || 'trash' === $oldpost->post_status ) {
|
||
return 0;
|
||
}
|
||
|
||
$old_cats = is_array( $old_cats ) ? implode( ', ', $old_cats ) : $old_cats;
|
||
$new_cats = is_array( $new_cats ) ? implode( ', ', $new_cats ) : $new_cats;
|
||
if ( ! empty( $old_cats ) && $old_cats !== $new_cats ) {
|
||
$editor_link = self::get_editor_link( $newpost );
|
||
Alert_Manager::trigger_event(
|
||
9003,
|
||
array(
|
||
'ProductTitle' => sanitize_text_field( $newpost->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $newpost->post_status ),
|
||
'PostID' => esc_attr( $newpost->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $newpost->ID ) ),
|
||
'OldCategories' => $old_cats ? sanitize_text_field( $old_cats ) : __( 'no categories', 'wp-security-audit-log' ),
|
||
'NewCategories' => $new_cats ? sanitize_text_field( $new_cats ) : __( 'no categories', 'wp-security-audit-log' ),
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Trigger events 9004
|
||
*
|
||
* @param object $oldpost - Old product object.
|
||
* @param object $newpost - New product object.
|
||
* @return int
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function check_short_description_change( $oldpost, $newpost ) {
|
||
if ( 'auto-draft' === $oldpost->post_status ) {
|
||
return 0;
|
||
}
|
||
|
||
if ( $oldpost->post_excerpt !== $newpost->post_excerpt ) {
|
||
if ( 'product' === $newpost->post_type ) {
|
||
$editor_link = self::get_editor_link( $oldpost );
|
||
Alert_Manager::trigger_event(
|
||
9004,
|
||
array(
|
||
'PostID' => esc_attr( $oldpost->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $oldpost->ID ) ),
|
||
'ProductTitle' => sanitize_text_field( $oldpost->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $oldpost->post_status ),
|
||
'OldDescription' => $oldpost->post_excerpt,
|
||
'NewDescription' => $newpost->post_excerpt,
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
return 1;
|
||
} elseif ( 'shop_coupon' === $newpost->post_type ) {
|
||
$coupon_data = self::get_coupon_event_data( $newpost );
|
||
$coupon_data['OldDescription'] = $oldpost->post_excerpt;
|
||
$coupon_data['NewDescription'] = $newpost->post_excerpt;
|
||
Alert_Manager::trigger_event( 9069, $coupon_data );
|
||
return 1;
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Trigger events 9005
|
||
*
|
||
* @param object $oldpost - Old product object.
|
||
* @param object $newpost - New product object.
|
||
* @return int
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function check_text_change( $oldpost, $newpost ) {
|
||
if ( 'auto-draft' === $oldpost->post_status ) {
|
||
return 0;
|
||
}
|
||
if ( $oldpost->post_content !== $newpost->post_content ) {
|
||
$editor_link = self::get_editor_link( $oldpost );
|
||
Alert_Manager::trigger_event(
|
||
9005,
|
||
array(
|
||
'PostID' => esc_attr( $oldpost->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $oldpost->ID ) ),
|
||
'ProductTitle' => sanitize_text_field( $oldpost->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $oldpost->post_status ),
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Trigger events 9006
|
||
*
|
||
* @param string $old_link - Old product link.
|
||
* @param string $new_link - New product link.
|
||
* @param object $post - Product object.
|
||
*
|
||
* @return int
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function check_permalink_change( $old_link, $new_link, $post ) {
|
||
if ( ! empty( $old_link ) && $old_link && $new_link && ( $old_link !== $new_link ) ) {
|
||
$editor_link = self::get_editor_link( $post );
|
||
Alert_Manager::trigger_event(
|
||
9006,
|
||
array(
|
||
'PostID' => esc_attr( $post->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $post->ID ) ),
|
||
'ProductTitle' => sanitize_text_field( $post->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $post->post_status ),
|
||
'OldUrl' => $old_link,
|
||
'NewUrl' => $new_link,
|
||
$editor_link['name'] => $editor_link['value'],
|
||
'ReportText' => '"' . $old_link . '"|"' . $new_link . '"',
|
||
)
|
||
);
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Trigger events 9007
|
||
*
|
||
* @param WP_Post $post - Product object.
|
||
*
|
||
* @return int
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function check_product_type_change( $post ) {
|
||
$old_type = isset( self::$old_data['type'] ) ? self::$old_data['type'] : false;
|
||
$new_type = isset( self::$new_data['type'] ) ? self::$new_data['type'] : false;
|
||
|
||
if ( $old_type !== $new_type ) {
|
||
$editor_link = self::get_editor_link( $post );
|
||
Alert_Manager::trigger_event(
|
||
9007,
|
||
array(
|
||
'PostID' => esc_attr( $post->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $post->ID ) ),
|
||
'ProductTitle' => sanitize_text_field( $post->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $post->post_status ),
|
||
'OldType' => $old_type,
|
||
'NewType' => $new_type,
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Trigger events 9008
|
||
*
|
||
* @param object $oldpost - Old product object.
|
||
* @param object $newpost - New product object.
|
||
* @return int
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function check_date_change( $oldpost, $newpost ) {
|
||
if ( 'draft' === $oldpost->post_status || 'auto-draft' === $oldpost->post_status ) {
|
||
return 0;
|
||
}
|
||
|
||
$from = strtotime( $oldpost->post_date );
|
||
$to = strtotime( $newpost->post_date );
|
||
|
||
if ( $from !== $to ) {
|
||
if ( 'shop_coupon' === $newpost->post_type ) {
|
||
$editor_link = self::get_editor_link( $oldpost );
|
||
Alert_Manager::trigger_event(
|
||
9126,
|
||
array(
|
||
'CouponID' => esc_attr( $oldpost->ID ),
|
||
'CouponName' => sanitize_text_field( $oldpost->post_title ),
|
||
'CouponStatus' => sanitize_text_field( $oldpost->post_status ),
|
||
'OldDate' => $oldpost->post_date,
|
||
'NewDate' => $newpost->post_date,
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
return 1;
|
||
} else {
|
||
$editor_link = self::get_editor_link( $oldpost );
|
||
Alert_Manager::trigger_event(
|
||
9008,
|
||
array(
|
||
'PostID' => esc_attr( $oldpost->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $oldpost->ID ) ),
|
||
'ProductTitle' => sanitize_text_field( $oldpost->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $oldpost->post_status ),
|
||
'OldDate' => $oldpost->post_date,
|
||
'NewDate' => $newpost->post_date,
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
return 1;
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Trigger events 9009
|
||
*
|
||
* @param WP_Post $oldpost - Old product object.
|
||
* @param WP_Post $newpost - New product object.
|
||
* @return int
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function check_visibility_change( $oldpost, $newpost ) {
|
||
if ( 'draft' === self::$old_status || 'draft' === $newpost->post_status ) {
|
||
return;
|
||
}
|
||
|
||
$old_visibility = '';
|
||
$new_visibility = '';
|
||
|
||
if ( $oldpost->post_password ) {
|
||
$old_visibility = __( 'Password Protected', 'wp-security-audit-log' );
|
||
} elseif ( 'publish' === self::$old_status ) {
|
||
$old_visibility = __( 'Public', 'wp-security-audit-log' );
|
||
} elseif ( 'private' === self::$old_status ) {
|
||
$old_visibility = __( 'Private', 'wp-security-audit-log' );
|
||
}
|
||
|
||
if ( $newpost->post_password ) {
|
||
$new_visibility = __( 'Password Protected', 'wp-security-audit-log' );
|
||
} elseif ( 'publish' === $newpost->post_status ) {
|
||
$new_visibility = __( 'Public', 'wp-security-audit-log' );
|
||
} elseif ( 'private' === $newpost->post_status ) {
|
||
$new_visibility = __( 'Private', 'wp-security-audit-log' );
|
||
}
|
||
|
||
if ( $old_visibility && $new_visibility && ( $old_visibility !== $new_visibility ) ) {
|
||
if ( 'shop_coupon' === $newpost->post_type ) {
|
||
$editor_link = self::get_editor_link( $oldpost );
|
||
Alert_Manager::trigger_event(
|
||
9125,
|
||
array(
|
||
'CouponID' => esc_attr( $oldpost->ID ),
|
||
'CouponCode' => sanitize_text_field( $oldpost->post_title ),
|
||
'CouponStatus' => sanitize_text_field( $oldpost->post_status ),
|
||
'OldVisibility' => $old_visibility,
|
||
'NewVisibility' => $new_visibility,
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
return 1;
|
||
} else {
|
||
$editor_link = self::get_editor_link( $oldpost );
|
||
Alert_Manager::trigger_event(
|
||
9009,
|
||
array(
|
||
'PostID' => esc_attr( $oldpost->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $oldpost->ID ) ),
|
||
'ProductTitle' => sanitize_text_field( $oldpost->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $oldpost->post_status ),
|
||
'OldVisibility' => $old_visibility,
|
||
'NewVisibility' => $new_visibility,
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
return 1;
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Check Title Change.
|
||
*
|
||
* Trigger event 9071.
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @param object $oldpost - Old product object.
|
||
* @param object $newpost - New product object.
|
||
* @return int
|
||
*/
|
||
private static function check_title_change( $oldpost, $newpost ) {
|
||
if ( 'auto-draft' === $oldpost->post_status ) {
|
||
return 0;
|
||
}
|
||
|
||
if ( 'shop_coupon' === $newpost->post_type && $oldpost->post_title !== $newpost->post_title ) {
|
||
// Get coupon event data.
|
||
$coupon_data = self::get_coupon_event_data( $newpost );
|
||
|
||
// Set old and new titles.
|
||
$coupon_data['OldName'] = $oldpost->post_title;
|
||
$coupon_data['NewName'] = $newpost->post_title;
|
||
|
||
// Log the event.
|
||
Alert_Manager::trigger_event( 9071, $coupon_data );
|
||
|
||
return 1;
|
||
} elseif ( 'product' === $newpost->post_type && $oldpost->post_title !== $newpost->post_title ) {
|
||
// Get editor link.
|
||
$editor_link = self::get_editor_link( $newpost );
|
||
|
||
// Log the event.
|
||
Alert_Manager::trigger_event(
|
||
9077,
|
||
array(
|
||
'PostID' => esc_attr( $newpost->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $newpost->ID ) ),
|
||
'ProductStatus' => sanitize_text_field( $newpost->post_status ),
|
||
'ProductTitle' => sanitize_text_field( $newpost->post_title ),
|
||
'OldTitle' => sanitize_text_field( $oldpost->post_title ),
|
||
'NewTitle' => sanitize_text_field( $newpost->post_title ),
|
||
'ProductUrl' => get_permalink( $newpost->ID ),
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Trigger events 9042
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @param WP_Post $post - Product object.
|
||
* @return int
|
||
*/
|
||
private static function check_catalog_visibility_change( $post ) {
|
||
// Get product data.
|
||
$old_visibility = isset( self::$old_data['catalog_visibility'] ) ? self::$old_data['catalog_visibility'] : false;
|
||
$new_visibility = isset( self::$new_data['catalog_visibility'] ) ? self::$new_data['catalog_visibility'] : false;
|
||
|
||
// Get WooCommerce visibility options.
|
||
$wc_visibilities = wc_get_product_visibility_options();
|
||
|
||
if ( ( $old_visibility && $new_visibility ) && ( $old_visibility !== $new_visibility ) ) {
|
||
$editor_link = self::get_editor_link( $post );
|
||
Alert_Manager::trigger_event(
|
||
9042,
|
||
array(
|
||
'PostID' => esc_attr( $post->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $post->ID ) ),
|
||
'ProductTitle' => sanitize_text_field( $post->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $post->post_status ),
|
||
'OldVisibility' => isset( $wc_visibilities[ $old_visibility ] ) ? $wc_visibilities[ $old_visibility ] : false,
|
||
'NewVisibility' => isset( $wc_visibilities[ $new_visibility ] ) ? $wc_visibilities[ $new_visibility ] : false,
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Trigger events 9043
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @param WP_Post $post - Product object.
|
||
* @return int
|
||
*/
|
||
private static function check_featured_product( $post ) {
|
||
$old_featured = isset( self::$old_data['featured'] ) ? self::$old_data['featured'] : false;
|
||
$new_featured = isset( self::$new_data['featured'] ) ? self::$new_data['featured'] : false;
|
||
|
||
if ( $old_featured !== $new_featured ) {
|
||
$editor_link = self::get_editor_link( $post );
|
||
Alert_Manager::trigger_event(
|
||
9043,
|
||
array(
|
||
'PostID' => esc_attr( $post->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $post->ID ) ),
|
||
'ProductTitle' => sanitize_text_field( $post->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $post->post_status ),
|
||
'EventType' => $new_featured ? 'enabled' : 'disabled',
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Trigger events 9044
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @param object $oldpost - Old product object.
|
||
* @param string $old_backorder - Old backorder value.
|
||
* @param string $new_backorder - New backorder value.
|
||
* @return int
|
||
*/
|
||
private static function check_backorders_setting( $oldpost, $old_backorder = '', $new_backorder = '' ) {
|
||
// Get product data.
|
||
if ( '' === $old_backorder ) {
|
||
$old_backorder = isset( self::$old_data['backorders'] ) ? self::$old_data['backorders'] : false;
|
||
}
|
||
if ( '' === $new_backorder ) {
|
||
$new_backorder = isset( self::$new_data['backorders'] ) ? self::$new_data['backorders'] : false;
|
||
}
|
||
|
||
if ( $old_backorder !== $new_backorder ) {
|
||
$editor_link = self::get_editor_link( $oldpost );
|
||
Alert_Manager::trigger_event(
|
||
9044,
|
||
array(
|
||
'PostID' => esc_attr( $oldpost->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $oldpost->ID ) ),
|
||
'ProductTitle' => sanitize_text_field( $oldpost->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $oldpost->post_status ),
|
||
'OldStatus' => $old_backorder,
|
||
'NewStatus' => $new_backorder,
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Trigger events 9045
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @param object $oldpost - Old product object.
|
||
* @return int
|
||
*/
|
||
private static function check_upsells_change( $oldpost ) {
|
||
// Get product data.
|
||
$old_upsell_ids = isset( self::$old_data['upsell_ids'] ) ? self::$old_data['upsell_ids'] : false;
|
||
$new_upsell_ids = isset( self::$new_data['upsell_ids'] ) ? self::$new_data['upsell_ids'] : false;
|
||
|
||
// Compute the difference.
|
||
$added_upsells = array();
|
||
$removed_upsells = array();
|
||
|
||
if ( is_array( $new_upsell_ids ) && is_array( $old_upsell_ids ) ) {
|
||
$added_upsells = array_diff( $new_upsell_ids, $old_upsell_ids );
|
||
$removed_upsells = array_diff( $old_upsell_ids, $new_upsell_ids );
|
||
}
|
||
|
||
// Get editor link.
|
||
$editor_link = self::get_editor_link( $oldpost );
|
||
|
||
// Return.
|
||
$return = 0;
|
||
|
||
// Added upsell products.
|
||
if ( ! empty( $added_upsells ) && is_array( $added_upsells ) ) {
|
||
foreach ( $added_upsells as $added_upsell ) {
|
||
$upsell_title = get_the_title( $added_upsell );
|
||
Alert_Manager::trigger_event(
|
||
9045,
|
||
array(
|
||
'EventType' => 'added',
|
||
'PostID' => esc_attr( $oldpost->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $oldpost->ID ) ),
|
||
'ProductTitle' => sanitize_text_field( $oldpost->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $oldpost->post_status ),
|
||
'UpsellTitle' => sanitize_text_field( $upsell_title ),
|
||
'UpsellID' => sanitize_text_field( $added_upsell ),
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
}
|
||
$return = 1;
|
||
}
|
||
|
||
// Removed upsell products.
|
||
if ( ! empty( $removed_upsells ) && is_array( $removed_upsells ) ) {
|
||
foreach ( $removed_upsells as $removed_upsell ) {
|
||
$upsell_title = get_the_title( $removed_upsell );
|
||
Alert_Manager::trigger_event(
|
||
9045,
|
||
array(
|
||
'EventType' => 'removed',
|
||
'PostID' => esc_attr( $oldpost->ID ),
|
||
'ProductTitle' => sanitize_text_field( $oldpost->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $oldpost->post_status ),
|
||
'UpsellTitle' => sanitize_text_field( $upsell_title ),
|
||
'UpsellID' => sanitize_text_field( $removed_upsell ),
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
}
|
||
$return = 1;
|
||
}
|
||
return $return;
|
||
}
|
||
|
||
/**
|
||
* Trigger events 9046
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @param object $oldpost - Old product object.
|
||
* @return int
|
||
*/
|
||
private static function check_cross_sell_change( $oldpost ) {
|
||
// Get product data.
|
||
$old_cross_sell_ids = isset( self::$old_data['cross_sell_ids'] ) ? self::$old_data['cross_sell_ids'] : false;
|
||
$new_cross_sell_ids = isset( self::$new_data['cross_sell_ids'] ) ? self::$new_data['cross_sell_ids'] : false;
|
||
|
||
// Compute the difference.
|
||
$added_cross_sells = array();
|
||
$removed_cross_sells = array();
|
||
if ( is_array( $new_cross_sell_ids ) && is_array( $old_cross_sell_ids ) ) {
|
||
$added_cross_sells = array_diff( $new_cross_sell_ids, $old_cross_sell_ids );
|
||
$removed_cross_sells = array_diff( $old_cross_sell_ids, $new_cross_sell_ids );
|
||
}
|
||
|
||
// Get editor link.
|
||
$editor_link = self::get_editor_link( $oldpost );
|
||
|
||
// Return.
|
||
$return = 0;
|
||
|
||
// Added cross-sell products.
|
||
if ( ! empty( $added_cross_sells ) && is_array( $added_cross_sells ) ) {
|
||
foreach ( $added_cross_sells as $added_cross_sell ) {
|
||
$cross_sell_title = get_the_title( $added_cross_sell );
|
||
Alert_Manager::trigger_event(
|
||
9046,
|
||
array(
|
||
'EventType' => 'added',
|
||
'PostID' => esc_attr( $oldpost->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $oldpost->ID ) ),
|
||
'ProductTitle' => sanitize_text_field( $oldpost->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $oldpost->post_status ),
|
||
'CrossSellTitle' => sanitize_text_field( $cross_sell_title ),
|
||
'CrossSellID' => sanitize_text_field( $added_cross_sell ),
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
}
|
||
$return = 1;
|
||
}
|
||
|
||
// Removed cross-sell products.
|
||
if ( ! empty( $removed_cross_sells ) && is_array( $removed_cross_sells ) ) {
|
||
foreach ( $removed_cross_sells as $removed_cross_sell ) {
|
||
$cross_sell_title = get_the_title( $removed_cross_sell );
|
||
Alert_Manager::trigger_event(
|
||
9046,
|
||
array(
|
||
'EventType' => 'removed',
|
||
'PostID' => esc_attr( $oldpost->ID ),
|
||
'ProductTitle' => sanitize_text_field( $oldpost->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $oldpost->post_status ),
|
||
'CrossSellTitle' => sanitize_text_field( $cross_sell_title ),
|
||
'CrossSellID' => sanitize_text_field( $removed_cross_sell ),
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
}
|
||
$return = 1;
|
||
}
|
||
return $return;
|
||
}
|
||
|
||
/**
|
||
* Trigger events 9010.
|
||
*
|
||
* @param object $oldpost - Old product object.
|
||
* @param object $newpost - New product object.
|
||
* @return int
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function check_modify_change( $oldpost, $newpost ) {
|
||
if ( 'trash' === $oldpost->post_status || 'trash' === $newpost->post_status || 'auto-draft' === $oldpost->post_status ) {
|
||
return 0;
|
||
}
|
||
|
||
// If the only change by this point is the "post_modified" time, then we really dont want
|
||
// to trigger this event.
|
||
$check_for_changes = array_diff( (array) $oldpost, (array) $newpost );
|
||
if ( ! empty( $check_for_changes ) && array_key_exists( 'post_modified', $check_for_changes ) ) {
|
||
return 0;
|
||
}
|
||
|
||
// Get Yoast alerts.
|
||
$yoast_alerts = Alert_Manager::get_alerts_by_category( 'Yoast SEO' );
|
||
$yoast_metabox_alerts = Alert_Manager::get_alerts_by_category( 'Yoast SEO Meta Box' );
|
||
$yoast_alerts = $yoast_alerts + $yoast_metabox_alerts;
|
||
|
||
// Check all alerts.
|
||
foreach ( $yoast_alerts as $alert_code => $alert ) {
|
||
if ( Alert_Manager::will_or_has_triggered( $alert_code ) ) {
|
||
return 0; // Return if any Yoast alert has or will trigger.
|
||
}
|
||
}
|
||
|
||
$editor_link = self::get_editor_link( $oldpost );
|
||
Alert_Manager::trigger_event_if(
|
||
9010,
|
||
array(
|
||
'PostID' => esc_attr( $oldpost->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $oldpost->ID ) ),
|
||
'ProductTitle' => sanitize_text_field( $oldpost->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $oldpost->post_status ),
|
||
'ProductUrl' => get_post_permalink( $oldpost->ID ),
|
||
$editor_link['name'] => $editor_link['value'],
|
||
),
|
||
array( __CLASS__, 'do_not_detect_variation_changes_as_product_modified' )
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Ensure 9010 does not fire for variable product changes.
|
||
*
|
||
* @return bool - Was triggered.
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function do_not_detect_variation_changes_as_product_modified() {
|
||
if ( Alert_Manager::will_or_has_triggered( 9016 ) || Alert_Manager::will_or_has_triggered( 9017 ) ) {
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
/**
|
||
* Moved to Trash 9012, 9037.
|
||
*
|
||
* @param int $post_id - Product/Order ID.
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function event_trashed( $post_id ) {
|
||
$post = wc_get_order( $post_id );
|
||
if ( false === $post ) {
|
||
$post = get_post( $post_id );
|
||
}
|
||
if ( empty( $post ) || ! $post instanceof \WP_Post ) {
|
||
if ( ! is_a( $post, '\Automattic\WooCommerce\Admin\Overrides\Order' ) ) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
if ( $post instanceof \WP_Post && 'product' === $post->post_type ) {
|
||
Alert_Manager::trigger_event(
|
||
9012,
|
||
array(
|
||
'PostID' => esc_attr( $post->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $post->ID ) ),
|
||
'ProductTitle' => sanitize_text_field( $post->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $post->post_status ),
|
||
'ProductUrl' => get_post_permalink( $post->ID ),
|
||
)
|
||
);
|
||
} elseif ( is_a( $post, '\Automattic\WooCommerce\Admin\Overrides\Order' ) ) {
|
||
$editor_link = self::get_editor_link( $post );
|
||
Alert_Manager::trigger_event(
|
||
9037,
|
||
array(
|
||
'OrderID' => esc_attr( $post->get_id() ),
|
||
'OrderTitle' => sanitize_text_field( Woocommerce_Helper::wsal_woocommerce_extension_get_order_title( $post->get_id() ) ),
|
||
'OrderStatus' => sanitize_text_field( $post->get_status() ),
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
} elseif ( 'shop_order' === $post->post_type ) {
|
||
$editor_link = self::get_editor_link( $post );
|
||
Alert_Manager::trigger_event(
|
||
9037,
|
||
array(
|
||
'OrderID' => esc_attr( $post->ID ),
|
||
'OrderTitle' => sanitize_text_field( Woocommerce_Helper::wsal_woocommerce_extension_get_order_title( $post->ID ) ),
|
||
'OrderStatus' => sanitize_text_field( $post->post_status ),
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
} elseif ( 'shop_coupon' === $post->post_type ) {
|
||
$editor_link = self::get_editor_link( $post );
|
||
Alert_Manager::trigger_event(
|
||
9123,
|
||
array(
|
||
'CouponID' => esc_attr( $post->ID ),
|
||
'CouponName' => sanitize_text_field( $post->post_title ),
|
||
'CouponStatus' => sanitize_text_field( $post->post_status ),
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Permanently deleted 9013 or 9039.
|
||
*
|
||
* @param int $post_id - Product/Order ID.
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function event_deleted( $post_id ) {
|
||
$post = wc_get_order( $post_id );
|
||
if ( false === $post ) {
|
||
$post = get_post( $post_id );
|
||
}
|
||
if ( empty( $post ) || ! $post instanceof \WP_Post ) {
|
||
if ( ! is_a( $post, '\Automattic\WooCommerce\Admin\Overrides\Order' ) ) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
if ( $post instanceof \WP_Post && 'product' === $post->post_type ) {
|
||
Alert_Manager::trigger_event(
|
||
9013,
|
||
array(
|
||
'PostID' => esc_attr( $post->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $post->ID ) ),
|
||
'ProductTitle' => sanitize_text_field( $post->post_title ),
|
||
)
|
||
);
|
||
} elseif ( is_a( $post, '\Automattic\WooCommerce\Admin\Overrides\Order' ) ) {
|
||
Alert_Manager::trigger_event(
|
||
9039,
|
||
array( 'OrderTitle' => sanitize_text_field( Woocommerce_Helper::wsal_woocommerce_extension_get_order_title( $post_id ) ) )
|
||
);
|
||
} elseif ( 'shop_order' === $post->post_type ) {
|
||
Alert_Manager::trigger_event(
|
||
9039,
|
||
array( 'OrderTitle' => sanitize_text_field( Woocommerce_Helper::wsal_woocommerce_extension_get_order_title( $post_id ) ) )
|
||
);
|
||
} elseif ( 'shop_coupon' === $post->post_type ) {
|
||
Alert_Manager::trigger_event(
|
||
9124,
|
||
array(
|
||
'CouponID' => esc_attr( $post->ID ),
|
||
'CouponCode' => sanitize_text_field( $post->post_title ),
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Restored from Trash 9014
|
||
*
|
||
* @param int $post_id - Product ID.
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function event_untrashed( $post_id ) {
|
||
$post = wc_get_order( $post_id );
|
||
if ( false === $post ) {
|
||
$post = get_post( $post_id );
|
||
}
|
||
if ( empty( $post ) || ! $post instanceof \WP_Post ) {
|
||
if ( ! is_a( $post, '\Automattic\WooCommerce\Admin\Overrides\Order' ) ) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
if ( $post instanceof \WP_Post && 'product' === $post->post_type ) {
|
||
$editor_link = self::get_editor_link( $post );
|
||
Alert_Manager::trigger_event(
|
||
9014,
|
||
array(
|
||
'PostID' => esc_attr( $post->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $post->ID ) ),
|
||
'ProductTitle' => sanitize_text_field( $post->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $post->post_status ),
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
} elseif ( is_a( $post, '\Automattic\WooCommerce\Admin\Overrides\Order' ) ) {
|
||
$editor_link = self::get_editor_link( $post );
|
||
Alert_Manager::trigger_event(
|
||
9038,
|
||
array(
|
||
'OrderID' => esc_attr( $post->get_id() ),
|
||
'OrderTitle' => sanitize_text_field( Woocommerce_Helper::wsal_woocommerce_extension_get_order_title( $post_id ) ),
|
||
'OrderStatus' => sanitize_text_field( $post->get_status() ),
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
} elseif ( 'shop_order' === $post->post_type ) {
|
||
$editor_link = self::get_editor_link( $post );
|
||
Alert_Manager::trigger_event(
|
||
9038,
|
||
array(
|
||
'OrderID' => esc_attr( $post->ID ),
|
||
'OrderTitle' => sanitize_text_field( Woocommerce_Helper::wsal_woocommerce_extension_get_order_title( $post_id ) ),
|
||
'OrderStatus' => sanitize_text_field( $post->post_status ),
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
} elseif ( 'shop_coupon' === $post->post_type ) {
|
||
$editor_link = self::get_editor_link( $post );
|
||
Alert_Manager::trigger_event(
|
||
9127,
|
||
array(
|
||
'CouponID' => esc_attr( $post->ID ),
|
||
'CouponCode' => sanitize_text_field( $post->post_title ),
|
||
'CouponStatus' => sanitize_text_field( $post->post_status ),
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Viewing Product Event.
|
||
*
|
||
* Alerts for viewing of product post type for WooCommerce.
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function viewing_product() {
|
||
|
||
// Retrieve the current post object.
|
||
$product = get_queried_object();
|
||
|
||
// Check product post type.
|
||
if ( ! empty( $product ) && $product instanceof \WP_Post && 'product' !== $product->post_type || ! empty( $product ) && ! isset( $product->post_status ) || ! function_exists( 'wc_get_product' ) ) {
|
||
return $product;
|
||
}
|
||
|
||
if ( is_user_logged_in() && ! is_admin() ) {
|
||
$current_path = isset( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : false;
|
||
if (
|
||
! empty( $_SERVER['HTTP_REFERER'] )
|
||
&& ! empty( $current_path )
|
||
&& false !== strpos( sanitize_text_field( wp_unslash( $_SERVER['HTTP_REFERER'] ) ), $current_path )
|
||
) {
|
||
// Ignore this if we were on the same page so we avoid double audit entries.
|
||
return;
|
||
}
|
||
|
||
if ( ! empty( $product->post_title ) ) {
|
||
$editor_link = self::get_editor_link( $product );
|
||
Alert_Manager::trigger_event(
|
||
9073,
|
||
array(
|
||
'PostID' => esc_attr( $product->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $product->ID ) ),
|
||
'PostType' => 'post', // Set to post to allow event to trigger (products are usually ignored).
|
||
'ProductStatus' => sanitize_text_field( $product->post_status ),
|
||
'ProductTitle' => sanitize_text_field( $product->post_title ),
|
||
'ProductUrl' => get_permalink( $product->ID ),
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Trigger events 9015
|
||
*
|
||
* @param object $oldpost - Old product object.
|
||
* @param object $newpost - New product object.
|
||
* @return int
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function check_status_change( $oldpost, $newpost ) {
|
||
if ( 'draft' === $oldpost->post_status || 'auto-draft' === $oldpost->post_status ) {
|
||
return 0;
|
||
}
|
||
if ( $oldpost->post_status !== $newpost->post_status ) {
|
||
if ( 'trash' !== $oldpost->post_status && 'trash' !== $newpost->post_status ) {
|
||
if ( 'product' === $newpost->post_type ) {
|
||
$editor_link = self::get_editor_link( $oldpost );
|
||
Alert_Manager::trigger_event(
|
||
9015,
|
||
array(
|
||
'PostID' => esc_attr( $oldpost->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $oldpost->ID ) ),
|
||
'ProductTitle' => sanitize_text_field( $oldpost->post_title ),
|
||
'OldStatus' => sanitize_text_field( $oldpost->post_status ),
|
||
'NewStatus' => sanitize_text_field( $newpost->post_status ),
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
return 1;
|
||
}
|
||
if ( 'shop_coupon' === $newpost->post_type ) {
|
||
// Get coupon data.
|
||
$coupon_data = self::get_coupon_event_data( $newpost );
|
||
// Set status event data.
|
||
$coupon_data['OldStatus'] = sanitize_text_field( $oldpost->post_status );
|
||
$coupon_data['NewStatus'] = sanitize_text_field( $newpost->post_status );
|
||
// Log the event.
|
||
Alert_Manager::trigger_event( 9070, $coupon_data );
|
||
return 1;
|
||
}
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Trigger events 9016
|
||
*
|
||
* @param WP_Post $post - Product object.
|
||
* @return int
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function check_price_change( $post ) {
|
||
$result = 0;
|
||
$old_price = isset( self::$old_data['regular_price'] ) ? self::$old_data['regular_price'] : false;
|
||
$old_sale_price = isset( self::$old_data['sale_price'] ) ? self::$old_data['sale_price'] : false;
|
||
$new_price = isset( self::$new_data['regular_price'] ) ? self::$new_data['regular_price'] : false;
|
||
$new_sale_price = isset( self::$new_data['sale_price'] ) ? self::$new_data['sale_price'] : false;
|
||
|
||
if ( ( $new_price ) && ( $old_price !== $new_price ) ) {
|
||
$result = self::event_price( $post, 'Regular price', $old_price, $new_price );
|
||
}
|
||
if ( ( $new_sale_price ) && ( $old_sale_price !== $new_sale_price ) ) {
|
||
$result = self::event_price( $post, 'Sale price', $old_sale_price, $new_sale_price );
|
||
}
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* Group the Price changes in one function
|
||
*
|
||
* @param object $post - Old Product Object.
|
||
* @param string $type - Price Type.
|
||
* @param int $old_price - Old Product Price.
|
||
* @param int $new_price - New Product Price.
|
||
* @return int
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function event_price( $post, $type, $old_price, $new_price ) {
|
||
$currency = self::get_currency_symbol( self::get_config( 'currency' ) );
|
||
$editor_link = self::get_editor_link( $post );
|
||
|
||
if ( empty( self::$last_9016_type ) || ! in_array( $type, self::$last_9016_type, true ) ) {
|
||
Alert_Manager::trigger_event(
|
||
9016,
|
||
array(
|
||
'PostID' => esc_attr( $post->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $post->ID ) ),
|
||
'ProductTitle' => sanitize_text_field( $post->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $post->post_status ),
|
||
'PriceType' => $type,
|
||
'OldPrice' => ! empty( $old_price ) ? $currency . $old_price : 0,
|
||
'NewPrice' => $currency . $new_price,
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
array_push( self::$last_9016_type, $type );
|
||
return 1;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Trigger events 9017
|
||
*
|
||
* @param object $oldpost - Old product object.
|
||
* @param string $old_sku - Old SKU.
|
||
* @param string $new_sku - New SKU.
|
||
* @return int
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function check_sku_change( $oldpost, $old_sku = '', $new_sku = '' ) {
|
||
if ( '' === $old_sku && '' === $new_sku ) {
|
||
$old_sku = isset( self::$old_data['sku'] ) ? self::$old_data['sku'] : false;
|
||
$new_sku = isset( self::$new_data['sku'] ) ? self::$new_data['sku'] : false;
|
||
}
|
||
|
||
if ( $new_sku && ( $old_sku !== $new_sku ) ) {
|
||
$editor_link = self::get_editor_link( $oldpost );
|
||
Alert_Manager::trigger_event(
|
||
9017,
|
||
array(
|
||
'PostID' => esc_attr( $oldpost->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $oldpost->ID ) ),
|
||
'ProductTitle' => sanitize_text_field( $oldpost->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $oldpost->post_status ),
|
||
'OldSku' => ! empty( $old_sku ) ? $old_sku : 0,
|
||
'NewSku' => $new_sku,
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Trigger events 9018
|
||
*
|
||
* @param object $oldpost - Old product object.
|
||
* @param string $old_status - Old status.
|
||
* @param string $new_status - New status.
|
||
* @return int
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function check_stock_status_change( $oldpost, $old_status = '', $new_status = '' ) {
|
||
if ( '' === $old_status && '' === $new_status ) {
|
||
$old_status = isset( self::$old_data['stock_status'] ) ? self::$old_data['stock_status'] : false;
|
||
$new_status = isset( self::$new_data['stock_status'] ) ? self::$new_data['stock_status'] : false;
|
||
}
|
||
|
||
if ( ( $old_status && $new_status ) && ( $old_status !== $new_status ) ) {
|
||
$editor_link = self::get_editor_link( $oldpost );
|
||
Alert_Manager::trigger_event(
|
||
9018,
|
||
array(
|
||
'PostID' => esc_attr( $oldpost->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $oldpost->ID ) ),
|
||
'ProductTitle' => sanitize_text_field( $oldpost->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $oldpost->post_status ),
|
||
'OldStatus' => sanitize_text_field( self::get_stock_status_name( $old_status ) ),
|
||
'NewStatus' => sanitize_text_field( self::get_stock_status_name( $new_status ) ),
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Trigger events 9019
|
||
*
|
||
* @param object $oldpost - Old product object.
|
||
* @param mixed $old_value - Old stock quantity.
|
||
* @param mixed $new_value - New stock quantity.
|
||
* @return int
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function check_stock_quantity_change( $oldpost, $old_value = false, $new_value = false ) {
|
||
if ( false === $old_value && false === $new_value ) {
|
||
if ( self::$old_data['manage_stock'] ) {
|
||
$old_value = isset( self::$old_data['stock_quantity'] ) ? self::$old_data['stock_quantity'] : false;
|
||
} else {
|
||
$old_value = false;
|
||
}
|
||
if ( self::$old_data['manage_stock'] ) {
|
||
$new_value = isset( self::$new_data['stock_quantity'] ) ? self::$new_data['stock_quantity'] : false;
|
||
} else {
|
||
$new_value = false;
|
||
}
|
||
}
|
||
|
||
if ( $new_value && ( $old_value !== $new_value ) ) {
|
||
$editor_link = self::get_editor_link( $oldpost );
|
||
Alert_Manager::trigger_event(
|
||
9019,
|
||
array(
|
||
'PostID' => esc_attr( $oldpost->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $oldpost->ID ) ),
|
||
'ProductTitle' => sanitize_text_field( $oldpost->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $oldpost->post_status ),
|
||
'OldValue' => ! empty( $old_value ) ? $old_value : '0',
|
||
'NewValue' => $new_value,
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Trigger events 9020
|
||
*
|
||
* @param object $oldpost - Old product object.
|
||
* @param object $newpost - New product object.
|
||
* @param mixed $virtual - Product virtual data.
|
||
* @param mixed $download - Product downloadable data.
|
||
* @return int
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function check_type_change( $oldpost, $newpost = null, $virtual = false, $download = false ) {
|
||
if ( 'trash' === $oldpost->post_status ) {
|
||
return 0;
|
||
}
|
||
|
||
if ( $newpost && $newpost instanceof \WP_Post && 'trash' === $newpost->post_status ) {
|
||
return 0;
|
||
}
|
||
|
||
// Set initial variables.
|
||
$old_virtual = false;
|
||
$new_virtual = false;
|
||
$old_download = false;
|
||
$new_download = false;
|
||
|
||
// Get simple product virtual data.
|
||
if ( false === $virtual ) {
|
||
$old_virtual = isset( self::$old_data['virtual'] ) ? self::$old_data['virtual'] : false;
|
||
$new_virtual = isset( self::$new_data['virtual'] ) ? self::$new_data['virtual'] : false;
|
||
} elseif ( is_array( $virtual ) ) {
|
||
$old_virtual = ( isset( $virtual['old'] ) && $virtual['old'] ) ? 'yes' : 'no';
|
||
$new_virtual = ( isset( $virtual['new'] ) && $virtual['new'] ) ? 'yes' : 'no';
|
||
}
|
||
|
||
// Get simple product downloadable data.
|
||
if ( false === $download ) {
|
||
$old_download = isset( self::$old_data['downloadable'] ) ? self::$old_data['downloadable'] : false;
|
||
$new_download = isset( self::$new_data['downloadable'] ) ? self::$new_data['downloadable'] : false;
|
||
} elseif ( is_array( $download ) ) {
|
||
$old_download = ( isset( $download['old'] ) && $download['old'] ) ? 'yes' : 'no';
|
||
$new_download = ( isset( $download['new'] ) && $download['new'] ) ? 'yes' : 'no';
|
||
}
|
||
|
||
// Return variable.
|
||
$result = 0;
|
||
|
||
if ( $old_virtual && $new_virtual && $old_virtual !== $new_virtual ) {
|
||
$editor_link = self::get_editor_link( $oldpost );
|
||
Alert_Manager::trigger_event(
|
||
9020,
|
||
array(
|
||
'PostID' => esc_attr( $oldpost->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $oldpost->ID ) ),
|
||
'ProductTitle' => sanitize_text_field( $oldpost->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $oldpost->post_status ),
|
||
'OldType' => 'yes' === $old_virtual ? 'Virtual' : 'Non-Virtual',
|
||
'NewType' => 'yes' === $new_virtual ? 'Virtual' : 'Non-Virtual',
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
$result = 1;
|
||
}
|
||
|
||
if ( $old_download && $new_download && $old_download !== $new_download ) {
|
||
$editor_link = self::get_editor_link( $oldpost );
|
||
Alert_Manager::trigger_event(
|
||
9020,
|
||
array(
|
||
'PostID' => esc_attr( $oldpost->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $oldpost->ID ) ),
|
||
'ProductTitle' => sanitize_text_field( $oldpost->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $oldpost->post_status ),
|
||
'OldType' => ( 'yes' === $old_download ) ? 'Downloadable' : 'Non-Downloadable',
|
||
'NewType' => ( 'yes' === $new_download ) ? 'Downloadable' : 'Non-Downloadable',
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
$result = 1;
|
||
}
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* Trigger events 9021
|
||
*
|
||
* @param object $oldpost - Old product object.
|
||
* @param string $old_weight - (Optional) Old weight.
|
||
* @param string $new_weight - (Optional) New weight.
|
||
* @return int
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function check_weight_change( $oldpost, $old_weight = '', $new_weight = '' ) {
|
||
if ( '' === $old_weight && '' === $new_weight ) {
|
||
$old_weight = isset( self::$old_data['weight'] ) ? self::$old_data['weight'] : false;
|
||
$new_weight = isset( self::$new_data['weight'] ) ? self::$new_data['weight'] : false;
|
||
}
|
||
|
||
if ( $new_weight && ( $old_weight !== $new_weight ) ) {
|
||
$weight_unit = self::get_config( 'weight_unit' );
|
||
$editor_link = self::get_editor_link( $oldpost );
|
||
Alert_Manager::trigger_event(
|
||
9021,
|
||
array(
|
||
'PostID' => esc_attr( $oldpost->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $oldpost->ID ) ),
|
||
'ProductTitle' => sanitize_text_field( $oldpost->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $oldpost->post_status ),
|
||
'OldWeight' => ! empty( $old_weight ) ? $old_weight . ' ' . $weight_unit : 0,
|
||
'NewWeight' => $new_weight . ' ' . $weight_unit,
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Trigger events 9022
|
||
*
|
||
* @param object $oldpost - Old product object.
|
||
* @param mixed $length - (Optional) Product lenght.
|
||
* @param mixed $width - (Optional) Product width.
|
||
* @param mixed $height - (Optional) Product height.
|
||
* @return int
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function check_dimensions_change( $oldpost, $length = false, $width = false, $height = false ) {
|
||
// Get product dimensions data.
|
||
$result = 0;
|
||
|
||
$old_length = false;
|
||
$new_length = false;
|
||
$old_width = false;
|
||
$new_width = false;
|
||
$old_height = false;
|
||
$new_height = false;
|
||
|
||
// Length.
|
||
if ( false === $length ) {
|
||
$old_length = isset( self::$old_data['length'] ) ? self::$old_data['length'] : false;
|
||
$new_length = isset( self::$new_data['length'] ) ? self::$new_data['length'] : false;
|
||
} elseif ( is_array( $length ) ) {
|
||
$old_length = isset( $length['old'] ) ? $length['old'] : false;
|
||
$new_length = isset( $length['new'] ) ? $length['new'] : false;
|
||
}
|
||
|
||
// Width.
|
||
if ( false === $width ) {
|
||
$old_width = isset( self::$old_data['width'] ) ? self::$old_data['width'] : false;
|
||
$new_width = isset( self::$new_data['width'] ) ? self::$new_data['width'] : false;
|
||
} elseif ( is_array( $width ) ) {
|
||
$old_width = isset( $width['old'] ) ? $width['old'] : false;
|
||
$new_width = isset( $width['new'] ) ? $width['new'] : false;
|
||
}
|
||
|
||
// Height.
|
||
if ( false === $height ) {
|
||
$old_height = isset( self::$old_data['height'] ) ? self::$old_data['height'] : false;
|
||
$new_height = isset( self::$new_data['height'] ) ? self::$new_data['height'] : false;
|
||
} elseif ( is_array( $height ) ) {
|
||
$old_height = isset( $height['old'] ) ? $height['old'] : false;
|
||
$new_height = isset( $height['new'] ) ? $height['new'] : false;
|
||
}
|
||
|
||
if ( $new_length && ( $old_length !== $new_length ) ) {
|
||
$result = self::event_dimension( $oldpost, 'Length', $old_length, $new_length );
|
||
}
|
||
if ( $new_width && ( $old_width !== $new_width ) ) {
|
||
$result = self::event_dimension( $oldpost, 'Width', $old_width, $new_width );
|
||
}
|
||
if ( $new_height && ( $old_height !== $new_height ) ) {
|
||
$result = self::event_dimension( $oldpost, 'Height', $old_height, $new_height );
|
||
}
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* Group the Dimension changes in one function.
|
||
*
|
||
* @param object $oldpost - Old Product object.
|
||
* @param string $type - Dimension type.
|
||
* @param string $old_dimension - Old dimension.
|
||
* @param string $new_dimension - New dimension.
|
||
* @return int
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function event_dimension( $oldpost, $type, $old_dimension, $new_dimension ) {
|
||
$dimension_unit = self::get_config( 'dimension_unit' );
|
||
$editor_link = self::get_editor_link( $oldpost );
|
||
Alert_Manager::trigger_event(
|
||
9022,
|
||
array(
|
||
'PostID' => esc_attr( $oldpost->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $oldpost->ID ) ),
|
||
'ProductTitle' => sanitize_text_field( $oldpost->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $oldpost->post_status ),
|
||
'DimensionType' => $type,
|
||
'OldDimension' => ! empty( $old_dimension ) ? $old_dimension . ' ' . $dimension_unit : 0,
|
||
'NewDimension' => $new_dimension . ' ' . $dimension_unit,
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
return 1;
|
||
}
|
||
|
||
/**
|
||
* Trigger events 9023, 9024, 9025, 9026
|
||
*
|
||
* @param object $oldpost - Old product object.
|
||
* @param mixed $file_names - (Optional) New product file names.
|
||
* @param mixed $file_urls - (Optional) New product file urls.
|
||
* @return int
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function check_downloadable_file_change( $oldpost, $file_names = false, $file_urls = false ) {
|
||
// Get product data.
|
||
$result = 0;
|
||
$is_url_changed = false;
|
||
$editor_link = self::get_editor_link( $oldpost );
|
||
|
||
if ( false === $file_names ) {
|
||
$old_file_names = isset( self::$old_data['file_names'] ) ? self::$old_data['file_names'] : array();
|
||
$new_file_names = isset( self::$new_data['file_names'] ) ? self::$new_data['file_names'] : array();
|
||
} else {
|
||
$old_file_names = isset( $file_names['old'] ) ? $file_names['old'] : array();
|
||
$new_file_names = isset( $file_names['new'] ) ? $file_names['new'] : array();
|
||
}
|
||
|
||
if ( false === $file_urls ) {
|
||
$old_file_urls = isset( self::$old_data['file_urls'] ) ? self::$old_data['file_urls'] : array();
|
||
$new_file_urls = isset( self::$new_data['file_urls'] ) ? self::$new_data['file_urls'] : array();
|
||
} else {
|
||
$old_file_urls = isset( $file_urls['old'] ) ? $file_urls['old'] : array();
|
||
$new_file_urls = isset( $file_urls['new'] ) ? $file_urls['new'] : array();
|
||
}
|
||
|
||
$added_urls = array_diff( $new_file_urls, $old_file_urls );
|
||
$removed_urls = array_diff( $old_file_urls, $new_file_urls );
|
||
$added_names = array_diff( $new_file_names, $old_file_names );
|
||
|
||
// Added files to the product.
|
||
if ( count( $added_urls ) > 0 ) {
|
||
// If the file has only changed URL.
|
||
if ( count( $new_file_urls ) === count( $old_file_urls ) ) {
|
||
$is_url_changed = true;
|
||
} else {
|
||
foreach ( $added_urls as $key => $url ) {
|
||
Alert_Manager::trigger_event(
|
||
9023,
|
||
array(
|
||
'PostID' => esc_attr( $oldpost->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $oldpost->ID ) ),
|
||
'ProductTitle' => sanitize_text_field( $oldpost->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $oldpost->post_status ),
|
||
'FileName' => sanitize_text_field( $new_file_names[ $key ] ),
|
||
'FileUrl' => $url,
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
}
|
||
$result = 1;
|
||
}
|
||
}
|
||
|
||
// Removed files from the product.
|
||
if ( count( $removed_urls ) > 0 ) {
|
||
// If the file has only changed URL.
|
||
if ( count( $new_file_urls ) === count( $old_file_urls ) ) {
|
||
$is_url_changed = true;
|
||
} else {
|
||
foreach ( $removed_urls as $key => $url ) {
|
||
Alert_Manager::trigger_event(
|
||
9024,
|
||
array(
|
||
'PostID' => esc_attr( $oldpost->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $oldpost->ID ) ),
|
||
'ProductTitle' => sanitize_text_field( $oldpost->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $oldpost->post_status ),
|
||
'FileName' => sanitize_text_field( $old_file_names[ $key ] ),
|
||
'FileUrl' => $url,
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
}
|
||
$result = 1;
|
||
}
|
||
}
|
||
|
||
if ( count( $added_names ) > 0 ) {
|
||
// If the file has only changed Name.
|
||
if ( count( $new_file_names ) === count( $old_file_names ) ) {
|
||
foreach ( $added_names as $key => $name ) {
|
||
Alert_Manager::trigger_event(
|
||
9025,
|
||
array(
|
||
'PostID' => esc_attr( $oldpost->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $oldpost->ID ) ),
|
||
'ProductTitle' => sanitize_text_field( $oldpost->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $oldpost->post_status ),
|
||
'OldName' => sanitize_text_field( $old_file_names[ $key ] ),
|
||
'NewName' => sanitize_text_field( $name ),
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
}
|
||
$result = 1;
|
||
}
|
||
}
|
||
|
||
if ( $is_url_changed ) {
|
||
foreach ( $added_urls as $key => $url ) {
|
||
Alert_Manager::trigger_event(
|
||
9026,
|
||
array(
|
||
'PostID' => esc_attr( $oldpost->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $oldpost->ID ) ),
|
||
'ProductTitle' => sanitize_text_field( $oldpost->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $oldpost->post_status ),
|
||
'FileName' => sanitize_text_field( $new_file_names[ $key ] ),
|
||
'OldUrl' => $removed_urls[ $key ],
|
||
'NewUrl' => $url,
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
}
|
||
$result = 1;
|
||
}
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* Trigger events Settings: 9027, 9028, 9029, 9030, 9031, 9032, 9033
|
||
*
|
||
* @param string $option - Option name.
|
||
* @param string $old_value - Previous value.
|
||
* @param mixed $value - New value.
|
||
*
|
||
* @return void
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function settings_updated( $option, $old_value, $value ) {
|
||
|
||
// Verify WooCommerce settings page nonce.
|
||
if ( isset( $_POST['_wpnonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) ), 'woocommerce-settings' ) ) {
|
||
// Verify settings page via $_GET array.
|
||
if ( isset( $_GET['page'] ) && 'wc-settings' === sanitize_text_field( wp_unslash( $_GET['page'] ) ) ) {
|
||
if ( isset( $_GET['tab'] ) && 'products' === sanitize_text_field( wp_unslash( $_GET['tab'] ) ) ) {
|
||
// Check weight unit event.
|
||
if ( isset( $_POST['woocommerce_weight_unit'] ) && 'woocommerce_weight_unit' === $option ) {
|
||
$old_unit = $old_value;
|
||
$new_unit = sanitize_text_field( wp_unslash( $value ) );
|
||
if ( $old_unit !== $new_unit ) {
|
||
Alert_Manager::trigger_event(
|
||
9027,
|
||
array(
|
||
'OldUnit' => sanitize_text_field( $old_unit ),
|
||
'NewUnit' => sanitize_text_field( $new_unit ),
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
// Check dimension unit event.
|
||
if ( isset( $_POST['woocommerce_dimension_unit'] ) && 'woocommerce_dimension_unit' === $option ) {
|
||
$old_unit = $old_value;
|
||
$new_unit = sanitize_text_field( wp_unslash( $value ) );
|
||
if ( $old_unit !== $new_unit ) {
|
||
Alert_Manager::trigger_event(
|
||
9028,
|
||
array(
|
||
'OldUnit' => sanitize_text_field( $old_unit ),
|
||
'NewUnit' => sanitize_text_field( $new_unit ),
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
// Check dimension unit event.
|
||
if ( 'woocommerce_enable_reviews' === $option ) {
|
||
$old_unit = $old_value;
|
||
$new_unit = sanitize_text_field( wp_unslash( $value ) );
|
||
if ( $old_unit !== $new_unit ) {
|
||
$event_type = ( 'yes' == $value ) ? 'enabled' : 'disabled';
|
||
Alert_Manager::trigger_event(
|
||
9100,
|
||
array(
|
||
'EventType' => $event_type,
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_review_rating_verification_label' === $option ) {
|
||
$old_unit = $old_value;
|
||
$new_unit = sanitize_text_field( wp_unslash( $value ) );
|
||
if ( $old_unit !== $new_unit ) {
|
||
$event_type = ( 'yes' == $value ) ? 'enabled' : 'disabled';
|
||
Alert_Manager::trigger_event(
|
||
9107,
|
||
array(
|
||
'EventType' => $event_type,
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_review_rating_verification_required' === $option ) {
|
||
$old_unit = $old_value;
|
||
$new_unit = sanitize_text_field( wp_unslash( $value ) );
|
||
if ( $old_unit !== $new_unit ) {
|
||
$event_type = ( 'yes' == $value ) ? 'enabled' : 'disabled';
|
||
Alert_Manager::trigger_event(
|
||
9108,
|
||
array(
|
||
'EventType' => $event_type,
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_enable_review_rating' === $option ) {
|
||
$old_unit = $old_value;
|
||
$new_unit = sanitize_text_field( wp_unslash( $value ) );
|
||
if ( $old_unit !== $new_unit ) {
|
||
$event_type = ( 'yes' == $value ) ? 'enabled' : 'disabled';
|
||
Alert_Manager::trigger_event(
|
||
9109,
|
||
array(
|
||
'EventType' => $event_type,
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_review_rating_required' === $option ) {
|
||
$old_unit = $old_value;
|
||
$new_unit = sanitize_text_field( wp_unslash( $value ) );
|
||
if ( $old_unit !== $new_unit ) {
|
||
$event_type = ( 'yes' == $value ) ? 'enabled' : 'disabled';
|
||
Alert_Manager::trigger_event(
|
||
9110,
|
||
array(
|
||
'EventType' => $event_type,
|
||
)
|
||
);
|
||
}
|
||
}
|
||
} elseif ( isset( $_GET['tab'] ) && 'account' === sanitize_text_field( wp_unslash( $_GET['tab'] ) ) ) {
|
||
// Guest Checkout event.
|
||
if ( 'woocommerce_enable_guest_checkout' === $option ) {
|
||
$old_enable_guest_checkout = $old_value;
|
||
$new_enable_guest_checkout = isset( $_POST['woocommerce_enable_guest_checkout'] ) ? 'yes' : 'no';
|
||
if ( $old_enable_guest_checkout !== $new_enable_guest_checkout ) {
|
||
$status = ( 'yes' === $new_enable_guest_checkout ) ? 'enabled' : 'disabled';
|
||
Alert_Manager::trigger_event( 9033, array( 'EventType' => $status ) );
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_enable_checkout_login_reminder' === $option ) {
|
||
if ( $old_value !== $value ) {
|
||
Alert_Manager::trigger_event(
|
||
9144,
|
||
array(
|
||
'EventType' => ( 'yes' === $value ) ? 'enabled' : 'disabled',
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_enable_signup_and_login_from_checkout' === $option ) {
|
||
if ( $old_value !== $value ) {
|
||
Alert_Manager::trigger_event(
|
||
9145,
|
||
array(
|
||
'EventType' => ( 'yes' === $value ) ? 'enabled' : 'disabled',
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_enable_myaccount_registration' === $option ) {
|
||
if ( $old_value !== $value ) {
|
||
Alert_Manager::trigger_event(
|
||
9146,
|
||
array(
|
||
'EventType' => ( 'yes' === $value ) ? 'enabled' : 'disabled',
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_registration_generate_username' === $option ) {
|
||
if ( $old_value !== $value ) {
|
||
Alert_Manager::trigger_event(
|
||
9147,
|
||
array(
|
||
'EventType' => ( 'yes' === $value ) ? 'enabled' : 'disabled',
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_registration_generate_password' === $option ) {
|
||
if ( $old_value !== $value ) {
|
||
Alert_Manager::trigger_event(
|
||
9148,
|
||
array(
|
||
'EventType' => ( 'yes' === $value ) ? 'enabled' : 'disabled',
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_erasure_request_removes_order_data' === $option ) {
|
||
if ( $old_value !== $value ) {
|
||
Alert_Manager::trigger_event(
|
||
9149,
|
||
array(
|
||
'EventType' => ( 'yes' === $value ) ? 'enabled' : 'disabled',
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_erasure_request_removes_download_data' === $option ) {
|
||
if ( $old_value !== $value ) {
|
||
Alert_Manager::trigger_event(
|
||
9150,
|
||
array(
|
||
'EventType' => ( 'yes' === $value ) ? 'enabled' : 'disabled',
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_allow_bulk_remove_personal_data' === $option ) {
|
||
if ( $old_value !== $value ) {
|
||
Alert_Manager::trigger_event(
|
||
9151,
|
||
array(
|
||
'EventType' => ( 'yes' === $value ) ? 'enabled' : 'disabled',
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_registration_privacy_policy_text' === $option ) {
|
||
if ( $old_value !== $value ) {
|
||
Alert_Manager::trigger_event(
|
||
9152,
|
||
array(
|
||
'old_setting' => $old_value,
|
||
'new_setting' => $value,
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_checkout_privacy_policy_text' === $option ) {
|
||
if ( $old_value !== $value ) {
|
||
Alert_Manager::trigger_event(
|
||
9153,
|
||
array(
|
||
'old_setting' => $old_value,
|
||
'new_setting' => $value,
|
||
)
|
||
);
|
||
}
|
||
}
|
||
} if ( isset( $_GET['tab'] ) && 'tax' === sanitize_text_field( wp_unslash( $_GET['tab'] ) ) ) {
|
||
// Check prices entered with tax setting.
|
||
if ( isset( $_POST['woocommerce_prices_include_tax'] ) && 'woocommerce_prices_include_tax' === $option ) {
|
||
$old_price_tax = $old_value;
|
||
$new_price_tax = sanitize_text_field( wp_unslash( $_POST['woocommerce_prices_include_tax'] ) );
|
||
if ( $old_price_tax !== $new_price_tax ) {
|
||
Alert_Manager::trigger_event( 9078, array( 'TaxStatus' => 'yes' === $new_price_tax ? 'including' : 'excluding' ) );
|
||
}
|
||
}
|
||
|
||
// Check calculate tax based on setting.
|
||
if ( isset( $_POST['woocommerce_tax_based_on'] ) && 'woocommerce_tax_based_on' === $option ) {
|
||
$old_tax_base = $old_value;
|
||
$new_tax_base = sanitize_text_field( wp_unslash( $_POST['woocommerce_tax_based_on'] ) );
|
||
if ( $old_tax_base !== $new_tax_base ) {
|
||
$setting = '';
|
||
if ( 'shipping' === $new_tax_base ) {
|
||
$setting = __( 'Customer shipping address', 'wp-security-audit-log' );
|
||
} elseif ( 'billing' === $new_tax_base ) {
|
||
$setting = __( 'Customer billing address', 'wp-security-audit-log' );
|
||
} elseif ( 'base' === $new_tax_base ) {
|
||
$setting = __( 'Shop base address', 'wp-security-audit-log' );
|
||
} else {
|
||
$setting = __( 'Customer shipping address', 'wp-security-audit-log' );
|
||
}
|
||
Alert_Manager::trigger_event(
|
||
9079,
|
||
array(
|
||
'Setting' => sanitize_text_field( $setting ),
|
||
'OldTaxBase' => sanitize_text_field( $old_tax_base ),
|
||
'NewTaxBase' => sanitize_text_field( $new_tax_base ),
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
// Check shipping tax class setting.
|
||
if ( isset( $_POST['woocommerce_shipping_tax_class'] ) && 'woocommerce_shipping_tax_class' === $option ) {
|
||
$old_tax_class = $old_value;
|
||
$new_tax_class = sanitize_text_field( wp_unslash( $_POST['woocommerce_shipping_tax_class'] ) );
|
||
if ( $old_tax_class !== $new_tax_class ) {
|
||
$setting = '';
|
||
if ( 'inherit' === $new_tax_class ) {
|
||
$setting = __( 'Shipping tax class based on cart items', 'wp-security-audit-log' );
|
||
} elseif ( 'reduced-rate' === $new_tax_class ) {
|
||
$setting = __( 'Reduced rate' );
|
||
} elseif ( 'zero-rate' === $new_tax_class ) {
|
||
$setting = __( 'Zero rate', 'wp-security-audit-log' );
|
||
} elseif ( empty( $new_tax_class ) ) {
|
||
$setting = __( 'Standard', 'wp-security-audit-log' );
|
||
} else {
|
||
$setting = __( 'Shipping tax class based on cart items', 'wp-security-audit-log' );
|
||
}
|
||
Alert_Manager::trigger_event(
|
||
9080,
|
||
array(
|
||
'Setting' => sanitize_text_field( $setting ),
|
||
'OldTaxClass' => sanitize_text_field( $old_tax_class ),
|
||
'NewTaxClass' => sanitize_text_field( $new_tax_class ),
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
// Check rounding of tax setting.
|
||
if ( 'woocommerce_tax_round_at_subtotal' === $option ) {
|
||
$old_tax_round = $old_value;
|
||
$new_tax_round = isset( $_POST['woocommerce_tax_round_at_subtotal'] ) ? 'yes' : 'no';
|
||
if ( $old_tax_round !== $new_tax_round ) {
|
||
Alert_Manager::trigger_event( 9081, array( 'EventType' => 'yes' === $new_tax_round ? 'enabled' : 'disabled' ) );
|
||
}
|
||
}
|
||
} elseif ( empty( $_GET['tab'] ) || 'general' === sanitize_text_field( wp_unslash( $_GET['tab'] ) ) ) {
|
||
// "Enable Coupon" event.
|
||
if ( 'woocommerce_enable_coupons' === $option ) {
|
||
$old_enable_coupons = $old_value;
|
||
$new_enable_coupons = isset( $_POST['woocommerce_enable_coupons'] ) ? 'yes' : 'no';
|
||
if ( $old_enable_coupons !== $new_enable_coupons ) {
|
||
$status = 'yes' === $new_enable_coupons ? 'enabled' : 'disabled';
|
||
Alert_Manager::trigger_event( 9032, array( 'EventType' => $status ) );
|
||
}
|
||
}
|
||
|
||
if ( isset( $_POST['woocommerce_store_address'] ) && 'woocommerce_store_address' === $option || isset( $_POST['woocommerce_store_address_2'] ) && 'woocommerce_store_address_2' === $option || isset( $_POST['woocommerce_store_city'] ) && 'woocommerce_store_city' === $option || isset( $_POST['woocommerce_default_country'] ) && 'woocommerce_default_country' === $option || isset( $_POST['woocommerce_store_postcode'] ) && 'woocommerce_store_postcode' === $option ) {
|
||
// Default country event.
|
||
if ( 'woocommerce_store_address' === $option ) {
|
||
self::$old_location_data = $old_value . ', ' . self::get_config( 'store_address_2' ) . ', ' . self::get_config( 'store_city' ) . ', ' . WC()->countries->countries[ strtok( self::get_config( 'default_country' ), ':' ) ] . ', ' . self::get_config( 'store_postcode' );
|
||
self::$new_location_data = sanitize_text_field( wp_unslash( $_POST['woocommerce_store_address'] ) ) . ', ' . self::get_config( 'store_address_2' ) . ', ' . self::get_config( 'store_city' ) . ', ' . WC()->countries->countries[ strtok( self::get_config( 'default_country' ), ':' ) ] . ', ' . self::get_config( 'store_postcode' );
|
||
}
|
||
if ( 'woocommerce_store_address_2' === $option ) {
|
||
self::$old_location_data = self::get_config( 'store_address' ) . ', ' . $old_value . ', ' . self::get_config( 'store_city' ) . ', ' . WC()->countries->countries[ strtok( self::get_config( 'default_country' ), ':' ) ] . ', ' . self::get_config( 'store_postcode' );
|
||
self::$new_location_data = self::get_config( 'store_address' ) . ', ' . sanitize_text_field( wp_unslash( $_POST['woocommerce_store_address_2'] ) ) . ', ' . self::get_config( 'store_city' ) . ', ' . WC()->countries->countries[ strtok( self::get_config( 'default_country' ), ':' ) ] . ', ' . self::get_config( 'store_postcode' );
|
||
}
|
||
if ( 'woocommerce_store_city' === $option ) {
|
||
self::$old_location_data = self::get_config( 'store_address' ) . ', ' . self::get_config( 'store_address_2' ) . ', ' . $old_value . ', ' . self::get_config( 'default_country' ) . ', ' . self::get_config( 'store_postcode' );
|
||
self::$new_location_data = self::get_config( 'store_address' ) . ', ' . self::get_config( 'store_address_2' ) . ', ' . sanitize_text_field( wp_unslash( $_POST['woocommerce_store_city'] ) ) . ', ' . WC()->countries->countries[ strtok( self::get_config( 'default_country' ), ':' ) ] . ', ' . self::get_config( 'store_postcode' );
|
||
}
|
||
if ( 'woocommerce_default_country' === $option ) {
|
||
self::$old_location_data = self::get_config( 'store_address' ) . ', ' . self::get_config( 'store_address_2' ) . ', ' . self::get_config( 'store_address' ) . ', ' . WC()->countries->countries[ strtok( $old_value, ':' ) ] . ', ' . $old_value;
|
||
self::$new_location_data = self::get_config( 'store_address' ) . ', ' . self::get_config( 'store_address_2' ) . ', ' . self::get_config( 'store_address' ) . ', ' . WC()->countries->countries[ strtok( sanitize_text_field( wp_unslash( $_POST['woocommerce_default_country'] ) ), ':' ) ] . ', ' . self::get_config( 'store_postcode' );
|
||
}
|
||
if ( 'woocommerce_store_postcode' === $option ) {
|
||
self::$old_location_data = self::get_config( 'store_address' ) . ', ' . self::get_config( 'store_address_2' ) . ', ' . self::get_config( 'store_address' ) . ', ' . self::get_config( 'default_country' ) . ', ' . $old_value;
|
||
self::$new_location_data = self::get_config( 'store_address' ) . ', ' . self::get_config( 'store_address_2' ) . ', ' . self::get_config( 'store_address' ) . ', ' . WC()->countries->countries[ strtok( self::get_config( 'default_country' ), ':' ) ] . ', ' . sanitize_text_field( wp_unslash( $_POST['woocommerce_store_postcode'] ) );
|
||
}
|
||
|
||
if ( self::$old_location_data !== self::$new_location_data ) {
|
||
sleep( 1 );
|
||
self::$new_location_data = sanitize_text_field( wp_unslash( $_POST['woocommerce_store_address'] ) ) . ', ' . sanitize_text_field( wp_unslash( $_POST['woocommerce_store_address_2'] ) ) . ', ' . sanitize_text_field( wp_unslash( $_POST['woocommerce_store_city'] ) ) . ', ' . WC()->countries->countries[ strtok( sanitize_text_field( wp_unslash( $_POST['woocommerce_default_country'] ) ), ':' ) ] . ', ' . sanitize_text_field( wp_unslash( $_POST['woocommerce_store_postcode'] ) );
|
||
if ( ! Alert_Manager::was_triggered_recently( 9029 ) ) {
|
||
Alert_Manager::trigger_event(
|
||
9029,
|
||
array(
|
||
'OldLocation' => sanitize_text_field( self::$old_location_data ),
|
||
'NewLocation' => sanitize_text_field( self::$new_location_data ),
|
||
)
|
||
);
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_allowed_countries' === $option ) {
|
||
if ( $old_value !== $value ) {
|
||
Alert_Manager::trigger_event(
|
||
9085,
|
||
array(
|
||
'old' => sanitize_text_field( $old_value ),
|
||
'new' => sanitize_text_field( $value ),
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_specific_allowed_countries' === $option ) {
|
||
if ( empty( $old_value ) ) {
|
||
$old_value = get_option( 'woocommerce_specific_allowed_countries' );
|
||
}
|
||
if ( $old_value !== $value ) {
|
||
// Check if any old values are present.
|
||
if ( ! empty( $old_value ) ) {
|
||
$old_country_codes = '';
|
||
// add each old country to a string to output in alert.
|
||
foreach ( $old_value as $old_country_code ) {
|
||
$old_country_codes .= WC()->countries->countries[ $old_country_code ] . ', ';
|
||
}
|
||
} else {
|
||
$old_country_codes = __( 'None, ', 'wp-security-audit-log' );
|
||
}
|
||
// Check if any new values are present.
|
||
if ( ! empty( $value ) ) {
|
||
$country_codes = '';
|
||
foreach ( $value as $country_code ) {
|
||
$country_codes .= WC()->countries->countries[ $country_code ] . ', ';
|
||
}
|
||
} else {
|
||
$country_codes = __( 'None', 'wp-security-audit-log' );
|
||
}
|
||
Alert_Manager::trigger_event(
|
||
9087,
|
||
array(
|
||
'old' => rtrim( $old_country_codes, ', ' ),
|
||
'new' => rtrim( $country_codes, ', ' ),
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_all_except_countries' === $option ) {
|
||
if ( empty( $old_value ) ) {
|
||
$old_value = get_option( 'woocommerce_all_except_countries' );
|
||
}
|
||
if ( $old_value !== $value ) {
|
||
// Check if any old values are present.
|
||
if ( ! empty( $old_value ) ) {
|
||
$old_country_codes = '';
|
||
// add each old country to a string to output in alert.
|
||
foreach ( $old_value as $old_country_code ) {
|
||
$old_country_codes .= WC()->countries->countries[ $old_country_code ] . ', ';
|
||
}
|
||
} else {
|
||
$old_country_codes = __( 'None, ', 'wp-security-audit-log' );
|
||
}
|
||
// Check if any new values are present.
|
||
if ( ! empty( $value ) ) {
|
||
$country_codes = '';
|
||
foreach ( $value as $country_code ) {
|
||
$country_codes .= WC()->countries->countries[ $country_code ] . ', ';
|
||
}
|
||
} else {
|
||
$country_codes = __( 'None', 'wp-security-audit-log' );
|
||
}
|
||
Alert_Manager::trigger_event(
|
||
9086,
|
||
array(
|
||
'old' => rtrim( $old_country_codes, ', ' ),
|
||
'new' => rtrim( $country_codes, ', ' ),
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_ship_to_countries' === $option && 'NULL' !== $value ) {
|
||
if ( $old_value !== $value ) {
|
||
$value = ( '' === $value ) ? __( 'Ship to all countries you sell to', 'wp-security-audit-log' ) : $value;
|
||
$old_value = ( '' === $old_value ) ? __( 'Ship to all countries you sell to', 'wp-security-audit-log' ) : $old_value;
|
||
|
||
Alert_Manager::trigger_event(
|
||
9088,
|
||
array(
|
||
'old' => $old_value,
|
||
'new' => $value,
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_specific_ship_to_countries' === $option && 'NULL' !== $value ) {
|
||
if ( empty( $old_value ) ) {
|
||
$old_value = get_option( 'woocommerce_specific_ship_to_countries' );
|
||
}
|
||
if ( $old_value !== $value ) {
|
||
// Check if any old values are present.
|
||
if ( ! empty( $old_value ) ) {
|
||
$old_country_codes = '';
|
||
// add each old country to a string to output in alert.
|
||
foreach ( $old_value as $old_country_code ) {
|
||
$old_country_codes .= WC()->countries->countries[ $old_country_code ] . ', ';
|
||
}
|
||
} else {
|
||
$old_country_codes = __( 'None, ', 'wp-security-audit-log' );
|
||
}
|
||
// Check if any new values are present.
|
||
if ( ! empty( $value ) ) {
|
||
$country_codes = '';
|
||
foreach ( $value as $country_code ) {
|
||
$country_codes .= WC()->countries->countries[ $country_code ] . ', ';
|
||
}
|
||
} else {
|
||
$country_codes = __( 'None', 'wp-security-audit-log' );
|
||
}
|
||
Alert_Manager::trigger_event(
|
||
9089,
|
||
array(
|
||
'old' => rtrim( $old_country_codes, ', ' ),
|
||
'new' => rtrim( $country_codes, ', ' ),
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_default_customer_address' === $option ) {
|
||
if ( $old_value !== $value ) {
|
||
$value = ( '' === $value ) ? __( 'No default location', 'wp-security-audit-log' ) : $value;
|
||
$old_value = ( '' === $old_value ) ? __( 'No default location', 'wp-security-audit-log' ) : $old_value;
|
||
|
||
Alert_Manager::trigger_event(
|
||
9090,
|
||
array(
|
||
'old' => sanitize_text_field( $old_value ),
|
||
'new' => sanitize_text_field( $value ),
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
// Calculate taxes event.
|
||
if ( 'woocommerce_calc_taxes' === $option ) {
|
||
$old_calc_taxes = $old_value;
|
||
$new_calc_taxes = isset( $_POST['woocommerce_calc_taxes'] ) ? 'yes' : 'no';
|
||
if ( $old_calc_taxes !== $new_calc_taxes ) {
|
||
$status = 'yes' === $new_calc_taxes ? 'enabled' : 'disabled';
|
||
Alert_Manager::trigger_event( 9030, array( 'EventType' => $status ) );
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_currency_pos' === $option ) {
|
||
if ( $old_value !== $value ) {
|
||
Alert_Manager::trigger_event(
|
||
9115,
|
||
array(
|
||
'old_setting' => $old_value,
|
||
'new_setting' => $value,
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_price_thousand_sep' === $option ) {
|
||
if ( $old_value !== $value ) {
|
||
Alert_Manager::trigger_event(
|
||
9116,
|
||
array(
|
||
'old_setting' => $old_value,
|
||
'new_setting' => $value,
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_price_decimal_sep' === $option ) {
|
||
if ( $old_value !== $value ) {
|
||
Alert_Manager::trigger_event(
|
||
9117,
|
||
array(
|
||
'old_setting' => $old_value,
|
||
'new_setting' => $value,
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_price_num_decimals' === $option ) {
|
||
if ( $old_value !== $value ) {
|
||
Alert_Manager::trigger_event(
|
||
9118,
|
||
array(
|
||
'old_setting' => $old_value,
|
||
'new_setting' => $value,
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
// Store current event.
|
||
if ( 'woocommerce_currency' === $option ) {
|
||
if ( isset( $_POST['woocommerce_currency'] ) ) {
|
||
if ( 'NULL' === $old_value ) {
|
||
$old_value = get_option( ' woocommerce_currency' );
|
||
} else {
|
||
$old_currency = $old_value;
|
||
}
|
||
$new_currency = sanitize_text_field( wp_unslash( $_POST['woocommerce_currency'] ) );
|
||
if ( $old_currency !== $new_currency ) {
|
||
Alert_Manager::trigger_event(
|
||
9031,
|
||
array(
|
||
'OldCurrency' => sanitize_text_field( $old_currency ),
|
||
'NewCurrency' => sanitize_text_field( $new_currency ),
|
||
)
|
||
);
|
||
}
|
||
}
|
||
}
|
||
} elseif ( empty( $_GET['tab'] ) || 'advanced' === sanitize_text_field( wp_unslash( $_GET['tab'] ) ) ) {
|
||
if ( 'woocommerce_cart_page_id' === $option ) {
|
||
if ( $old_value !== $value ) {
|
||
if ( 'NULL' === $old_value ) {
|
||
$old_value = get_option( ' woocommerce_cart_page_id' );
|
||
} else {
|
||
$old_value = get_the_title( $old_value );
|
||
}
|
||
Alert_Manager::trigger_event(
|
||
9091,
|
||
array(
|
||
'old' => sanitize_text_field( $old_value ),
|
||
'new' => get_the_title( $value ),
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_checkout_page_id' === $option ) {
|
||
if ( $old_value !== $value ) {
|
||
if ( 'NULL' === $old_value ) {
|
||
$old_value = get_option( ' woocommerce_cart_page_id' );
|
||
} else {
|
||
$old_value = get_the_title( $old_value );
|
||
}
|
||
Alert_Manager::trigger_event(
|
||
9092,
|
||
array(
|
||
'old' => sanitize_text_field( $old_value ),
|
||
'new' => get_the_title( $value ),
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_myaccount_page_id' === $option ) {
|
||
if ( $old_value !== $value ) {
|
||
Alert_Manager::trigger_event(
|
||
9093,
|
||
array(
|
||
'old' => get_the_title( $old_value ),
|
||
'new' => get_the_title( $value ),
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_terms_page_id' === $option ) {
|
||
if ( $old_value !== $value ) {
|
||
Alert_Manager::trigger_event(
|
||
9094,
|
||
array(
|
||
'old' => get_the_title( $old_value ),
|
||
'new' => get_the_title( $value ),
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( strpos( $option, 'woocommerce_checkout' ) !== false ) {
|
||
if ( $old_value !== $value ) {
|
||
Alert_Manager::trigger_event(
|
||
9111,
|
||
array(
|
||
'endpoint_name' => str_replace( 'woocommerce_checkout_', '', str_replace( '_endpoint', '', $option ) ),
|
||
'old' => $old_value,
|
||
'new_value' => $value,
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( strpos( $option, 'woocommerce_myaccount' ) !== false ) {
|
||
if ( $old_value !== $value ) {
|
||
Alert_Manager::trigger_event(
|
||
9112,
|
||
array(
|
||
'endpoint_name' => str_replace( 'woocommerce_myaccount_', '', str_replace( '_endpoint', '', $option ) ),
|
||
'old' => $old_value,
|
||
'new_value' => $value,
|
||
)
|
||
);
|
||
}
|
||
}
|
||
} elseif ( empty( $_GET['tab'] ) || 'shipping' === sanitize_text_field( wp_unslash( $_GET['tab'] ) ) ) {
|
||
if ( 'woocommerce_enable_shipping_calc' === $option ) {
|
||
if ( $old_value !== $value ) {
|
||
Alert_Manager::trigger_event(
|
||
9140,
|
||
array(
|
||
'EventType' => ( 'yes' === $value ) ? 'enabled' : 'disabled',
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_shipping_cost_requires_address' === $option ) {
|
||
if ( $old_value !== $value ) {
|
||
Alert_Manager::trigger_event(
|
||
9141,
|
||
array(
|
||
'EventType' => ( $value ) ? 'enabled' : 'disabled',
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_shipping_debug_mode' === $option ) {
|
||
if ( $old_value !== $value ) {
|
||
Alert_Manager::trigger_event(
|
||
9143,
|
||
array(
|
||
'EventType' => ( $value ) ? 'enabled' : 'disabled',
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( 'woocommerce_ship_to_destination' === $option ) {
|
||
if ( $old_value !== $value ) {
|
||
Alert_Manager::trigger_event(
|
||
9142,
|
||
array(
|
||
'old_setting' => $old_value,
|
||
'new_setting' => $value,
|
||
)
|
||
);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Trigger events Settings: 9027, 9028, 9029, 9030, 9031, 9032, 9033
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function check_settings_change() {
|
||
// Verify WooCommerce settings page nonce.
|
||
if ( isset( $_REQUEST['_wpnonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) ), 'woocommerce-settings' ) ) {
|
||
// Verify settings page via $_GET array.
|
||
if ( isset( $_GET['page'] ) && 'wc-settings' === sanitize_text_field( wp_unslash( $_GET['page'] ) ) ) {
|
||
if ( isset( $_GET['tab'] ) && 'checkout' === sanitize_text_field( wp_unslash( $_GET['tab'] ) ) ) {
|
||
// Get payment method.
|
||
$gateway = isset( $_GET['section'] ) ? sanitize_text_field( wp_unslash( $_GET['section'] ) ) : false;
|
||
|
||
// Set to true if payment gateways are enabled or disabled.
|
||
$status_change = false;
|
||
|
||
// Check Cash On Delivery section.
|
||
if ( $gateway && 'cod' === sanitize_text_field( wp_unslash( $gateway ) ) ) {
|
||
// Check COD event.
|
||
$old_cash_on_delivery = self::get_config( 'cod_settings' );
|
||
$old_cash_on_delivery = isset( $old_cash_on_delivery['enabled'] ) ? $old_cash_on_delivery['enabled'] : '';
|
||
$new_cash_on_delivery = isset( $_POST['woocommerce_cod_enabled'] ) ? 'yes' : 'no';
|
||
|
||
// Check status change.
|
||
if ( $old_cash_on_delivery !== $new_cash_on_delivery ) {
|
||
$status = 'yes' === $new_cash_on_delivery ? 'enabled' : 'disabled';
|
||
Alert_Manager::trigger_event( 9034, array( 'EventType' => $status ) );
|
||
$status_change = true;
|
||
}
|
||
} elseif ( $gateway ) {
|
||
// Get old gateway settings.
|
||
$gateway_settings = self::get_config( $gateway . '_settings' );
|
||
$old_gateway_status = isset( $gateway_settings['enabled'] ) ? $gateway_settings['enabled'] : false;
|
||
$new_gateway_status = isset( $_POST[ 'woocommerce_' . $gateway . '_enabled' ] ) ? 'yes' : 'no';
|
||
|
||
// Check status change.
|
||
if ( $old_gateway_status !== $new_gateway_status ) {
|
||
// Gateway enabled.
|
||
Alert_Manager::trigger_event(
|
||
9074,
|
||
array(
|
||
'GatewayID' => sanitize_text_field( $gateway ),
|
||
'GatewayName' => isset( $gateway_settings['title'] ) ? $gateway_settings['title'] : false,
|
||
'EventType' => 'yes' === $new_gateway_status ? 'enabled' : 'disabled',
|
||
)
|
||
);
|
||
$status_change = true;
|
||
}
|
||
}
|
||
|
||
if ( $gateway && ! $status_change ) {
|
||
$gateway_settings = self::get_config( $gateway . '_settings' );
|
||
Alert_Manager::trigger_event(
|
||
9076,
|
||
array(
|
||
'GatewayID' => sanitize_text_field( $gateway ),
|
||
'GatewayName' => isset( $gateway_settings['title'] ) ? $gateway_settings['title'] : false,
|
||
)
|
||
);
|
||
}
|
||
}
|
||
}
|
||
|
||
$webhook_id = ( isset( $_POST['webhook_id'] ) ) ? \sanitize_text_field( wp_unslash( $_POST['webhook_id'] ) ) : false;
|
||
if ( $webhook_id ) {
|
||
// Gather POSTed (freshest) data.
|
||
$new_webhook_data = array(
|
||
'id' => $webhook_id,
|
||
'name' => isset( $_POST['webhook_name'] ) ? \sanitize_text_field( wp_unslash( $_POST['webhook_name'] ) ) : '',
|
||
'delivery_url' => isset( $_POST['webhook_delivery_url'] ) ? \sanitize_text_field( wp_unslash( $_POST['webhook_delivery_url'] ) ) : '',
|
||
'topic' => isset( $_POST['webhook_topic'] ) ? \sanitize_text_field( wp_unslash( $_POST['webhook_topic'] ) ) : '',
|
||
'status' => isset( $_POST['webhook_status'] ) ? \sanitize_text_field( wp_unslash( $_POST['webhook_status'] ) ) : '',
|
||
'secret' => isset( $_POST['webhook_secret'] ) ? \sanitize_text_field( wp_unslash( $_POST['webhook_secret'] ) ) : '',
|
||
);
|
||
|
||
// Get a current copy of the soon to be "old" version for comparison.
|
||
$data_store = \WC_Data_Store::load( 'webhook' );
|
||
$webhooks = $data_store->search_webhooks( array( 'limit' => -1 ) );
|
||
$old_hook_found = false;
|
||
foreach ( $webhooks as $wc_webkook_key => $lookup_id ) {
|
||
$id_we_want = intval( $webhook_id );
|
||
if ( $id_we_want === $lookup_id && ! $old_hook_found ) {
|
||
$old_hook_found = true;
|
||
$old_webhook = wc_get_webhook( $id_we_want );
|
||
continue;
|
||
}
|
||
}
|
||
|
||
if ( ! $old_hook_found ) {
|
||
return;
|
||
}
|
||
|
||
$alert_needed = false;
|
||
|
||
if ( isset( $old_webhook ) ) {
|
||
// Tidy up data for comparison.
|
||
$old_webhook_data = array(
|
||
'id' => $webhook_id,
|
||
'name' => $old_webhook->get_name(),
|
||
'delivery_url' => $old_webhook->get_delivery_url(),
|
||
'topic' => $old_webhook->get_topic(),
|
||
'status' => $old_webhook->get_status(),
|
||
'secret' => $old_webhook->get_secret(),
|
||
);
|
||
|
||
foreach ( $new_webhook_data as $key => $data ) {
|
||
if ( $old_webhook_data[ $key ] !== $new_webhook_data[ $key ] ) {
|
||
$alert_needed = true;
|
||
}
|
||
}
|
||
|
||
if ( $alert_needed ) {
|
||
$editor_link = Woocommerce_Helper::create_webhook_editor_link( $webhook_id );
|
||
Alert_Manager::trigger_event(
|
||
9122,
|
||
array(
|
||
'HookName' => $new_webhook_data['name'],
|
||
'OldHookName' => $old_webhook_data['name'],
|
||
'DeliveryURL' => $new_webhook_data['delivery_url'],
|
||
'OldDeliveryURL' => $old_webhook_data['delivery_url'],
|
||
'Topic' => $new_webhook_data['topic'],
|
||
'OldTopic' => $old_webhook_data['topic'],
|
||
'Status' => $new_webhook_data['status'],
|
||
'OldStatus' => $old_webhook_data['status'],
|
||
'Secret' => $new_webhook_data['secret'],
|
||
'OldSecret' => $old_webhook_data['secret'],
|
||
'EditorLinkWebhook' => $editor_link,
|
||
)
|
||
);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Verify nonce for payment gateways.
|
||
if ( isset( $_POST['security'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['security'] ) ), 'woocommerce-toggle-payment-gateway-enabled' ) ) {
|
||
if ( isset( $_POST['action'] ) && 'woocommerce_toggle_gateway_enabled' === sanitize_text_field( wp_unslash( $_POST['action'] ) ) ) {
|
||
// Get payment gateways.
|
||
$payment_gateways = WC()->payment_gateways->payment_gateways();
|
||
|
||
if ( ! empty( $payment_gateways ) ) {
|
||
foreach ( $payment_gateways as $gateway ) {
|
||
// Get gateway ID.
|
||
$gateway_id = isset( $_POST['gateway_id'] ) ? sanitize_text_field( wp_unslash( $_POST['gateway_id'] ) ) : false;
|
||
|
||
// Check if the gateway id matches any available gateway ids.
|
||
if ( ! in_array( $gateway_id, array( $gateway->id, sanitize_title( get_class( $gateway ) ) ), true ) ) {
|
||
continue;
|
||
}
|
||
$enabled = $gateway->get_option( 'enabled', 'no' );
|
||
|
||
if ( 'cod' === $gateway->id ) {
|
||
$status = ! wc_string_to_bool( $enabled ) ? 'enabled' : 'disabled';
|
||
Alert_Manager::trigger_event( 9034, array( 'EventType' => $status ) );
|
||
} else {
|
||
// Gateway enabled.
|
||
Alert_Manager::trigger_event(
|
||
9074,
|
||
array(
|
||
'GatewayID' => sanitize_text_field( $gateway->id ),
|
||
'GatewayName' => sanitize_text_field( $gateway->title ),
|
||
'EventType' => ! wc_string_to_bool( $enabled ) ? 'enabled' : 'disabled',
|
||
)
|
||
);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Verify nonce for shipping zones events.
|
||
if ( isset( $_POST['wc_shipping_zones_nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['wc_shipping_zones_nonce'] ) ), 'wc_shipping_zones_nonce' ) ) {
|
||
|
||
if ( isset( $_POST['changes'] ) && ! empty( $_POST['changes'] ) ) {
|
||
// @codingStandardsIgnoreLine
|
||
$changes = $_POST['changes'];
|
||
foreach ( $changes as $key => $zone ) {
|
||
if ( ! is_integer( $key ) ) {
|
||
continue;
|
||
}
|
||
|
||
if ( isset( $zone['zone_id'], $zone['deleted'] ) && 'deleted' === $zone['deleted'] ) {
|
||
$zone_obj = new \WC_Shipping_Zone( sanitize_text_field( $zone['zone_id'] ) );
|
||
Alert_Manager::trigger_event(
|
||
9082,
|
||
array(
|
||
'ShippingZoneID' => sanitize_text_field( $zone['zone_id'] ),
|
||
'EventType' => 'deleted',
|
||
'ShippingZoneName' => sanitize_text_field( $zone_obj->get_zone_name() ),
|
||
)
|
||
);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Get Stock Status Name.
|
||
*
|
||
* @param string $slug - Stock slug.
|
||
* @return string
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function get_stock_status_name( $slug ) {
|
||
if ( 'instock' === $slug ) {
|
||
return __( 'In stock', 'wp-security-audit-log' );
|
||
} elseif ( 'outofstock' === $slug ) {
|
||
return __( 'Out of stock', 'wp-security-audit-log' );
|
||
} elseif ( 'onbackorder' === $slug ) {
|
||
return __( 'On backorder', 'wp-security-audit-log' );
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Return: Product Categories.
|
||
*
|
||
* @param object $post - Product post object.
|
||
* @return array
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function get_product_categories( $post ) {
|
||
return wp_get_post_terms( $post->ID, 'product_cat', array( 'fields' => 'names' ) );
|
||
}
|
||
|
||
/**
|
||
* Returns Product Data.
|
||
*
|
||
* Returns an array containing only WooCommerce product specific data.
|
||
* This array contains the following data:
|
||
* 1. Product type.
|
||
* 2. Catalog visibility.
|
||
* 3. Featured product.
|
||
* 4. Regular price.
|
||
* 5. Sale price.
|
||
* 6. SKU.
|
||
* 7. Stock status.
|
||
* 8. stock quantity.
|
||
* 9. Virtual.
|
||
* 10. Downloadable.
|
||
* 11. Weight.
|
||
* 12. Length.
|
||
* 13. Width.
|
||
* 14. Height.
|
||
* 15. Backorders.
|
||
* 16. Upsell IDs.
|
||
* 17. Cross sell IDs.
|
||
* 18. File names.
|
||
* 19. File URLs.
|
||
*
|
||
* @param WC_Product $product - Product post object.
|
||
*
|
||
* @return array Product data as array. Empty if the argument is not a valid WooCommerce product.
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function get_product_data( $product ) {
|
||
if ( ! is_a( $product, 'WC_Product' ) ) {
|
||
return array();
|
||
}
|
||
|
||
$product_data = array(
|
||
'type' => $product->get_type(),
|
||
'catalog_visibility' => $product->get_catalog_visibility(),
|
||
'featured' => $product->get_featured(),
|
||
'regular_price' => $product->get_regular_price(),
|
||
'sale_price' => $product->get_sale_price(),
|
||
'sku' => $product->get_sku(),
|
||
'stock_status' => $product->get_stock_status(),
|
||
'stock_quantity' => $product->get_stock_quantity(),
|
||
'virtual' => $product->is_virtual() ? 'yes' : 'no',
|
||
'downloadable' => $product->is_downloadable() ? 'yes' : 'no',
|
||
'weight' => $product->get_weight(),
|
||
'length' => $product->get_length(),
|
||
'width' => $product->get_width(),
|
||
'height' => $product->get_height(),
|
||
'backorders' => $product->get_backorders(),
|
||
'upsell_ids' => $product->get_upsell_ids(),
|
||
'cross_sell_ids' => $product->get_cross_sell_ids(),
|
||
'tax_status' => $product->get_tax_status(),
|
||
'tax_class' => $product->get_tax_class(),
|
||
'low_stock_amount' => $product->get_low_stock_amount(),
|
||
'manage_stock' => $product->get_manage_stock(),
|
||
'file_names' => array(),
|
||
'file_urls' => array(),
|
||
);
|
||
|
||
foreach ( $product->get_downloads() as $download ) {
|
||
array_push( $product_data['file_names'], $download->get_name() );
|
||
array_push( $product_data['file_urls'], $download->get_file() );
|
||
}
|
||
return $product_data;
|
||
}
|
||
|
||
/**
|
||
* Get the config setting
|
||
*
|
||
* @param string $option_name - Option Name.
|
||
* @return string
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function get_config( $option_name ) {
|
||
// If this is multisite AND we have some kind of value, we can return it.
|
||
if ( is_multisite() && ! empty( get_site_option( 'woocommerce_' . $option_name ) ) ) {
|
||
// get_site_option is not empty, so lets return it.
|
||
return get_site_option( 'woocommerce_' . $option_name );
|
||
} else {
|
||
// Otherwise, looking the sites wp_options table, even in multisite.
|
||
return get_option( 'woocommerce_' . $option_name );
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Check post type.
|
||
*
|
||
* @param stdClass $post - Post.
|
||
* @return bool
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function check_woo_commerce( $post ) {
|
||
switch ( $post->post_type ) {
|
||
case 'product':
|
||
return true;
|
||
default:
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Get editor link.
|
||
*
|
||
* @param stdClass $post - The post.
|
||
* @return array $editor_link - Name and value link.
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function get_editor_link( $post ) {
|
||
|
||
$post_type = '';
|
||
|
||
if ( \method_exists( $post, 'get_id' ) ) {
|
||
$post_type = get_post_type( $post->get_id() );
|
||
} else {
|
||
$post_type = get_post_type( $post->ID );
|
||
}
|
||
|
||
// Meta value key.
|
||
if ( is_a( $post, '\Automattic\WooCommerce\Admin\Overrides\Order' ) || 'shop_order' === $post_type ) {
|
||
$name = 'EditorLinkOrder';
|
||
} elseif ( 'shop_coupon' === $post_type ) {
|
||
$name = 'EditorLinkCoupon';
|
||
} else {
|
||
$name = 'EditorLinkProduct';
|
||
}
|
||
|
||
// Get editor post link URL.
|
||
if ( is_a( $post, '\Automattic\WooCommerce\Admin\Overrides\Order' ) ) {
|
||
$value = $post->get_edit_order_url();
|
||
} else {
|
||
$product_id = '';
|
||
if ( \method_exists( $post, 'get_id' ) ) {
|
||
$product_id = $post->get_id();
|
||
} else {
|
||
$product_id = $post->ID;
|
||
}
|
||
$value = get_edit_post_link( $product_id );
|
||
}
|
||
|
||
// If the URL is not empty then set values.
|
||
if ( ! empty( $value ) ) {
|
||
$editor_link = array(
|
||
'name' => $name, // Meta key.
|
||
'value' => $value, // Meta value.
|
||
);
|
||
} else {
|
||
$product_id = '';
|
||
if ( \method_exists( $post, 'get_id' ) ) {
|
||
$product_id = $post->get_id();
|
||
} else {
|
||
$product_id = $post->ID;
|
||
}
|
||
// Get post object.
|
||
$post = get_post( $product_id );
|
||
|
||
// Set URL action.
|
||
if ( 'revision' === $post_type ) {
|
||
$action = '';
|
||
} else {
|
||
$action = '&action=edit';
|
||
}
|
||
|
||
// Get and check post type object.
|
||
$post_type_object = get_post_type_object( $post_type );
|
||
if ( ! $post_type_object ) {
|
||
return;
|
||
}
|
||
|
||
// Set editor link manually.
|
||
if ( $post_type_object->_edit_link ) {
|
||
$link = \network_admin_url( sprintf( $post_type_object->_edit_link . $action, $product_id ) );
|
||
} else {
|
||
$link = '';
|
||
}
|
||
|
||
$editor_link = array(
|
||
'name' => $name, // Meta key.
|
||
'value' => $link, // Meta value.
|
||
);
|
||
}
|
||
|
||
return $editor_link;
|
||
}
|
||
|
||
/**
|
||
* Alerts for editing of product post type for WooCommerce.
|
||
*
|
||
* @param WP_Post $product - Product post type.
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function editing_product( $product ) {
|
||
// Check product post type.
|
||
if ( 'product' !== $product->post_type ) {
|
||
return $product;
|
||
}
|
||
|
||
if ( is_user_logged_in() && is_admin() ) {
|
||
// Filter $_SERVER array for security.
|
||
$server_array = filter_input_array( INPUT_SERVER );
|
||
|
||
$current_path = isset( $server_array['SCRIPT_NAME'] ) ? $server_array['SCRIPT_NAME'] . '?post=' . $product->ID : false;
|
||
if ( ! empty( $server_array['HTTP_REFERER'] )
|
||
&& strpos( $server_array['HTTP_REFERER'], $current_path ) !== false ) {
|
||
// Ignore this if we were on the same page so we avoid double audit entries.
|
||
return $product;
|
||
}
|
||
if ( ! empty( $product->post_title ) ) {
|
||
$event = 9072;
|
||
if ( ! Alert_Manager::was_triggered( $event ) && ! Alert_Manager::was_triggered( 9001 ) || ! Alert_Manager::was_triggered_recently( 9000 ) ) {
|
||
$editor_link = self::get_editor_link( $product );
|
||
Alert_Manager::trigger_event_if(
|
||
$event,
|
||
array(
|
||
'PostID' => esc_attr( $product->ID ),
|
||
'SKU' => esc_attr( self::get_product_sku( $product->ID ) ),
|
||
'ProductStatus' => sanitize_text_field( $product->post_status ),
|
||
'ProductTitle' => sanitize_text_field( $product->post_title ),
|
||
'ProductUrl' => get_permalink( $product->ID ),
|
||
$editor_link['name'] => $editor_link['value'],
|
||
),
|
||
array( __CLASS__, 'must_not_be_fresh_post' )
|
||
);
|
||
}
|
||
}
|
||
}
|
||
return $product;
|
||
}
|
||
|
||
/**
|
||
* Check if is a fresh post.
|
||
*
|
||
* @return bool - Has triggered or not.
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function must_not_be_fresh_post() {
|
||
if ( Alert_Manager::will_or_has_triggered( 9000 ) ) {
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* Get Currency symbol.
|
||
*
|
||
* @param string $currency - Currency (default: '').
|
||
* @return string
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function get_currency_symbol( $currency = '' ) {
|
||
$symbols = array(
|
||
'AED' => 'د.إ',
|
||
'AFN' => '؋',
|
||
'ALL' => 'L',
|
||
'AMD' => 'AMD',
|
||
'ANG' => 'ƒ',
|
||
'AOA' => 'Kz',
|
||
'ARS' => '$',
|
||
'AUD' => '$',
|
||
'AWG' => 'ƒ',
|
||
'AZN' => 'AZN',
|
||
'BAM' => 'KM',
|
||
'BBD' => '$',
|
||
'BDT' => '৳ ',
|
||
'BGN' => 'лв.',
|
||
'BHD' => '.د.ب',
|
||
'BIF' => 'Fr',
|
||
'BMD' => '$',
|
||
'BND' => '$',
|
||
'BOB' => 'Bs.',
|
||
'BRL' => 'R$',
|
||
'BSD' => '$',
|
||
'BTC' => '฿',
|
||
'BTN' => 'Nu.',
|
||
'BWP' => 'P',
|
||
'BYR' => 'Br',
|
||
'BZD' => '$',
|
||
'CAD' => '$',
|
||
'CDF' => 'Fr',
|
||
'CHF' => 'CHF',
|
||
'CLP' => '$',
|
||
'CNY' => '¥',
|
||
'COP' => '$',
|
||
'CRC' => '₡',
|
||
'CUC' => '$',
|
||
'CUP' => '$',
|
||
'CVE' => '$',
|
||
'CZK' => 'Kč',
|
||
'DJF' => 'Fr',
|
||
'DKK' => 'DKK',
|
||
'DOP' => 'RD$',
|
||
'DZD' => 'د.ج',
|
||
'EGP' => 'EGP',
|
||
'ERN' => 'Nfk',
|
||
'ETB' => 'Br',
|
||
'EUR' => '€',
|
||
'FJD' => '$',
|
||
'FKP' => '£',
|
||
'GBP' => '£',
|
||
'GEL' => 'ლ',
|
||
'GGP' => '£',
|
||
'GHS' => '₵',
|
||
'GIP' => '£',
|
||
'GMD' => 'D',
|
||
'GNF' => 'Fr',
|
||
'GTQ' => 'Q',
|
||
'GYD' => '$',
|
||
'HKD' => '$',
|
||
'HNL' => 'L',
|
||
'HRK' => 'Kn',
|
||
'HTG' => 'G',
|
||
'HUF' => 'Ft',
|
||
'IDR' => 'Rp',
|
||
'ILS' => '₪',
|
||
'IMP' => '£',
|
||
'INR' => '₹',
|
||
'IQD' => 'ع.د',
|
||
'IRR' => '﷼',
|
||
'ISK' => 'kr.',
|
||
'JEP' => '£',
|
||
'JMD' => '$',
|
||
'JOD' => 'د.ا',
|
||
'JPY' => '¥',
|
||
'KES' => 'KSh',
|
||
'KGS' => 'сом',
|
||
'KHR' => '៛',
|
||
'KMF' => 'Fr',
|
||
'KPW' => '₩',
|
||
'KRW' => '₩',
|
||
'KWD' => 'د.ك',
|
||
'KYD' => '$',
|
||
'KZT' => 'KZT',
|
||
'LAK' => '₭',
|
||
'LBP' => 'ل.ل',
|
||
'LKR' => 'රු',
|
||
'LRD' => '$',
|
||
'LSL' => 'L',
|
||
'LYD' => 'ل.د',
|
||
'MAD' => 'د.م.',
|
||
'MDL' => 'L',
|
||
'MGA' => 'Ar',
|
||
'MKD' => 'ден',
|
||
'MMK' => 'Ks',
|
||
'MNT' => '₮',
|
||
'MOP' => 'P',
|
||
'MRO' => 'UM',
|
||
'MUR' => '₨',
|
||
'MVR' => '.ރ',
|
||
'MWK' => 'MK',
|
||
'MXN' => '$',
|
||
'MYR' => 'RM',
|
||
'MZN' => 'MT',
|
||
'NAD' => '$',
|
||
'NGN' => '₦',
|
||
'NIO' => 'C$',
|
||
'NOK' => 'kr',
|
||
'NPR' => '₨',
|
||
'NZD' => '$',
|
||
'OMR' => 'ر.ع.',
|
||
'PAB' => 'B/.',
|
||
'PEN' => 'S/.',
|
||
'PGK' => 'K',
|
||
'PHP' => '₱',
|
||
'PKR' => '₨',
|
||
'PLN' => 'zł',
|
||
'PRB' => 'р.',
|
||
'PYG' => '₲',
|
||
'QAR' => 'ر.ق',
|
||
'RMB' => '¥',
|
||
'RON' => 'lei',
|
||
'RSD' => 'дин.',
|
||
'RUB' => '₽',
|
||
'RWF' => 'Fr',
|
||
'SAR' => 'ر.س',
|
||
'SBD' => '$',
|
||
'SCR' => '₨',
|
||
'SDG' => 'ج.س.',
|
||
'SEK' => 'kr',
|
||
'SGD' => '$',
|
||
'SHP' => '£',
|
||
'SLL' => 'Le',
|
||
'SOS' => 'Sh',
|
||
'SRD' => '$',
|
||
'SSP' => '£',
|
||
'STD' => 'Db',
|
||
'SYP' => 'ل.س',
|
||
'SZL' => 'L',
|
||
'THB' => '฿',
|
||
'TJS' => 'ЅМ',
|
||
'TMT' => 'm',
|
||
'TND' => 'د.ت',
|
||
'TOP' => 'T$',
|
||
'TRY' => '₺',
|
||
'TTD' => '$',
|
||
'TWD' => 'NT$',
|
||
'TZS' => 'Sh',
|
||
'UAH' => '₴',
|
||
'UGX' => 'UGX',
|
||
'USD' => '$',
|
||
'UYU' => '$',
|
||
'UZS' => 'UZS',
|
||
'VEF' => 'Bs F',
|
||
'VND' => '₫',
|
||
'VUV' => 'Vt',
|
||
'WST' => 'T',
|
||
'XAF' => 'Fr',
|
||
'XCD' => '$',
|
||
'XOF' => 'Fr',
|
||
'XPF' => 'Fr',
|
||
'YER' => '﷼',
|
||
'ZAR' => 'R',
|
||
'ZMW' => 'ZK',
|
||
);
|
||
$currency_symbol = isset( $symbols[ $currency ] ) ? $symbols[ $currency ] : '';
|
||
|
||
return $currency_symbol;
|
||
}
|
||
|
||
/**
|
||
* WooCommerce Order Status Changed Event.
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @param integer $order_id – Order ID.
|
||
* @param string $status_from – Status changing from.
|
||
* @param string $status_to – Status changing to.
|
||
* @param WC_Order $order – WooCommerce order object.
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function event_order_status_changed( $order_id, $status_from, $status_to, $order ) {
|
||
$order_post = wc_get_order( $order_id ); // Get order post object.
|
||
$edit_link = self::get_editor_link( $order_post );
|
||
$event_data = array(
|
||
'OrderID' => esc_attr( $order_id ),
|
||
'OrderTitle' => sanitize_text_field( Woocommerce_Helper::wsal_woocommerce_extension_get_order_title( $order ) ),
|
||
'OrderStatus' => sanitize_text_field( $status_to ),
|
||
$edit_link['name'] => $edit_link['value'],
|
||
);
|
||
Alert_Manager::trigger_event_if( 9036, $event_data, array( __CLASS__, 'must_not_contain_refund' ) );
|
||
}
|
||
|
||
/**
|
||
* Report additional products being added to an order.
|
||
*
|
||
* @param int $item_id - Item ID.
|
||
* @param object $item - Item data.
|
||
* @param int $order_id - Order ID.
|
||
* @return void
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function event_order_items_added( $item_id, $item, $order_id ) {
|
||
|
||
if ( empty( $order_id ) ) {
|
||
$order_id = (int) wc_get_order_id_by_order_item_id( $item_id );
|
||
if ( ! isset( $order_id ) || intval( $order_id ) <= 0 ) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
if ( $item instanceof \WC_Order_Item_Product ) {
|
||
$product = $item->get_product();
|
||
if ( $product instanceof \WC_Product ) {
|
||
$order = wc_get_order( $order_id );
|
||
$order_post = wc_get_order( $order_id );
|
||
$edit_link = self::get_editor_link( $order_post );
|
||
$event_data = array(
|
||
'OrderID' => esc_attr( $order_id ),
|
||
'OrderTitle' => Woocommerce_Helper::wsal_woocommerce_extension_get_order_title( $order ),
|
||
'ProductTitle' => $product->get_name(),
|
||
'ProductID' => $product->get_id(),
|
||
'SKU' => self::get_product_sku( $product->get_id() ),
|
||
'OrderStatus' => $order_post->get_status(),
|
||
'EventType' => 'added',
|
||
$edit_link['name'] => $edit_link['value'],
|
||
);
|
||
Alert_Manager::trigger_event_if( 9130, $event_data, array( __CLASS__, 'ignore_if_new_order' ) );
|
||
}
|
||
}
|
||
|
||
if ( $item instanceof \WC_Order_Item_Fee ) {
|
||
$order = wc_get_order( $order_id );
|
||
if ( $order ) {
|
||
$order_post = wc_get_order( $order_id );
|
||
$edit_link = self::get_editor_link( $order_post );
|
||
$event_data = array(
|
||
'OrderID' => esc_attr( $order_id ),
|
||
'OrderTitle' => Woocommerce_Helper::wsal_woocommerce_extension_get_order_title( $order ),
|
||
'FeeAmount' => $item->get_amount(),
|
||
'OrderStatus' => $order_post->get_status(),
|
||
'EventType' => 'added',
|
||
$edit_link['name'] => $edit_link['value'],
|
||
);
|
||
Alert_Manager::trigger_event_if( 9132, $event_data, array( __CLASS__, 'ignore_if_new_order' ) );
|
||
}
|
||
}
|
||
|
||
if ( $item instanceof \WC_Order_Item_Coupon ) {
|
||
$order = wc_get_order( $order_id );
|
||
if ( $order ) {
|
||
$order_post = wc_get_order( $order_id );
|
||
$edit_link = self::get_editor_link( $order_post );
|
||
$event_data = array(
|
||
'OrderID' => esc_attr( $order_id ),
|
||
'OrderTitle' => Woocommerce_Helper::wsal_woocommerce_extension_get_order_title( $order ),
|
||
'CouponName' => $item->get_name(),
|
||
'CouponValue' => $item->get_discount(),
|
||
'OrderStatus' => $order_post->get_status(),
|
||
'EventType' => 'added',
|
||
$edit_link['name'] => $edit_link['value'],
|
||
);
|
||
Alert_Manager::trigger_event_if( 9134, $event_data, array( __CLASS__, 'ignore_if_new_order' ) );
|
||
}
|
||
}
|
||
|
||
if ( $item instanceof \WC_Order_Item_Tax ) {
|
||
$order = wc_get_order( $order_id );
|
||
if ( $order ) {
|
||
$order_post = wc_get_order( $order_id );
|
||
$edit_link = self::get_editor_link( $order_post );
|
||
$event_data = array(
|
||
'OrderID' => esc_attr( $order_id ),
|
||
'OrderTitle' => Woocommerce_Helper::wsal_woocommerce_extension_get_order_title( $order ),
|
||
'TaxName' => $item->get_name(),
|
||
'OrderStatus' => $order_post->get_status(),
|
||
'EventType' => 'added',
|
||
$edit_link['name'] => $edit_link['value'],
|
||
);
|
||
Alert_Manager::trigger_event_if( 9135, $event_data, array( __CLASS__, 'ignore_if_new_order' ) );
|
||
}
|
||
}
|
||
|
||
if ( $item instanceof \WC_Order_Item_Shipping ) {
|
||
$order = wc_get_order( $order_id );
|
||
if ( $order ) {
|
||
$order_post = wc_get_order( $order_id );
|
||
$edit_link = self::get_editor_link( $order_post );
|
||
$event_data = array(
|
||
'OrderID' => esc_attr( $order_id ),
|
||
'OrderTitle' => Woocommerce_Helper::wsal_woocommerce_extension_get_order_title( $order ),
|
||
'OrderStatus' => $order_post->get_status(),
|
||
'EventType' => 'added',
|
||
$edit_link['name'] => $edit_link['value'],
|
||
);
|
||
Alert_Manager::trigger_event_if( 9137, $event_data, array( __CLASS__, 'ignore_if_new_order' ) );
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Report additional products being removed from an an order.
|
||
*
|
||
* @param int $item_id - Item ID.
|
||
* @return void
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function event_order_items_removed( $item_id ) {
|
||
$order_id = wc_get_order_id_by_order_item_id( $item_id );
|
||
$order = wc_get_order( $order_id );
|
||
|
||
if ( isset( $order->get_items()[ $item_id ] ) ) {
|
||
$item = $order->get_items()[ $item_id ];
|
||
$product = $item->get_product();
|
||
|
||
$order_post = wc_get_order( $order_id );
|
||
$edit_link = self::get_editor_link( $order_post );
|
||
$event_data = array(
|
||
'OrderID' => esc_attr( $order_id ),
|
||
'OrderTitle' => Woocommerce_Helper::wsal_woocommerce_extension_get_order_title( $order ),
|
||
'ProductTitle' => $product->get_name(),
|
||
'ProductID' => $product->get_id(),
|
||
'SKU' => self::get_product_sku( $product->get_id() ),
|
||
'OrderStatus' => $order_post->get_status(),
|
||
'EventType' => 'removed',
|
||
$edit_link['name'] => $edit_link['value'],
|
||
);
|
||
Alert_Manager::trigger_event( 9130, $event_data );
|
||
}
|
||
|
||
if ( isset( $order->get_fees()[ $item_id ] ) ) {
|
||
$item = $order->get_fees()[ $item_id ];
|
||
|
||
$order_post = wc_get_order( $order_id );
|
||
$edit_link = self::get_editor_link( $order_post );
|
||
$event_data = array(
|
||
'OrderID' => esc_attr( $order_id ),
|
||
'OrderTitle' => Woocommerce_Helper::wsal_woocommerce_extension_get_order_title( $order ),
|
||
'FeeAmount' => $item->get_amount(),
|
||
'OrderStatus' => $order_post->get_status(),
|
||
'EventType' => 'removed',
|
||
$edit_link['name'] => $edit_link['value'],
|
||
);
|
||
Alert_Manager::trigger_event( 9132, $event_data );
|
||
}
|
||
|
||
if ( isset( $order->get_coupons()[ $item_id ] ) ) {
|
||
$item = $order->get_coupons()[ $item_id ];
|
||
|
||
$order_post = wc_get_order( $order_id );
|
||
$edit_link = self::get_editor_link( $order_post );
|
||
$event_data = array(
|
||
'OrderID' => esc_attr( $order_id ),
|
||
'OrderTitle' => Woocommerce_Helper::wsal_woocommerce_extension_get_order_title( $order ),
|
||
'CouponName' => $item->get_name(),
|
||
'CouponValue' => $item->get_discount(),
|
||
'OrderStatus' => $order_post->get_status(),
|
||
'EventType' => 'removed',
|
||
$edit_link['name'] => $edit_link['value'],
|
||
);
|
||
Alert_Manager::trigger_event( 9134, $event_data );
|
||
}
|
||
|
||
if ( isset( $order->get_taxes()[ $item_id ] ) ) {
|
||
$item = $order->get_taxes()[ $item_id ];
|
||
|
||
$order_post = wc_get_order( $order_id );
|
||
$edit_link = self::get_editor_link( $order_post );
|
||
$event_data = array(
|
||
'OrderID' => esc_attr( $order_id ),
|
||
'OrderTitle' => Woocommerce_Helper::wsal_woocommerce_extension_get_order_title( $order ),
|
||
'TaxName' => $item->get_name(),
|
||
'OrderStatus' => $order_post->get_status(),
|
||
'EventType' => 'removed',
|
||
$edit_link['name'] => $edit_link['value'],
|
||
);
|
||
Alert_Manager::trigger_event( 9135, $event_data );
|
||
}
|
||
|
||
if ( isset( $order->get_shipping_methods()[ $item_id ] ) ) {
|
||
$item = $order->get_shipping_method()[ $item_id ];
|
||
|
||
$order_post = wc_get_order( $order_id );
|
||
$edit_link = self::get_editor_link( $order_post );
|
||
$event_data = array(
|
||
'OrderID' => esc_attr( $order_id ),
|
||
'OrderTitle' => Woocommerce_Helper::wsal_woocommerce_extension_get_order_title( $order ),
|
||
'OrderStatus' => $order_post->get_status(),
|
||
'EventType' => 'removed',
|
||
$edit_link['name'] => $edit_link['value'],
|
||
);
|
||
Alert_Manager::trigger_event( 9137, $event_data );
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Detect changes within a WC order.
|
||
*
|
||
* @param int $order_id - Order ID being changed.
|
||
* @param array $items - Items being changed.
|
||
* @return void
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function event_order_items_quantity_changed( $order_id, $items ) {
|
||
$order = wc_get_order( $order_id );
|
||
|
||
$output = array();
|
||
|
||
if ( isset( $_POST['items'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||
if ( is_array( $_POST['items'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||
$data = array_map( 'sanitize_text_field', wp_unslash( $_POST['items'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||
foreach ( $data as $key => $value ) {
|
||
$items['order_item_id'][] = $key;
|
||
$output['order_item_qty' . $key ] = $value;
|
||
}
|
||
} else {
|
||
parse_str( sanitize_text_field( wp_unslash( $_POST['items'] ) ), $output ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||
}
|
||
} else {
|
||
$output = wp_unslash( $_POST ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||
}
|
||
|
||
if ( ! isset( $items['order_item_id'] ) ) {
|
||
return;
|
||
}
|
||
|
||
foreach ( $items['order_item_id'] as $item_id ) {
|
||
if ( isset( $order->get_items()[ $item_id ] ) ) {
|
||
$item = $order->get_items()[ $item_id ];
|
||
if ( $item instanceof \WC_Order_Item_Product ) {
|
||
$product = $item->get_product();
|
||
$old_quantity = $item->get_quantity();
|
||
$order = wc_get_order( $order_id );
|
||
$order_post = wc_get_order( $order_id );
|
||
$edit_link = self::get_editor_link( $order_post );
|
||
if ( isset( $output['order_item_qty' . $item_id ] ) && intval( $output['order_item_qty' . $item_id ] ) !== intval( $old_quantity ) ) {
|
||
$event_data = array(
|
||
'OrderID' => esc_attr( $order_id ),
|
||
'OrderTitle' => Woocommerce_Helper::wsal_woocommerce_extension_get_order_title( $order ),
|
||
'ProductID' => $product->get_id(),
|
||
'SKU' => self::get_product_sku( $product->get_id() ),
|
||
'NewQuantity' => $output['order_item_qty' . $item_id ],
|
||
'OldQuantity' => $old_quantity,
|
||
'ProductTitle' => $product->get_name(),
|
||
'OrderStatus' => $order_post->get_status(),
|
||
$edit_link['name'] => $edit_link['value'],
|
||
);
|
||
Alert_Manager::trigger_event( 9131, $event_data );
|
||
}
|
||
}
|
||
}
|
||
if ( isset( $order->get_fees()[ $item_id ] ) ) {
|
||
$item = $order->get_fees()[ $item_id ];
|
||
if ( $item instanceof \WC_Order_Item_Fee ) {
|
||
$order = wc_get_order( $order_id );
|
||
$order_post = wc_get_order( $order_id );
|
||
$edit_link = self::get_editor_link( $order_post );
|
||
if ( intval( $output['line_total'][ $item_id ] ) !== intval( $item->get_amount() ) ) {
|
||
$event_data = array(
|
||
'OrderID' => esc_attr( $order_id ),
|
||
'OrderTitle' => Woocommerce_Helper::wsal_woocommerce_extension_get_order_title( $order ),
|
||
'FeeAmount' => $output['line_total'][ $item_id ],
|
||
'OldFeeAmount' => $item->get_amount(),
|
||
'OrderStatus' => $order_post->get_status(),
|
||
$edit_link['name'] => $edit_link['value'],
|
||
);
|
||
Alert_Manager::trigger_event( 9133, $event_data );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Checks if event 9041 has triggered or if it will
|
||
* trigger.
|
||
*
|
||
* @since 3.3.1.1
|
||
*
|
||
* @return boolean
|
||
*/
|
||
public static function must_not_contain_refund() {
|
||
if ( Alert_Manager::will_or_has_triggered( 9041 ) ) {
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* Checks if event 9035 has triggered or if it will
|
||
* trigger.
|
||
*
|
||
* @since 1.3.0
|
||
*
|
||
* @return boolean
|
||
*/
|
||
public static function ignore_if_new_order() {
|
||
if ( Alert_Manager::will_or_has_triggered( 9035 ) ) {
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* Checks if event 9041 or 9036 has triggered or if it will
|
||
* trigger.
|
||
*
|
||
* @since 4.1.3
|
||
*
|
||
* @return boolean
|
||
*/
|
||
public static function must_not_contain_refund_or_modification() {
|
||
if ( Alert_Manager::will_or_has_triggered( 9041 ) ) {
|
||
return false;
|
||
}
|
||
if ( Alert_Manager::will_or_has_triggered( 9036 ) ) {
|
||
return false;
|
||
}
|
||
if ( Alert_Manager::will_or_has_triggered( 9038 ) ) {
|
||
return false;
|
||
}
|
||
if ( Alert_Manager::will_or_has_triggered( 9120 ) ) {
|
||
return false;
|
||
}
|
||
if ( Alert_Manager::will_or_has_triggered( 9120 ) ) {
|
||
return false;
|
||
}
|
||
if ( Alert_Manager::will_or_has_triggered( 9130 ) || Alert_Manager::was_triggered_recently( 9130 ) ) {
|
||
return false;
|
||
}
|
||
if ( Alert_Manager::will_or_has_triggered( 9131 ) || Alert_Manager::was_triggered_recently( 9131 ) ) {
|
||
return false;
|
||
}
|
||
if ( Alert_Manager::will_or_has_triggered( 9132 ) || Alert_Manager::was_triggered_recently( 9132 ) ) {
|
||
return false;
|
||
}
|
||
if ( Alert_Manager::will_or_has_triggered( 9133 ) || Alert_Manager::was_triggered_recently( 9133 ) ) {
|
||
return false;
|
||
}
|
||
if ( Alert_Manager::will_or_has_triggered( 9134 ) || Alert_Manager::was_triggered_recently( 9134 ) ) {
|
||
return false;
|
||
}
|
||
if ( Alert_Manager::will_or_has_triggered( 9137 ) || Alert_Manager::was_triggered_recently( 9137 ) ) {
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* WooCommerce Order Modified.
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @param integer $order_id – Order id.
|
||
* @param WP_Post $oldorder – Old order WP_Post object.
|
||
* @param WP_Post $neworder – New order WP_Post object.
|
||
*/
|
||
private static function check_order_modify_change( $order_id, $oldorder, $neworder ) {
|
||
if ( 'trash' === $neworder->post_status ) {
|
||
return 0;
|
||
}
|
||
|
||
// Dont fire if we know an item was added/removed recently.
|
||
if ( Alert_Manager::was_triggered_recently( 9120 ) || Alert_Manager::was_triggered_recently( 9130 ) || Alert_Manager::was_triggered_recently( 9131 ) || Alert_Manager::was_triggered_recently( 9132 ) | Alert_Manager::was_triggered_recently( 9133 ) || Alert_Manager::was_triggered_recently( 9134 ) || Alert_Manager::was_triggered_recently( 9135 ) || Alert_Manager::was_triggered_recently( 9137 ) ) {
|
||
return;
|
||
}
|
||
|
||
$order = wc_get_order( $order_id );
|
||
$items = $order->get_items( array( 'fee' ) );
|
||
|
||
self::event_order_items_quantity_changed( $order_id, $items );
|
||
|
||
$difference = self::order_recursive_array_diff( (array) self::$_old_order, (array) $order );
|
||
|
||
if ( ! empty( $difference ) ) {
|
||
// Get editor link.
|
||
$edit_link = self::get_editor_link( $oldorder );
|
||
|
||
// Set event data.
|
||
$event_data = array(
|
||
'OrderID' => esc_attr( $order_id ),
|
||
'OrderTitle' => sanitize_text_field( Woocommerce_Helper::wsal_woocommerce_extension_get_order_title( $order_id ) ),
|
||
'OrderStatus' => sanitize_text_field( $neworder->post_status ),
|
||
$edit_link['name'] => $edit_link['value'],
|
||
);
|
||
|
||
// Log event.
|
||
Alert_Manager::trigger_event_if( 9040, $event_data, array( __CLASS__, 'must_not_contain_refund_or_modification' ) );
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Little helper to recursively compare arrays, which is this case is WC order details.
|
||
*
|
||
* @param array $old_details - Array of old details.
|
||
* @param array $new_details - Array of new details.
|
||
*
|
||
* @return array
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function order_recursive_array_diff( $old_details, $new_details ) {
|
||
$r = array();
|
||
$ignored_keys = array(
|
||
'date_modified',
|
||
);
|
||
foreach ( $old_details as $k => $v ) {
|
||
if ( in_array( $k, $ignored_keys, true ) ) {
|
||
continue;
|
||
}
|
||
if ( array_key_exists( $k, $new_details ) ) {
|
||
if ( is_array( $v ) ) {
|
||
$rad = self::order_recursive_array_diff( $v, $new_details[ $k ] );
|
||
if ( count( $rad ) ) {
|
||
$r[ $k ] = $rad;
|
||
}
|
||
} elseif ( $v !== $new_details[ $k ] ) {
|
||
$r[ $k ] = $v;
|
||
}
|
||
} else {
|
||
$r[ $k ] = $v;
|
||
}
|
||
}
|
||
return $r;
|
||
}
|
||
|
||
/**
|
||
* WooCommerce Bulk Order Modified.
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @param array $order_ids – Bulk Order ids.
|
||
* @param string $action – Bulk action to perform.
|
||
* @return array
|
||
*/
|
||
public static function event_bulk_order_actions( $order_ids, $action ) {
|
||
// Check for remove personal data action.
|
||
if ( 'remove_personal_data' === $action ) {
|
||
foreach ( $order_ids as $order_id ) {
|
||
$order_post = wc_get_order( $order_id );
|
||
|
||
// Get editor link.
|
||
$edit_link = self::get_editor_link( $order_post );
|
||
|
||
// Log event.
|
||
Alert_Manager::trigger_event_if(
|
||
9040,
|
||
array(
|
||
'OrderID' => esc_attr( $order_id ),
|
||
'OrderTitle' => sanitize_text_field( Woocommerce_Helper::wsal_woocommerce_extension_get_order_title( $order_id ) ),
|
||
'OrderStatus' => sanitize_text_field( $order_post->get_status() ),
|
||
$edit_link['name'] => $edit_link['value'],
|
||
),
|
||
array( __CLASS__, 'must_not_contain_refund_or_modification' )
|
||
);
|
||
}
|
||
}
|
||
return $order_ids;
|
||
}
|
||
|
||
/**
|
||
* WooCommerce Order Refunded.
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @param integer $order_id – Order ID.
|
||
* @param integer $refund_id – Refund ID.
|
||
*/
|
||
public static function event_order_refunded( $order_id, $refund_id ) {
|
||
// Get order post object.
|
||
$order_obj = wc_get_order( $order_id );
|
||
$edit_link = self::get_editor_link( $order_obj );
|
||
$order = wc_get_order( $order_id );
|
||
$customer_user_id = $order->get_user_id();
|
||
$username = esc_html__( 'Guest', 'wp-security-audit-log' );
|
||
|
||
if ( 0 !== $customer_user_id ) {
|
||
$user = get_user_by( 'id', $customer_user_id );
|
||
$username = $user->user_login;
|
||
}
|
||
|
||
$date = $order->get_date_created();
|
||
$date_format = get_option( 'date_format' );
|
||
$time_format = get_option( 'time_format' );
|
||
$created_date = $date->date( $date_format . ' ' . $time_format );
|
||
$refund_amount = '';
|
||
$refund_reason = '';
|
||
$currency = get_woocommerce_currency_symbol( $order->get_currency() );
|
||
$refunds = $order->get_refunds();
|
||
|
||
foreach ( $refunds as $refund_object ) {
|
||
$id = $refund_object->get_id();
|
||
if ( $id === $refund_id ) {
|
||
$amount = $refund_object->get_amount();
|
||
$refund_amount = ( $amount ) ? $amount : '0.00';
|
||
$reason = $refund_object->get_reason();
|
||
$refund_reason = ( $reason ) ? $reason : esc_html__( 'None supplied', 'wp-security-audit-log' );
|
||
}
|
||
}
|
||
|
||
Alert_Manager::trigger_event(
|
||
9041,
|
||
array(
|
||
'OrderID' => esc_attr( $order_id ),
|
||
'RefundID' => esc_attr( $refund_id ),
|
||
'CustomerUser' => $username,
|
||
'RefundedAmount' => $currency . $refund_amount,
|
||
'Reason' => $refund_reason,
|
||
'OrderDate' => $created_date,
|
||
'OrderTitle' => sanitize_text_field( Woocommerce_Helper::wsal_woocommerce_extension_get_order_title( $order_id ) ),
|
||
'OrderStatus' => sanitize_text_field( $order_obj->get_status() ),
|
||
$edit_link['name'] => $edit_link['value'],
|
||
)
|
||
);
|
||
}
|
||
|
||
/**
|
||
* WooCommerce Order Refunded.
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @param integer $refund_id – Refund ID.
|
||
* @param integer $order_id – Order ID.
|
||
*/
|
||
public static function event_order_refund_removed( $refund_id, $order_id ) {
|
||
// Get order post object.
|
||
$order_obj = wc_get_order( $order_id );
|
||
$edit_link = self::get_editor_link( $order_obj );
|
||
$order = wc_get_order( $order_id );
|
||
$customer_user_id = $order->get_user_id();
|
||
$username = esc_html__( 'Guest', 'wp-security-audit-log' );
|
||
|
||
if ( 0 !== $customer_user_id ) {
|
||
$user = get_user_by( 'id', $customer_user_id );
|
||
$username = $user->user_login;
|
||
}
|
||
|
||
$date = $order->get_date_created();
|
||
$date_format = get_option( 'date_format' );
|
||
$time_format = get_option( 'time_format' );
|
||
$created_date = $date->date( $date_format . ' ' . $time_format );
|
||
|
||
Alert_Manager::trigger_event(
|
||
9136,
|
||
array(
|
||
'OrderID' => esc_attr( $order_id ),
|
||
'RefundID' => esc_attr( $refund_id ),
|
||
'CustomerUser' => $username,
|
||
'OrderDate' => $created_date,
|
||
'OrderTitle' => sanitize_text_field( Woocommerce_Helper::wsal_woocommerce_extension_get_order_title( $order_id ) ),
|
||
'OrderStatus' => sanitize_text_field( $order_obj->post_status ),
|
||
$edit_link['name'] => $edit_link['value'],
|
||
)
|
||
);
|
||
}
|
||
|
||
/**
|
||
* WooCommerce New Attribute Event.
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @param int $attr_id - Attribute ID.
|
||
* @param array $attr_data - Attribute data array.
|
||
*/
|
||
public static function event_attribute_added( $attr_id, $attr_data ) {
|
||
if ( $attr_id && is_array( $attr_data ) ) {
|
||
Alert_Manager::trigger_event( 9057, self::get_attribute_event_data( $attr_id, $attr_data ) );
|
||
}
|
||
}
|
||
|
||
/**
|
||
* WooCommerce Attribute Deleted Event.
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @param int $id - Attribute ID.
|
||
* @param string $name - Attribute name.
|
||
* @param string $taxonomy - Attribute taxonomy name.
|
||
*/
|
||
public static function event_attribute_deleted( $id, $name, $taxonomy ) {
|
||
// Get the attribute.
|
||
$attribute = wc_get_attribute( $id );
|
||
|
||
// Check id and attribute object.
|
||
if ( $id && ! is_null( $attribute ) ) {
|
||
Alert_Manager::trigger_event(
|
||
9058,
|
||
array(
|
||
'AttributeID' => esc_attr( $id ),
|
||
'AttributeName' => isset( $attribute->name ) ? sanitize_text_field( $attribute->name ) : false,
|
||
'AttributeSlug' => isset( $attribute->slug ) ? sanitize_text_field( str_replace( 'pa_', '', $attribute->slug ) ) : false,
|
||
'AttributeType' => isset( $attribute->type ) ? sanitize_text_field( $attribute->type ) : false,
|
||
'AttributeOrderby' => isset( $attribute->order_by ) ? sanitize_text_field( $attribute->order_by ) : false,
|
||
'AttributePublic' => isset( $attribute->has_archives ) ? sanitize_text_field( $attribute->has_archives ) : '0',
|
||
'Taxonomy' => sanitize_text_field( $taxonomy ),
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Retrieve Attribute Data before editing.
|
||
*
|
||
* @since 3.3.1
|
||
*/
|
||
private static function retrieve_attribute_data() {
|
||
// @codingStandardsIgnoreStart
|
||
$save_attribute = isset( $_POST['save_attribute'] ) ? true : false;
|
||
$post_type = isset( $_GET['post_type'] ) ? sanitize_text_field( wp_unslash( $_GET['post_type'] ) ) : false;
|
||
$page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : false;
|
||
$attribute_id = isset( $_GET['edit'] ) ? absint( sanitize_text_field( wp_unslash( $_GET['edit'] ) ) ) : false;
|
||
// @codingStandardsIgnoreEnd
|
||
|
||
if ( $save_attribute && ! empty( $post_type ) && ! empty( $page ) && ! empty( $attribute_id ) && 'product' === $post_type && 'product_attributes' === $page ) {
|
||
// Verify nonce.
|
||
check_admin_referer( 'woocommerce-save-attribute_' . $attribute_id );
|
||
|
||
// Get attribute data.
|
||
self::$old_attr_data = wc_get_attribute( $attribute_id );
|
||
}
|
||
}
|
||
|
||
/**
|
||
* WooCommerce Attribute Updated Events.
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @param int $id - Added attribute ID.
|
||
* @param array $data - Attribute data.
|
||
* @param string $old_slug - Attribute old name.
|
||
*/
|
||
public static function event_attribute_updated( $id, $data, $old_slug ) {
|
||
// Check the attribute slug.
|
||
if ( isset( $data['attribute_name'] ) && $data['attribute_name'] !== $old_slug ) {
|
||
$attr_event = self::get_attribute_event_data( $id, $data );
|
||
$attr_event['OldSlug'] = $old_slug;
|
||
$attr_event['NewSlug'] = $data['attribute_name'];
|
||
Alert_Manager::trigger_event( 9059, $attr_event );
|
||
}
|
||
|
||
// Check the attribute name.
|
||
if ( isset( $data['attribute_label'] ) && isset( self::$old_attr_data->name ) && $data['attribute_label'] !== self::$old_attr_data->name ) {
|
||
$attr_event = self::get_attribute_event_data( $id, $data );
|
||
$attr_event['OldName'] = self::$old_attr_data->name;
|
||
$attr_event['NewName'] = $data['attribute_label'];
|
||
Alert_Manager::trigger_event( 9060, $attr_event );
|
||
}
|
||
|
||
// Check the attribute orderby.
|
||
if ( isset( $data['attribute_orderby'] ) && isset( self::$old_attr_data->order_by ) && $data['attribute_orderby'] !== self::$old_attr_data->order_by ) {
|
||
$attr_event = self::get_attribute_event_data( $id, $data );
|
||
$attr_event['OldSortOrder'] = self::$old_attr_data->order_by;
|
||
$attr_event['NewSortOrder'] = $data['attribute_orderby'];
|
||
Alert_Manager::trigger_event( 9061, $attr_event );
|
||
}
|
||
|
||
// Check the attribute archives.
|
||
if ( isset( $data['attribute_public'] ) && isset( self::$old_attr_data->has_archives ) && (int) self::$old_attr_data->has_archives !== $data['attribute_public'] ) {
|
||
$attr_event = self::get_attribute_event_data( $id, $data );
|
||
$attr_event['EventType'] = 1 === $data['attribute_public'] ? 'enabled' : 'disabled';
|
||
$attr_event['Slug'] = $old_slug;
|
||
Alert_Manager::trigger_event( 9062, $attr_event );
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Return Attribute Events Data.
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @param int $attr_id - Added attribute ID.
|
||
* @param array $data - Attribute data.
|
||
* @return array
|
||
*/
|
||
private static function get_attribute_event_data( $attr_id, $data ) {
|
||
return array(
|
||
'AttributeID' => $attr_id,
|
||
'AttributeName' => isset( $data['attribute_label'] ) ? sanitize_text_field( $data['attribute_label'] ) : false,
|
||
'AttributeSlug' => isset( $data['attribute_name'] ) ? sanitize_text_field( $data['attribute_name'] ) : false,
|
||
'AttributeType' => isset( $data['attribute_type'] ) ? sanitize_text_field( $data['attribute_type'] ) : false,
|
||
'AttributeOrderby' => isset( $data['attribute_orderby'] ) ? sanitize_text_field( $data['attribute_orderby'] ) : false,
|
||
'AttributePublic' => isset( $data['attribute_public'] ) ? sanitize_text_field( $data['attribute_public'] ) : '0',
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Check AJAX changes for WooCommerce.
|
||
*
|
||
* @since 3.3.1
|
||
*/
|
||
public static function check_wc_ajax_change_events() {
|
||
// @codingStandardsIgnoreStart
|
||
$action = isset( $_POST['action'] ) ? sanitize_text_field( wp_unslash( $_POST['action'] ) ) : false;
|
||
$is_data = isset( $_POST['data'] ) ? true : false;
|
||
// @codingStandardsIgnoreEnd
|
||
|
||
// WooCommerce order actions.
|
||
$wc_order_actions = array(
|
||
'woocommerce_add_order_item',
|
||
'woocommerce_save_order_items',
|
||
'woocommerce_remove_order_item',
|
||
'woocommerce_add_coupon_discount',
|
||
'woocommerce_remove_order_coupon',
|
||
);
|
||
|
||
// Check for save attributes action.
|
||
if ( $is_data && 'woocommerce_save_attributes' === $action ) {
|
||
// Check nonce.
|
||
check_ajax_referer( 'save-attributes', 'security' );
|
||
|
||
$post_id = isset( $_POST['post_id'] ) ? sanitize_text_field( wp_unslash( $_POST['post_id'] ) ) : false;
|
||
if ( ! $post_id ) {
|
||
return;
|
||
}
|
||
|
||
$post = \wc_get_product( $post_id );
|
||
if ( ! $post ) {
|
||
return;
|
||
}
|
||
|
||
// Get the attributes data.
|
||
// @codingStandardsIgnoreLine
|
||
parse_str( $_POST['data'], $data );
|
||
self::check_attributes_change( $post, $data );
|
||
} elseif ( 'woocommerce_save_variations' === $action ) {
|
||
// Check nonce.
|
||
check_ajax_referer( 'save-variations', 'security' );
|
||
|
||
$product_id = isset( $_POST['product_id'] ) ? sanitize_text_field( wp_unslash( $_POST['product_id'] ) ) : false;
|
||
if ( ! $product_id ) {
|
||
return;
|
||
}
|
||
|
||
$post = \wc_get_product( $product_id );
|
||
if ( ! $post ) {
|
||
return;
|
||
}
|
||
// Grab posted data so we have something to process.
|
||
$data = wp_unslash( $_POST );
|
||
|
||
self::check_variations_change( $post, $data );
|
||
} elseif ( in_array( $action, $wc_order_actions, true ) ) {
|
||
// Check nonce.
|
||
check_ajax_referer( 'order-item', 'security' );
|
||
|
||
// Get order ID.
|
||
$order_id = isset( $_POST['order_id'] ) ? absint( sanitize_text_field( wp_unslash( $_POST['order_id'] ) ) ) : false;
|
||
if ( ! $order_id ) {
|
||
return;
|
||
}
|
||
|
||
// Get order post.
|
||
$order = wc_get_order( $order_id );
|
||
|
||
// Get editor link.
|
||
$edit_link = self::get_editor_link( $order );
|
||
|
||
// Log event.
|
||
Alert_Manager::trigger_event_if(
|
||
9040,
|
||
array(
|
||
'OrderID' => esc_attr( $order_id ),
|
||
'OrderTitle' => sanitize_text_field( Woocommerce_Helper::wsal_woocommerce_extension_get_order_title( $order_id ) ),
|
||
'OrderStatus' => $order->get_status() ? sanitize_text_field( $order->get_status() ) : false,
|
||
$edit_link['name'] => $edit_link['value'],
|
||
),
|
||
array( __CLASS__, 'must_not_contain_refund_or_modification' )
|
||
);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Triggers when post is ipdated, checks if that is an order, and compare it to the old one to detect any changes
|
||
*
|
||
* @param int $order_id - The order ID.
|
||
* @param \WP_Post $order - The actual order object.
|
||
*
|
||
* @return void
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function order_updated( $order_id, $order ) {
|
||
// Get order post.
|
||
$order = wc_get_order( $order_id );
|
||
|
||
if ( isset( $order ) && ! empty( $order ) && ! empty( self::$_old_meta_data ) ) {
|
||
|
||
$new_meta = get_post_meta( $order_id, '', false );
|
||
$compare_changed_items = array_diff_assoc(
|
||
array_map( 'serialize', $new_meta ),
|
||
array_map( 'serialize', self::$_old_meta_data )
|
||
);
|
||
|
||
if ( ! empty( $compare_changed_items ) ) {
|
||
// Get editor link.
|
||
$edit_link = self::get_editor_link( $order );
|
||
|
||
// Log event.
|
||
Alert_Manager::trigger_event_if(
|
||
9040,
|
||
array(
|
||
'OrderID' => esc_attr( $order_id ),
|
||
'OrderTitle' => sanitize_text_field( Woocommerce_Helper::wsal_woocommerce_extension_get_order_title( $order_id ) ),
|
||
'OrderStatus' => $order->get_status() ? sanitize_text_field( $order->get_status() ) : false,
|
||
$edit_link['name'] => $edit_link['value'],
|
||
),
|
||
array( __CLASS__, 'must_not_contain_refund_or_modification' )
|
||
);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Check Product Attributes Change.
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @param WP_Post $oldpost - WP Post type object.
|
||
* @param array $data - Data array.
|
||
* @return int
|
||
*/
|
||
private static function check_attributes_change( $oldpost, $data = false ) {
|
||
$product_id = '';
|
||
$title = '';
|
||
$status = '';
|
||
|
||
if ( isset( $oldpost->ID ) && ! empty( $oldpost->ID ) ) {
|
||
$post_attributes = get_post_meta( $oldpost->ID, '_product_attributes', true ); // Get post attribute meta.
|
||
$product_id = $oldpost->ID;
|
||
$title = $oldpost->post_title;
|
||
$status = $oldpost->post_status;
|
||
} else {
|
||
$post_attributes = get_post_meta( $oldpost->get_id(), '_product_attributes', true ); // Get post attribute meta.
|
||
$product_id = $oldpost->get_id();
|
||
$title = $oldpost->get_title();
|
||
$status = $oldpost->get_status();
|
||
}
|
||
$post_attributes = ! $post_attributes ? array() : $post_attributes;
|
||
|
||
if ( ! $data ) {
|
||
$data = array_map( 'sanitize_text_field', wp_unslash( $_POST ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||
}
|
||
|
||
$attribute_names = isset( $data['attribute_names'] ) && ! empty( $data['attribute_names'] ) ? array_map( 'sanitize_text_field', wp_unslash( $data['attribute_names'] ) ) : false;
|
||
$attribute_position = isset( $data['attribute_position'] ) && ! empty( $data['attribute_position'] ) ? array_map( 'sanitize_text_field', wp_unslash( $data['attribute_position'] ) ) : false;
|
||
$attribute_visibility = isset( $data['attribute_visibility'] ) && ! empty( $data['attribute_visibility'] ) ? array_map( 'sanitize_text_field', wp_unslash( $data['attribute_visibility'] ) ) : false;
|
||
$attribute_values = isset( $data['attribute_values'] ) && ! empty( $data['attribute_values'] ) ? array_map( 'sanitize_text_field', wp_unslash( $data['attribute_values'] ) ) : false;
|
||
|
||
if ( ! empty( $attribute_names ) && ! empty( $attribute_values ) ) {
|
||
$new_attributes = array();
|
||
foreach ( $attribute_names as $key => $name ) {
|
||
$attr_key = self::get_attribute_key( $name );
|
||
$new_attributes[ $attr_key ] = array(
|
||
'name' => $name,
|
||
'value' => isset( $attribute_values[ $key ] ) ? sanitize_text_field( self::get_string_attribute_value( $attribute_values[ $key ] ) ) : false,
|
||
'position' => isset( $attribute_position[ $key ] ) ? sanitize_text_field( $attribute_position[ $key ] ) : false,
|
||
'is_visible' => isset( $attribute_visibility[ $key ] ) ? sanitize_text_field( $attribute_visibility[ $key ] ) : false,
|
||
);
|
||
}
|
||
|
||
// Compare old and new attributes.
|
||
|
||
$added_attributes = array_diff_key( $new_attributes, $post_attributes );
|
||
$deleted_attributes = array_diff_key( $post_attributes, $new_attributes );
|
||
|
||
$compare_changed_items = array_diff_assoc(
|
||
array_map( 'serialize', $added_attributes ),
|
||
array_map( 'serialize', $deleted_attributes )
|
||
);
|
||
$changed_items = array_map( 'unserialize', $compare_changed_items );
|
||
|
||
$compare_added = array_diff(
|
||
array_map( 'serialize', $added_attributes ),
|
||
array_map( 'serialize', $changed_items )
|
||
);
|
||
$diff_check = array_map( 'unserialize', $compare_added );
|
||
|
||
// Get product editor link.
|
||
$editor_link = self::get_editor_link( $oldpost );
|
||
|
||
// Result.
|
||
$result = 0;
|
||
|
||
// Event 9047.
|
||
if ( ! empty( $added_attributes ) && empty( $diff_check ) ) {
|
||
foreach ( $added_attributes as $added_attribute ) {
|
||
$old_name = array( array_search( $added_attribute['value'], array_column( $changed_items, 'value', 'name' ), true ) );
|
||
$deleted_name = array( array_search( $added_attribute['value'], array_column( $deleted_attributes, 'value', 'name' ), true ) );
|
||
if ( ! empty( $old_name[0] ) && ! empty( $deleted_name[0] ) ) {
|
||
continue;
|
||
}
|
||
if ( $added_attribute && ! empty( $added_attribute['name'] ) && ! empty( $added_attribute['value'] ) ) {
|
||
Alert_Manager::trigger_event(
|
||
9047,
|
||
array(
|
||
'AttributeName' => sanitize_text_field( $added_attribute['name'] ),
|
||
'AttributeValue' => sanitize_text_field( $added_attribute['value'] ),
|
||
'ProductID' => esc_attr( $product_id ),
|
||
'SKU' => self::get_product_sku( $product_id ),
|
||
'ProductTitle' => sanitize_text_field( $title ),
|
||
'ProductStatus' => sanitize_text_field( $status ),
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
$result = 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Event 9050.
|
||
if ( ! empty( $deleted_attributes ) ) {
|
||
foreach ( $deleted_attributes as $deleted_attribute ) {
|
||
$old_name = array( array_search( $deleted_attribute['value'], array_column( $changed_items, 'value', 'name' ), true ) );
|
||
if ( ! empty( $old_name[0] ) ) {
|
||
continue;
|
||
}
|
||
Alert_Manager::trigger_event(
|
||
9050,
|
||
array(
|
||
'AttributeName' => sanitize_text_field( $deleted_attribute['name'] ),
|
||
'AttributeValue' => sanitize_text_field( $deleted_attribute['value'] ),
|
||
'ProductID' => esc_attr( $product_id ),
|
||
'SKU' => self::get_product_sku( $product_id ),
|
||
'ProductTitle' => sanitize_text_field( $title ),
|
||
'ProductStatus' => sanitize_text_field( $status ),
|
||
'ProductUrl' => get_permalink( $product_id ),
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
$result = 1;
|
||
}
|
||
}
|
||
|
||
// Event 9049.
|
||
if ( ! empty( $changed_items ) ) {
|
||
foreach ( $changed_items as $attr_key => $new_attr ) {
|
||
// Get old and new attribute names.
|
||
$old_name = array( array_search( $new_attr['value'], array_column( $deleted_attributes, 'value', 'name' ), true ) );
|
||
if ( ! empty( $old_name ) ) {
|
||
$old_name = (string) $old_name[0];
|
||
} else {
|
||
$old_name = isset( $post_attributes[ $attr_key ]['name'] ) ? $post_attributes[ $attr_key ]['name'] : false;
|
||
}
|
||
$new_name = isset( $new_attr['name'] ) ? $new_attr['name'] : false;
|
||
|
||
if ( ! empty( $old_attributes ) && isset( $old_attributes[ $attr_key ] ) ) {
|
||
$old_name = $old_attributes[ $attr_key ]['name'];
|
||
}
|
||
|
||
// Name change.
|
||
if ( ! empty( $old_name ) && $old_name !== $new_name ) {
|
||
if ( ! $new_name ) {
|
||
continue;
|
||
}
|
||
Alert_Manager::trigger_event(
|
||
9049,
|
||
array(
|
||
'AttributeName' => sanitize_text_field( $new_attr['name'] ),
|
||
'OldValue' => sanitize_text_field( $old_name ),
|
||
'NewValue' => sanitize_text_field( $new_name ),
|
||
'ProductID' => esc_attr( $product_id ),
|
||
'SKU' => self::get_product_sku( $product_id ),
|
||
'ProductTitle' => sanitize_text_field( $title ),
|
||
'ProductStatus' => sanitize_text_field( $status ),
|
||
'ProductUrl' => get_permalink( $product_id ),
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
$result = 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( ! empty( $new_attributes ) ) {
|
||
foreach ( $new_attributes as $attr_key => $new_attr ) {
|
||
|
||
// Get old attribute value.
|
||
$old_value = '';
|
||
if ( false !== strpos( $attr_key, 'pa_' ) ) {
|
||
$old_value = self::get_wc_product_attributes( $oldpost, $attr_key );
|
||
} else {
|
||
$old_value = isset( $post_attributes[ $attr_key ]['value'] ) ? $post_attributes[ $attr_key ]['value'] : false;
|
||
}
|
||
$new_value = isset( $new_attr['value'] ) ? $new_attr['value'] : false; // Get new attribute value.
|
||
|
||
// Get old and new attribute names.
|
||
$old_name = array( array_search( $new_attr['value'], array_column( $deleted_attributes, 'value', 'name' ), true ) );
|
||
if ( ! empty( $old_name ) ) {
|
||
$old_name = (string) $old_name[0];
|
||
} else {
|
||
$old_name = isset( $post_attributes[ $attr_key ]['name'] ) ? $post_attributes[ $attr_key ]['name'] : false;
|
||
}
|
||
$new_name = isset( $new_attr['name'] ) ? $new_attr['name'] : false;
|
||
|
||
// Get old and new attribute visibility.
|
||
$old_visible = isset( $post_attributes[ $attr_key ]['is_visible'] ) ? (int) $post_attributes[ $attr_key ]['is_visible'] : false;
|
||
$new_visible = isset( $new_attr['is_visible'] ) ? (int) $new_attr['is_visible'] : false;
|
||
|
||
if ( ! empty( $old_attributes ) && isset( $old_attributes[ $attr_key ] ) ) {
|
||
$old_value = $old_attributes[ $attr_key ]['value'];
|
||
$old_name = $old_attributes[ $attr_key ]['name'];
|
||
$old_visible = $old_attributes[ $attr_key ]['is_visible'];
|
||
}
|
||
|
||
// Value change.
|
||
if ( $old_value && $new_value && $old_value !== $new_value ) {
|
||
Alert_Manager::trigger_event(
|
||
9048,
|
||
array(
|
||
'AttributeName' => sanitize_text_field( $new_attr['name'] ),
|
||
'OldValue' => sanitize_text_field( $old_value ),
|
||
'NewValue' => sanitize_text_field( $new_value ),
|
||
'ProductID' => esc_attr( $product_id ),
|
||
'SKU' => self::get_product_sku( $product_id ),
|
||
'ProductTitle' => sanitize_text_field( $title ),
|
||
'ProductStatus' => sanitize_text_field( $status ),
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
$result = 1;
|
||
}
|
||
|
||
// Visibility change.
|
||
if ( ! empty( $oldpost ) && ! empty( $new_attr['name'] ) && $old_visible !== $new_visible && ! $result ) {
|
||
Alert_Manager::trigger_event(
|
||
9051,
|
||
array(
|
||
'AttributeName' => sanitize_text_field( $new_attr['name'] ),
|
||
'AttributeVisiblilty' => 1 === $new_visible ? __( 'Visible', 'wp-security-audit-log' ) : __( 'Non-Visible', 'wp-security-audit-log' ),
|
||
'OldAttributeVisiblilty' => 1 === $old_visible ? __( 'Visible', 'wp-security-audit-log' ) : __( 'Non-Visible', 'wp-security-audit-log' ),
|
||
'ProductID' => esc_attr( $product_id ),
|
||
'SKU' => self::get_product_sku( $product_id ),
|
||
'ProductTitle' => sanitize_text_field( $title ),
|
||
'ProductStatus' => sanitize_text_field( $status ),
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
$result = 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
return $result;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Check Product Image Change.
|
||
*
|
||
* @param WP_Post $oldpost - WP Post type object.
|
||
* @param array $data - Data array.
|
||
* @return int
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function check_image_change( $oldpost, $data = false ) {
|
||
|
||
if ( ! $data ) {
|
||
// @codingStandardsIgnoreStart
|
||
$data = array_map( 'sanitize_text_field', wp_unslash( $_POST ) );
|
||
// @codingStandardsIgnoreEnd
|
||
}
|
||
|
||
if ( ! isset( $data['_thumbnail_id'] ) ) {
|
||
return 0;
|
||
}
|
||
|
||
// Setup our variables.
|
||
$thumb_id = get_post_thumbnail_id( $oldpost->ID );
|
||
$old_attachment_metadata = self::$_old_attachment_metadata;
|
||
$attachment_metadata = wp_get_attachment_metadata( $data['_thumbnail_id'] );
|
||
$get_upload_dir = wp_get_upload_dir();
|
||
$event_id = 9095;
|
||
$editor_link = self::get_editor_link( $oldpost );
|
||
$alert_needed = false;
|
||
|
||
// Push editor link into event data early.
|
||
$event_data = array(
|
||
$editor_link['name'] => $editor_link['value'],
|
||
);
|
||
|
||
$event_data['PostID'] = $oldpost->ID;
|
||
$event_data['ProductTitle'] = sanitize_text_field( $oldpost->post_title );
|
||
$event_data['ProductStatus'] = sanitize_text_field( $oldpost->post_status );
|
||
$event_data['SKU'] = self::get_product_sku( $oldpost->ID );
|
||
|
||
// Featued image added.
|
||
if ( empty( $old_attachment_metadata ) && ! empty( $attachment_metadata ) && isset( $attachment_metadata['file'] ) ) {
|
||
$event_data['EventType'] = 'added';
|
||
$event_data['name'] = basename( $attachment_metadata['file'] );
|
||
$event_data['path'] = $get_upload_dir['basedir'] . DIRECTORY_SEPARATOR . $attachment_metadata['file'];
|
||
$alert_needed = true;
|
||
}
|
||
|
||
// Featued image removed.
|
||
if ( empty( $attachment_metadata ) && ! empty( $old_attachment_metadata ) ) {
|
||
$event_data['EventType'] = 'deleted';
|
||
$event_data['name'] = basename( $old_attachment_metadata['file'] );
|
||
$event_data['path'] = $get_upload_dir['basedir'] . DIRECTORY_SEPARATOR . $old_attachment_metadata['file'];
|
||
$alert_needed = true;
|
||
}
|
||
|
||
// Featured image modified.
|
||
if ( ! empty( $attachment_metadata ) && ! empty( $old_attachment_metadata ) && ( $attachment_metadata !== $old_attachment_metadata ) ) {
|
||
$event_id = 9096;
|
||
$event_data['EventType'] = 'modified';
|
||
$event_data['old_name'] = basename( $old_attachment_metadata['file'] );
|
||
$event_data['old_path'] = $get_upload_dir['basedir'] . DIRECTORY_SEPARATOR . $old_attachment_metadata['file'];
|
||
$event_data['name'] = basename( $attachment_metadata['file'] );
|
||
$event_data['path'] = $get_upload_dir['basedir'] . DIRECTORY_SEPARATOR . $attachment_metadata['file'];
|
||
$alert_needed = true;
|
||
}
|
||
|
||
// Its go time.
|
||
if ( $alert_needed ) {
|
||
Alert_Manager::trigger_event( $event_id, $event_data );
|
||
return 1;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Check Product Download Limit Change.
|
||
*
|
||
* @param WP_Post $oldpost - WP Post type object.
|
||
* @param array $data - Data array.
|
||
* @return int
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function check_download_limit_change( $oldpost, $data = false ) {
|
||
|
||
if ( ! $data ) {
|
||
// @codingStandardsIgnoreStart
|
||
$data = array_map( 'sanitize_text_field', wp_unslash( $_POST ) );
|
||
// @codingStandardsIgnoreEnd
|
||
}
|
||
|
||
if ( ! isset( $data['_download_expiry'] ) || ! isset( $data['_download_limit'] ) ) {
|
||
return 0;
|
||
}
|
||
|
||
$event_id = false;
|
||
$editor_link = self::get_editor_link( self::$old_post );
|
||
$alert_needed = false;
|
||
|
||
// Push editor link into event data early.
|
||
$event_data = array(
|
||
$editor_link['name'] => $editor_link['value'],
|
||
);
|
||
|
||
$event_data['new_value'] = $data['_download_expiry'];
|
||
$event_data['product_name'] = $data['post_title'];
|
||
$event_data['ID'] = $data['post_ID'];
|
||
$event_data['ProductStatus'] = $data['post_status'];
|
||
|
||
if ( isset( $oldpost['_download_limit'] ) && intval( $oldpost['_download_limit'][0] ) < 0 ) {
|
||
$oldpost['_download_limit'][0] = __( 'Unlimited', 'wp-security-audit-log' );
|
||
}
|
||
|
||
if ( isset( $oldpost['_download_expire'] ) && intval( $oldpost['_download_expiry'][0] ) < 0 ) {
|
||
$oldpost['_download_expiry'][0] = __( 'Never', 'wp-security-audit-log' );
|
||
}
|
||
|
||
if ( ! $data['_download_limit'] ) {
|
||
$data['_download_limit'] = __( 'Unlimited', 'wp-security-audit-log' );
|
||
}
|
||
|
||
if ( ! $data['_download_expiry'] ) {
|
||
$data['_download_expiry'] = __( 'Never', 'wp-security-audit-log' );
|
||
}
|
||
|
||
// Event 9097 (Modified the download limit of the product).
|
||
if ( isset( $oldpost['_download_limit'] ) && $oldpost['_download_limit'][0] !== $data['_download_limit'] ) {
|
||
$event_id = 9097;
|
||
$event_data['previous_value'] = $oldpost['_download_limit'][0];
|
||
$event_data['new_value'] = $data['_download_limit'];
|
||
$event_data['SKU'] = self::get_product_sku( $data['post_ID'] );
|
||
Alert_Manager::trigger_event( $event_id, $event_data );
|
||
|
||
$alert_needed = true;
|
||
}
|
||
|
||
// Event 9098 (Modified the download expires of the product).
|
||
if ( isset( $oldpost['_download_expiry'] ) && $oldpost['_download_expiry'][0] !== $data['_download_expiry'] ) {
|
||
|
||
// The empty value for this is stored as -1, so double check we actually have a change to report.
|
||
$old_value = ( '-1' === $oldpost['_download_expiry'][0] ) ? 'Never' : $oldpost['_download_expiry'][0];
|
||
if ( $old_value === $data['_download_expiry'] ) {
|
||
return false;
|
||
}
|
||
|
||
$event_id = 9098;
|
||
$event_data['previous_value'] = $old_value;
|
||
$event_data['new_value'] = $data['_download_expiry'];
|
||
$event_data['SKU'] = self::get_product_sku( $data['post_ID'] );
|
||
Alert_Manager::trigger_event( $event_id, $event_data );
|
||
|
||
$alert_needed = true;
|
||
}
|
||
|
||
return $alert_needed;
|
||
}
|
||
|
||
|
||
/**
|
||
* Trigger alert if change of tax status or class occurs.
|
||
*
|
||
* @param WC_Product $product - Old post meta data.
|
||
* @param array $oldpost - Old post.
|
||
* @param WC_Product $post - new post.
|
||
*
|
||
* @return void
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function check_tax_status_change( $product, $oldpost, $post ) {
|
||
if ( ! isset( $oldpost['_tax_status'] ) || ! isset( $post['tax_status'] ) ) {
|
||
return;
|
||
}
|
||
|
||
// Tax status.
|
||
$old_status = $oldpost['_tax_status'][0];
|
||
$status = $post['tax_status'];
|
||
|
||
if ( $status !== $old_status ) {
|
||
$editor_link = self::get_editor_link( $product );
|
||
Alert_Manager::trigger_event(
|
||
9113,
|
||
array(
|
||
'PostID' => $product->ID,
|
||
'SKU' => esc_attr( self::get_product_sku( $product->ID ) ),
|
||
'ProductTitle' => $product->post_title,
|
||
'ProductStatus' => $product->post_status,
|
||
'old_tax_status' => $old_status,
|
||
'new_tax_status' => $status,
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
}
|
||
|
||
// Tax class.
|
||
$old_class = ( empty( $oldpost['_tax_class'][0] ) ) ? 'standard' : $oldpost['_tax_class'][0];
|
||
$class = ( empty( $post['tax_class'] ) ) ? 'standard' : $post['tax_class'];
|
||
|
||
if ( $class !== $old_class ) {
|
||
$editor_link = self::get_editor_link( $product );
|
||
Alert_Manager::trigger_event(
|
||
9114,
|
||
array(
|
||
'PostID' => $product->ID,
|
||
'SKU' => esc_attr( self::get_product_sku( $product->ID ) ),
|
||
'ProductTitle' => $product->post_title,
|
||
'ProductStatus' => $product->post_status,
|
||
'old_tax_class' => $old_class,
|
||
'new_tax_class' => $class,
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Trigger alert if change of low stock threshold occurs.
|
||
*
|
||
* @param WC_Product $product - Old post meta data.
|
||
* @param array $oldpost - Old post.
|
||
* @param WC_Product $post - new post.
|
||
* @return void
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
private static function check_low_stock_threshold_change( $product, $oldpost, $post ) {
|
||
$old_status = ( isset( $oldpost['_low_stock_amount'] ) ) ? $oldpost['_low_stock_amount'][0] : __( 'Store Default', 'wp-security-audit-log' );
|
||
$status = ( isset( $post['low_stock_amount'] ) && ! empty( $post['low_stock_amount'] ) ) ? $post['low_stock_amount'] : __( 'Store Default', 'wp-security-audit-log' );
|
||
|
||
if ( $status !== $old_status ) {
|
||
$editor_link = self::get_editor_link( $product );
|
||
Alert_Manager::trigger_event(
|
||
9119,
|
||
array(
|
||
'PostID' => $product->ID,
|
||
'SKU' => esc_attr( self::get_product_sku( $product->ID ) ),
|
||
'ProductTitle' => $product->post_title,
|
||
'ProductStatus' => $product->post_status,
|
||
'old_low_stock_amount' => $old_status,
|
||
'new_low_stock_amount' => $status,
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Check Product Variations Change.
|
||
*
|
||
* @since 3.3.1.2
|
||
*
|
||
* @param WP_Post $oldpost - WP Post type object.
|
||
* @param array $data - Data array.
|
||
* @return int
|
||
*/
|
||
private static function check_variations_change( $oldpost, $data = false ) {
|
||
if ( ! $data ) {
|
||
// @codingStandardsIgnoreLine
|
||
$data = array_map( 'sanitize_text_field', wp_unslash( $_POST ) );
|
||
}
|
||
|
||
if ( ! empty( $data['variable_post_id'] ) ) {
|
||
foreach ( $data['variable_post_id'] as $key => $post_id ) {
|
||
$post_id = absint( $post_id );
|
||
$variation = new \WC_Product_Variation( $post_id );
|
||
|
||
// Copy and set the product variation.
|
||
$product = $oldpost;
|
||
$product->post_title = $variation->get_name();
|
||
$product->post_status = $variation->get_status();
|
||
|
||
// Check regular price.
|
||
$old_price = (int) $variation->get_regular_price();
|
||
$new_price = isset( $data['variable_regular_price'][ $key ] ) ? (int) sanitize_text_field( wp_unslash( $data['variable_regular_price'][ $key ] ) ) : false;
|
||
if ( $old_price !== $new_price ) {
|
||
$result = self::event_price( $product, 'Regular price', $old_price, $new_price );
|
||
}
|
||
|
||
// Check sale price.
|
||
$old_sale_price = (int) $variation->get_sale_price();
|
||
$new_sale_price = isset( $data['variable_sale_price'][ $key ] ) ? (int) sanitize_text_field( wp_unslash( $data['variable_sale_price'][ $key ] ) ) : false;
|
||
if ( $old_sale_price !== $new_sale_price ) {
|
||
$result = self::event_price( $product, 'Sale price', $old_sale_price, $new_sale_price );
|
||
}
|
||
|
||
// Check product SKU.
|
||
$old_sku = $variation->get_sku();
|
||
$new_sku = isset( $data['variable_sku'][ $key ] ) ? sanitize_text_field( wp_unslash( $data['variable_sku'][ $key ] ) ) : false;
|
||
if ( $old_sku !== $new_sku ) {
|
||
$result = self::check_sku_change( $product, $old_sku, $new_sku );
|
||
}
|
||
|
||
// Check product virtual.
|
||
$virtual['old'] = $variation->is_virtual();
|
||
$virtual['new'] = isset( $data['variable_is_virtual'][ $key ] ) ? true : false;
|
||
if ( $virtual['old'] !== $virtual['new'] ) {
|
||
$result = self::check_type_change( $product, null, $virtual );
|
||
}
|
||
|
||
// Check product downloadable.
|
||
$download['old'] = $variation->is_downloadable();
|
||
$download['new'] = isset( $data['variable_is_downloadable'][ $key ] ) ? true : false;
|
||
if ( $download['old'] !== $download['new'] ) {
|
||
$result = self::check_type_change( $product, null, false, $download );
|
||
}
|
||
|
||
// Check product stock status.
|
||
$old_stock_status = $variation->get_stock_status();
|
||
$new_stock_status = isset( $data['variable_stock_status'][ $key ] ) ? sanitize_text_field( wp_unslash( $data['variable_stock_status'][ $key ] ) ) : false;
|
||
if ( $old_stock_status !== $new_stock_status ) {
|
||
$result = self::check_stock_status_change( $product, $old_stock_status, $new_stock_status );
|
||
}
|
||
|
||
// Check product stock quantity.
|
||
$old_stock = $variation->get_stock_quantity();
|
||
$new_stock = isset( $data['variable_stock'][ $key ] ) ? (int) sanitize_text_field( wp_unslash( $data['variable_stock'][ $key ] ) ) : false;
|
||
if ( $old_stock !== $new_stock ) {
|
||
$result = self::check_stock_quantity_change( $product, $old_stock, $new_stock );
|
||
}
|
||
|
||
// Check product weight.
|
||
$old_weight = $variation->get_weight();
|
||
$new_weight = isset( $data['variable_weight'][ $key ] ) ? sanitize_text_field( wp_unslash( $data['variable_weight'][ $key ] ) ) : false;
|
||
if ( $old_weight !== $new_weight ) {
|
||
$result = self::check_weight_change( $product, $old_weight, $new_weight );
|
||
}
|
||
|
||
// Check product dimensions change.
|
||
$length['old'] = $variation->get_length();
|
||
$length['new'] = isset( $data['variable_length'][ $key ] ) ? sanitize_text_field( wp_unslash( $data['variable_length'][ $key ] ) ) : false;
|
||
$width['old'] = $variation->get_width();
|
||
$width['new'] = isset( $data['variable_width'][ $key ] ) ? sanitize_text_field( wp_unslash( $data['variable_width'][ $key ] ) ) : false;
|
||
$height['old'] = $variation->get_height();
|
||
$height['new'] = isset( $data['variable_height'][ $key ] ) ? sanitize_text_field( wp_unslash( $data['variable_height'][ $key ] ) ) : false;
|
||
self::check_dimensions_change( $product, $length, $width, $height );
|
||
|
||
// Check product downloads change.
|
||
$file_names['new'] = isset( $data['_wc_variation_file_names'][ $post_id ] ) ? array_map( 'sanitize_text_field', wp_unslash( $data['_wc_variation_file_names'][ $post_id ] ) ) : array();
|
||
$file_urls['new'] = isset( $data['_wc_variation_file_urls'][ $post_id ] ) ? array_map( 'esc_url_raw', wp_unslash( $data['_wc_variation_file_urls'][ $post_id ] ) ) : array();
|
||
$file_names['old'] = array();
|
||
$file_urls['old'] = array();
|
||
|
||
// Set product old downloads data.
|
||
foreach ( $variation->get_downloads() as $download ) {
|
||
array_push( $file_names['old'], $download->get_name() );
|
||
array_push( $file_urls['old'], $download->get_file() );
|
||
}
|
||
self::check_downloadable_file_change( $product, $file_names, $file_urls );
|
||
|
||
// Check backorders change.
|
||
$old_backorder = $variation->get_backorders();
|
||
$new_backorder = isset( $data['variable_backorders'][ $key ] ) ? sanitize_text_field( wp_unslash( $data['variable_backorders'][ $key ] ) ) : false;
|
||
self::check_backorders_setting( $product, $old_backorder, $new_backorder );
|
||
}
|
||
}
|
||
return 1;
|
||
}
|
||
|
||
/**
|
||
* Returns the attribute key using attribute name.
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @param string $attribute_name - Attribute name.
|
||
* @return string
|
||
*/
|
||
private static function get_attribute_key( $attribute_name = '' ) {
|
||
return str_replace( ' ', '-', strtolower( $attribute_name ) );
|
||
}
|
||
|
||
/**
|
||
* Return the attribute value string using WooCommerce attribute value field.
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @param string $attribute_value - WooCommerce attribute value field.
|
||
* @return string
|
||
*/
|
||
private static function get_string_attribute_value( $attribute_value = '' ) {
|
||
// New attribute value.
|
||
$new_attr_value = '';
|
||
|
||
// Check if incoming value is string.
|
||
if ( is_string( $attribute_value ) ) {
|
||
$new_attr_value = sanitize_text_field( wp_unslash( $attribute_value ) );
|
||
} elseif ( is_array( $attribute_value ) ) {
|
||
// If the incoming value is an array, it is an array of term ids.
|
||
$term_attr_values = array_map( 'sanitize_text_field', wp_unslash( $attribute_value ) );
|
||
|
||
$new_attr_value = array();
|
||
foreach ( $term_attr_values as $term_id ) {
|
||
$term = get_term( $term_id ); // Get term.
|
||
if ( null !== $term && ! is_wp_error( $term ) ) {
|
||
$new_attr_value[] = $term->name;
|
||
}
|
||
}
|
||
$new_attr_value = implode( ' | ', $new_attr_value );
|
||
}
|
||
return $new_attr_value;
|
||
}
|
||
|
||
/**
|
||
* Return product attribute value.
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @param WP_Post $product - Product post object.
|
||
* @param string $taxonomy - Taxonomy.
|
||
* @return string
|
||
*/
|
||
private static function get_wc_product_attributes( $product, $taxonomy ) {
|
||
$attribute_terms = wp_get_post_terms( $product->ID, $taxonomy );
|
||
$product_attrs = array();
|
||
|
||
if ( ! is_wp_error( $attribute_terms ) ) {
|
||
foreach ( $attribute_terms as $single_term ) {
|
||
$product_attrs[] = $single_term->term_id;
|
||
}
|
||
}
|
||
return self::get_string_attribute_value( $product_attrs );
|
||
}
|
||
|
||
/**
|
||
* Check Product Category Updated Events.
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @param array $data - Term data to be updated.
|
||
* @param int $term_id - Term ID.
|
||
* @param string $taxonomy - Taxonomy slug.
|
||
* @param array $args - Arguments passed to wp_update_term().
|
||
*/
|
||
public static function event_product_cat_updated( $data, $term_id, $taxonomy, $args ) {
|
||
|
||
// Check if the taxonomy is `product_cat`.
|
||
if ( 'product_cat' === $taxonomy ) {
|
||
// Get term data.
|
||
$new_name = isset( $data['name'] ) ? $data['name'] : false;
|
||
$new_slug = isset( $data['slug'] ) ? $data['slug'] : false;
|
||
$new_parent_id = isset( $args['parent'] ) ? $args['parent'] : false;
|
||
|
||
// New parent category.
|
||
$new_parent_cat = false;
|
||
if ( 0 !== $new_parent_id ) {
|
||
$new_parent_cat = get_term( $new_parent_id, $taxonomy );
|
||
}
|
||
|
||
// Get old data.
|
||
$term = get_term( $term_id, $taxonomy );
|
||
$old_name = $term->name;
|
||
$old_slug = $term->slug;
|
||
|
||
// Old parent category.
|
||
$old_parent_cat = false;
|
||
if ( $term->parent ) {
|
||
$old_parent_cat = get_term( $term->parent, $taxonomy );
|
||
}
|
||
|
||
// Update if both slugs are not same.
|
||
if ( $old_slug !== $new_slug ) {
|
||
Alert_Manager::trigger_event(
|
||
9053,
|
||
array(
|
||
'CategoryID' => esc_attr( $term_id ),
|
||
'CategoryName' => sanitize_text_field( $new_name ),
|
||
'OldSlug' => sanitize_text_field( $old_slug ),
|
||
'NewSlug' => sanitize_text_field( $new_slug ),
|
||
'ProductCatLink' => Woocommerce_Helper::get_taxonomy_edit_link( $term_id ),
|
||
)
|
||
);
|
||
}
|
||
|
||
// Update if both parent categories are not same.
|
||
if ( $term->parent !== $new_parent_id ) {
|
||
Alert_Manager::trigger_event(
|
||
9054,
|
||
array(
|
||
'CategoryID' => esc_attr( $term_id ),
|
||
'CategoryName' => sanitize_text_field( $new_name ),
|
||
'CategorySlug' => sanitize_text_field( $term->slug ),
|
||
'ProductCatLink' => Woocommerce_Helper::get_taxonomy_edit_link( $term_id ),
|
||
'OldParentID' => isset( $old_parent_cat->term_id ) ? esc_attr( $old_parent_cat->term_id ) : false,
|
||
'OldParentCat' => isset( $old_parent_cat->name ) ? sanitize_text_field( $old_parent_cat->name ) : false,
|
||
'NewParentID' => isset( $new_parent_cat->term_id ) ? esc_attr( $new_parent_cat->term_id ) : false,
|
||
'NewParentCat' => isset( $new_parent_cat->name ) ? sanitize_text_field( $new_parent_cat->name ) : false,
|
||
)
|
||
);
|
||
}
|
||
|
||
// Update if both names are not same.
|
||
if ( $old_name !== $new_name ) {
|
||
Alert_Manager::trigger_event(
|
||
9056,
|
||
array(
|
||
'CategoryID' => esc_attr( $term_id ),
|
||
'CategoryName' => sanitize_text_field( $new_name ),
|
||
'OldName' => sanitize_text_field( $old_name ),
|
||
'NewName' => sanitize_text_field( $new_name ),
|
||
'CategorySlug' => sanitize_text_field( $term->slug ),
|
||
'ProductCatLink' => Woocommerce_Helper::get_taxonomy_edit_link( $term_id ),
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
if ( 'product_tag' === $taxonomy ) {
|
||
// Get term data.
|
||
$new_name = isset( $data['name'] ) ? $data['name'] : false;
|
||
$new_slug = isset( $data['slug'] ) ? $data['slug'] : false;
|
||
$new_parent_id = isset( $args['parent'] ) ? $args['parent'] : false;
|
||
|
||
// New parent category.
|
||
$new_parent_cat = false;
|
||
if ( 0 !== $new_parent_id ) {
|
||
$new_parent_cat = get_term( $new_parent_id, $taxonomy );
|
||
}
|
||
|
||
// Get old data.
|
||
$term = get_term( $term_id, $taxonomy );
|
||
$old_name = $term->name;
|
||
$old_slug = $term->slug;
|
||
|
||
// Old parent category.
|
||
$old_parent_cat = false;
|
||
if ( $term->parent ) {
|
||
$old_parent_cat = get_term( $term->parent, $taxonomy );
|
||
}
|
||
|
||
// Update if both slugs are not same.
|
||
if ( $old_slug !== $new_slug ) {
|
||
Alert_Manager::trigger_event(
|
||
9104,
|
||
array(
|
||
'TagName' => sanitize_text_field( $new_name ),
|
||
'OldSlug' => sanitize_text_field( $old_slug ),
|
||
'NewSlug' => sanitize_text_field( $new_slug ),
|
||
'ProductTagLink' => Woocommerce_Helper::get_taxonomy_edit_link( $term_id, 'product_tag' ),
|
||
)
|
||
);
|
||
}
|
||
|
||
// Update if both names are not same.
|
||
if ( $old_name !== $new_name ) {
|
||
Alert_Manager::trigger_event(
|
||
9103,
|
||
array(
|
||
'OldName' => sanitize_text_field( $old_name ),
|
||
'NewName' => sanitize_text_field( $new_name ),
|
||
'Slug' => sanitize_text_field( $term->slug ),
|
||
'ProductTagLink' => Woocommerce_Helper::get_taxonomy_edit_link( $term_id, 'product_tag' ),
|
||
)
|
||
);
|
||
}
|
||
}
|
||
return $data;
|
||
}
|
||
|
||
/**
|
||
* Check Product Category Display Type Meta Event.
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @param int $meta_id - ID of the metadata entry to update.
|
||
* @param int $object_id - Object ID.
|
||
* @param string $meta_key - Meta key.
|
||
* @param mixed $meta_value - Meta value.
|
||
*/
|
||
public static function event_cat_display_updated( $meta_id, $object_id, $meta_key, $meta_value ) {
|
||
// Check `display_type` meta key.
|
||
if ( 'display_type' !== $meta_key ) {
|
||
return;
|
||
}
|
||
|
||
// Get previous value.
|
||
$old_display = get_term_meta( $object_id, $meta_key, true );
|
||
|
||
// Get term.
|
||
$term = get_term( $object_id, 'product_cat' );
|
||
|
||
// Check if display type changed.
|
||
if ( $meta_value !== $old_display ) {
|
||
Alert_Manager::trigger_event(
|
||
9055,
|
||
array(
|
||
'CategoryID' => esc_attr( $object_id ),
|
||
'CategoryName' => sanitize_text_field( $term->name ),
|
||
'CategorySlug' => sanitize_text_field( $term->slug ),
|
||
'OldDisplayType' => sanitize_text_field( $old_display ),
|
||
'NewDisplayType' => sanitize_text_field( $meta_value ),
|
||
'ProductCatLink' => Woocommerce_Helper::get_taxonomy_edit_link( $object_id ),
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Check Product Category Deletion Event.
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @param int $term_id - Term ID.
|
||
* @param int $tt_id - Term taxonomy ID.
|
||
* @param mixed $deleted_term - Copy of the already-deleted term, in the form specified by the parent function. WP_Error otherwise.
|
||
* @param array $object_ids - List of term object IDs.
|
||
*/
|
||
public static function event_product_cat_deleted( $term_id, $tt_id, $deleted_term, $object_ids ) {
|
||
if ( 'product_cat' === $deleted_term->taxonomy ) {
|
||
Alert_Manager::trigger_event(
|
||
9052,
|
||
array(
|
||
'CategoryID' => esc_attr( $deleted_term->term_id ),
|
||
'CategoryName' => sanitize_text_field( $deleted_term->name ),
|
||
'CategorySlug' => sanitize_text_field( $deleted_term->slug ),
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Check Product Tag Deletion Event.
|
||
*
|
||
* @since 1.4.0
|
||
*
|
||
* @param int $term_id - Term ID.
|
||
* @param int $tt_id - Term taxonomy ID.
|
||
* @param mixed $deleted_term - Copy of the already-deleted term, in the form specified by the parent function. WP_Error otherwise.
|
||
* @param array $object_ids - List of term object IDs.
|
||
*/
|
||
public static function event_product_tag_deleted( $term_id, $tt_id, $deleted_term, $object_ids ) {
|
||
if ( 'product_tag' === $deleted_term->taxonomy ) {
|
||
Alert_Manager::trigger_event(
|
||
9102,
|
||
array(
|
||
'ID' => esc_attr( $deleted_term->term_id ),
|
||
'Name' => sanitize_text_field( $deleted_term->name ),
|
||
'Slug' => sanitize_text_field( $deleted_term->slug ),
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Check Created Events for Coupon Meta.
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @param bool $log_event - True if log event 2053 for coupon meta, false if not.
|
||
* @param string $meta_key - Meta key.
|
||
* @param mixed $meta_value - Meta value.
|
||
* @param WP_Post $coupon - Coupon CPT object.
|
||
* @return bool
|
||
*/
|
||
public static function log_coupon_meta_created_event( $log_event, $meta_key, $meta_value, $coupon ) {
|
||
|
||
$usage_restriction_meta = array( 'individual_use', 'product_ids', 'exclude_product_ids', 'product_categories', 'exclude_product_categories', 'exclude_sale_items', 'minimum_amount', 'maximum_amount', 'customer_email' );
|
||
|
||
if ( ! empty( $meta_key ) && in_array( $meta_key, $usage_restriction_meta, true ) ) {
|
||
self::log_coupon_meta_update_events( $log_event, $meta_key, $meta_value, false, $coupon );
|
||
return false;
|
||
}
|
||
|
||
if ( ! empty( $meta_key ) && 'shop_coupon' === $coupon->post_type && in_array( $meta_key, self::$coupon_meta, true ) ) {
|
||
return false;
|
||
}
|
||
// Do not report total sales as its added automatically when a product is published.
|
||
if ( ! empty( $meta_key ) && 'total_sales' === $meta_key ) {
|
||
return false;
|
||
}
|
||
|
||
return $log_event;
|
||
}
|
||
|
||
/**
|
||
* Check Updated Events for Coupon Meta.
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @param bool $log_meta_event - True if log meta events 2054 or 2062, false if not.
|
||
* @param string $meta_key - Meta key.
|
||
* @param mixed $meta_value - Meta value.
|
||
* @param stdClass $old_meta_obj - Old meta value and key object.
|
||
* @param WP_Post $coupon - Coupon CPT object.
|
||
* @return bool
|
||
*/
|
||
public static function log_coupon_meta_update_events( $log_meta_event, $meta_key, $meta_value, $old_meta_obj, $coupon ) {
|
||
|
||
if ( \is_array( $old_meta_obj ) ) {
|
||
$old_meta_obj = (object) $old_meta_obj;
|
||
}
|
||
|
||
// If meta key does not match with any coupon meta key, then return.
|
||
if ( ! empty( $meta_key ) && ( ! in_array( $meta_key, self::$coupon_meta, true ) || 'shop_coupon' !== $coupon->post_type ) ) {
|
||
return $log_meta_event;
|
||
}
|
||
|
||
$ignore_coupon_meta = array( 'usage_count', 'free_shipping' ); // Ignore these meta keys.
|
||
$usage_restriction_meta = array( 'individual_use', 'product_ids', 'exclude_product_ids', 'product_categories', 'exclude_product_categories', 'exclude_sale_items', 'minimum_amount', 'maximum_amount', 'customer_email' ); // Event 9067.
|
||
$usage_limits_meta = array( 'usage_limit', 'usage_limit_per_user', 'limit_usage_to_x_items' ); // Event 9068.
|
||
|
||
if ( in_array( $meta_key, $ignore_coupon_meta, true ) && $meta_value !== $old_meta_obj->val ) {
|
||
return false;
|
||
} elseif ( isset( $old_meta_obj->val ) && $meta_value !== $old_meta_obj->val || ! isset( $old_meta_obj->val ) ) {
|
||
// Event id.
|
||
$event_id = false;
|
||
|
||
// Get coupon event data.
|
||
$coupon_data = self::get_coupon_event_data( $coupon );
|
||
|
||
if ( 'discount_type' === $meta_key ) {
|
||
// Set coupon discount type data.
|
||
$coupon_data['OldDiscountType'] = isset( $old_meta_obj->val ) ? $old_meta_obj->val : false;
|
||
$coupon_data['NewDiscountType'] = $meta_value;
|
||
$coupon_data['EditorLinkCoupon'] = self::get_editor_link( $coupon )['value'];
|
||
|
||
// Set event id.
|
||
$event_id = 9064;
|
||
} elseif ( 'coupon_amount' === $meta_key ) {
|
||
// Set coupon amount data.
|
||
$coupon_data['OldAmount'] = isset( $old_meta_obj->val ) ? $old_meta_obj->val : false;
|
||
$coupon_data['NewAmount'] = $meta_value;
|
||
|
||
// Set event id.
|
||
$event_id = 9065;
|
||
} elseif ( 'date_expires' === $meta_key ) {
|
||
// Set coupon expiry date data.
|
||
$coupon_data['OldDate'] = isset( $old_meta_obj->val ) && ! empty( $old_meta_obj->val ) ? gmdate( get_option( 'date_format' ), (int) $old_meta_obj->val ) : __( 'Does not expire', 'wp-security-audit-log' );
|
||
$coupon_data['NewDate'] = ! empty( $meta_value ) ? gmdate( get_option( 'date_format' ), (int) $meta_value ) : __( 'Does not expire', 'wp-security-audit-log' );
|
||
|
||
// Set event id.
|
||
$event_id = 9066;
|
||
} elseif ( in_array( $meta_key, $usage_restriction_meta, true ) && ( $meta_value || isset( $old_meta_obj->val ) ) ) {
|
||
$event_type = 'modified';
|
||
$event_id = 9067;
|
||
|
||
$meta_key = ucfirst( str_replace( '_', ' ', (string) $meta_key ) );
|
||
|
||
$previous_value = isset( $old_meta_obj->val ) ? $old_meta_obj->val : '0';
|
||
|
||
// Set usage restriction meta data.
|
||
$coupon_data['MetaKey'] = $meta_key;
|
||
$coupon_data['OldMetaValue'] = $previous_value;
|
||
$coupon_data['NewMetaValue'] = ! empty( $meta_value ) ? $meta_value : '0';
|
||
$coupon_data['EventType'] = $event_type;
|
||
|
||
if ( false === self::$is_9067_logged ) {
|
||
self::$is_9067_logged = true;
|
||
}
|
||
} elseif ( in_array( $meta_key, $usage_limits_meta, true ) ) {
|
||
// Set usage limits meta data.
|
||
$coupon_data['MetaKey'] = $meta_key;
|
||
$coupon_data['OldMetaValue'] = isset( $old_meta_obj->val ) ? $old_meta_obj->val : false;
|
||
$coupon_data['NewMetaValue'] = $meta_value;
|
||
|
||
if ( false === self::$is_9068_logged ) {
|
||
// Set event id.
|
||
$event_id = 9068;
|
||
self::$is_9068_logged = true;
|
||
}
|
||
}
|
||
|
||
if ( $event_id && ! empty( $coupon_data ) ) {
|
||
// Log the event.
|
||
Alert_Manager::trigger_event_if(
|
||
$event_id,
|
||
$coupon_data,
|
||
array( __CLASS__, 'must_not_be_new_coupon' )
|
||
);
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* Check if is a new coupon or not.
|
||
*
|
||
* @return bool - If is duplicate or not.
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function must_not_be_new_coupon() {
|
||
if ( Alert_Manager::will_or_has_triggered( 9063 ) ) {
|
||
return false;
|
||
}
|
||
if ( Alert_Manager::will_or_has_triggered( 9124 ) ) {
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* Check Created Events for Coupon Meta.
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @param bool $log_event - True if log event 2055 for coupon meta, false if not.
|
||
* @param string $meta_key - Meta key.
|
||
* @param mixed $meta_value - Meta value.
|
||
* @param WP_Post $coupon - Coupon CPT object.
|
||
* @return bool
|
||
*/
|
||
public static function log_coupon_meta_delete_event( $log_event, $meta_key, $meta_value, $coupon ) {
|
||
|
||
$usage_restriction_meta = array( 'individual_use', 'product_ids', 'exclude_product_ids', 'product_categories', 'exclude_product_categories', 'exclude_sale_items', 'minimum_amount', 'maximum_amount', 'customer_email' );
|
||
|
||
if ( ! empty( $meta_key ) && in_array( $meta_key, $usage_restriction_meta, true ) ) {
|
||
$post_attributes = array();
|
||
$post_attributes['val'] = isset( self::$_old_meta_data ) ? self::$_old_meta_data[ $meta_key ][0] : false;
|
||
$post_attributes = (object) $post_attributes;
|
||
self::log_coupon_meta_update_events( $log_event, $meta_key, $meta_value, $post_attributes, $coupon );
|
||
return false;
|
||
}
|
||
|
||
if ( ! empty( $meta_key ) && 'shop_coupon' === $coupon->post_type && in_array( $meta_key, self::$coupon_meta, true ) ) {
|
||
return false;
|
||
}
|
||
return $log_event;
|
||
}
|
||
|
||
/**
|
||
* Get WC User Meta Data before updating.
|
||
*
|
||
* @since 3.4
|
||
*
|
||
* @param integer $meta_id - Meta id.
|
||
* @param integer $user_id - User id.
|
||
* @param string $meta_key - Meta key.
|
||
*/
|
||
public static function before_wc_user_meta_update( $meta_id, $user_id, $meta_key ) {
|
||
if ( ! Woocommerce_Helper::is_woocommerce_user_meta( $meta_key ) ) {
|
||
return;
|
||
}
|
||
|
||
self::$wc_user_meta[ $meta_id ] = (object) array(
|
||
'key' => $meta_key,
|
||
'value' => get_user_meta( $user_id, $meta_key, true ),
|
||
);
|
||
}
|
||
|
||
/**
|
||
* WC User Meta data updated.
|
||
*
|
||
* @since 3.4
|
||
*
|
||
* @param integer $meta_id - Meta id.
|
||
* @param integer $user_id - User id.
|
||
* @param string $meta_key - Meta key.
|
||
* @param mixed $meta_value - Meta value.
|
||
*/
|
||
public static function wc_user_meta_updated( $meta_id, $user_id, $meta_key, $meta_value ) {
|
||
if ( ! Woocommerce_Helper::is_woocommerce_user_meta( $meta_key ) ) {
|
||
return;
|
||
}
|
||
|
||
$is_first_edit = false;
|
||
|
||
if ( ! isset( self::$wc_user_meta[ $meta_id ] ) || ! is_object( self::$wc_user_meta[ $meta_id ] ) ) {
|
||
self::$wc_user_meta[ $meta_id ] = (object) array(
|
||
'key' => $meta_key,
|
||
'value' => 'None supplied', // Not translatable as its internal only, we use a translatable string for display later on.
|
||
);
|
||
$is_first_edit = true;
|
||
}
|
||
|
||
$current_value = get_user_meta( $user_id, self::$wc_user_meta[ $meta_id ]->key, true );
|
||
|
||
if ( isset( self::$wc_user_meta[ $meta_id ] ) && $current_value !== self::$wc_user_meta[ $meta_id ]->value ) {
|
||
if ( self::$wc_user_meta[ $meta_id ]->value !== $meta_value ) {
|
||
// Event id.
|
||
$event_id = false;
|
||
|
||
if ( false !== strpos( (string) $meta_key, 'billing_' ) ) {
|
||
$event_id = 9083;
|
||
|
||
$billing_address_fields = array( 'billing_first_name', 'billing_last_name', 'billing_company', 'billing_country', 'billing_address_1', 'billing_address_2', 'billing_city', 'billing_state', 'billing_postcode', 'billing_phone' );
|
||
|
||
// We will fill this is as needed below.
|
||
$new_address_array = array();
|
||
$old_address_array = array();
|
||
|
||
foreach ( $billing_address_fields as $field ) {
|
||
$field_value = get_user_meta( $user_id, $field, true );
|
||
$new_address_array[ $field ] = ( $meta_key === $field ) ? $meta_value : $field_value;
|
||
$old_address_array[ $field ] = $field_value;
|
||
}
|
||
|
||
// Replace old values we already have stored.
|
||
foreach ( self::$wc_user_meta as $user_meta ) {
|
||
$old_address_array[ $user_meta->key ] = $user_meta->value;
|
||
}
|
||
|
||
$new_address_array = array_filter( $new_address_array );
|
||
$old_address_array = array_filter( $old_address_array );
|
||
|
||
// Combine name fields to avoid weird comma.
|
||
if ( isset( $new_address_array['billing_first_name'] ) && isset( $new_address_array['billing_last_name'] ) ) {
|
||
$new_address_array['billing_first_name'] = $new_address_array['billing_first_name'] . ' ' . $new_address_array['billing_last_name'];
|
||
unset( $new_address_array['billing_last_name'] );
|
||
}
|
||
if ( isset( $old_address_array['billing_first_name'] ) && isset( $old_address_array['billing_last_name'] ) ) {
|
||
$old_address_array['billing_first_name'] = $old_address_array['billing_first_name'] . ' ' . $old_address_array['billing_last_name'];
|
||
unset( $old_address_array['billing_last_name'] );
|
||
}
|
||
|
||
// Turn them into a nice string.
|
||
$new_address = implode( ', ', $new_address_array );
|
||
$old_address = implode( ', ', $old_address_array );
|
||
|
||
if ( $event_id ) {
|
||
$user = get_user_by( 'ID', $user_id );
|
||
if ( 9083 === $event_id ) {
|
||
// Add 1 to our changed fields counter.
|
||
++self::$updated_field_count;
|
||
Alert_Manager::trigger_event_if(
|
||
$event_id,
|
||
array(
|
||
'TargetUsername' => $user ? $user->user_login : false,
|
||
'NewValue' => sanitize_text_field( $new_address ),
|
||
'OldValue' => ( $is_first_edit ) ? esc_html__( 'Not supplied', 'wp-security-audit-log' ) : sanitize_text_field( $old_address ),
|
||
'EditUserLink' => add_query_arg( 'user_id', $user_id, \network_admin_url( 'user-edit.php' ) ),
|
||
'Roles' => is_array( $user->roles ) ? implode( ', ', $user->roles ) : $user->roles,
|
||
),
|
||
array(
|
||
__CLASS__,
|
||
'must_not_repeat_billing',
|
||
)
|
||
);
|
||
}
|
||
}
|
||
} elseif ( false !== strpos( (string) $meta_key, 'shipping_' ) ) {
|
||
$event_id = 9084;
|
||
|
||
$shipping_address_fields = array( 'shipping_first_name', 'shipping_last_name', 'shipping_company', 'shipping_country', 'shipping_address_1', 'shipping_address_2', 'shipping_city', 'shipping_state', 'shipping_postcode', 'shipping_phone' );
|
||
|
||
// We will fill this is as needed below.
|
||
$new_address_array = array();
|
||
|
||
foreach ( $shipping_address_fields as $field ) {
|
||
$field_value = get_user_meta( $user_id, $field, true );
|
||
$new_address_array[ $field ] = ( $meta_key === $field ) ? $meta_value : $field_value;
|
||
$old_address_array[ $field ] = $field_value;
|
||
}
|
||
|
||
// Replace old values we already have stored.
|
||
foreach ( self::$wc_user_meta as $user_meta ) {
|
||
$old_address_array[ $user_meta->key ] = $user_meta->value;
|
||
}
|
||
|
||
$new_address_array = array_filter( $new_address_array );
|
||
$old_address_array = array_filter( $old_address_array );
|
||
|
||
// Combine name fields to avoid weird comma.
|
||
if ( isset( $new_address_array['shipping_first_name'] ) && isset( $new_address_array['shipping_last_name'] ) ) {
|
||
$new_address_array['shipping_first_name'] = $new_address_array['shipping_first_name'] . ' ' . $new_address_array['shipping_last_name'];
|
||
unset( $new_address_array['shipping_last_name'] );
|
||
}
|
||
if ( isset( $old_address_array['shipping_first_name'] ) && isset( $old_address_array['shipping_last_name'] ) ) {
|
||
$old_address_array['shipping_first_name'] = $old_address_array['shipping_first_name'] . ' ' . $old_address_array['shipping_last_name'];
|
||
unset( $old_address_array['shipping_last_name'] );
|
||
}
|
||
|
||
// Turn them into a nice string.
|
||
$new_address = implode( ', ', $new_address_array );
|
||
$old_address = implode( ', ', $old_address_array );
|
||
|
||
if ( $event_id ) {
|
||
$user = get_user_by( 'ID', $user_id );
|
||
|
||
if ( 9084 === $event_id ) {
|
||
++self::$updated_shipping_field_count;
|
||
Alert_Manager::trigger_event_if(
|
||
$event_id,
|
||
array(
|
||
'TargetUsername' => $user ? $user->user_login : false,
|
||
'NewValue' => sanitize_text_field( $new_address ),
|
||
'OldValue' => ( $is_first_edit ) ? esc_html__( 'Not supplied', 'wp-security-audit-log' ) : sanitize_text_field( $old_address ),
|
||
'EditUserLink' => add_query_arg( 'user_id', $user_id, \network_admin_url( 'user-edit.php' ) ),
|
||
'Roles' => is_array( $user->roles ) ? implode( ', ', $user->roles ) : $user->roles,
|
||
),
|
||
array(
|
||
__CLASS__,
|
||
'must_not_repeat_shipping',
|
||
)
|
||
);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Check if is a repeated billing alert.
|
||
*
|
||
* @return bool - If was repeat or not.
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function must_not_repeat_billing() {
|
||
--self::$updated_field_count;
|
||
if ( 1 === self::$updated_field_count ) {
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* Check if is a repeated shipping alert.
|
||
*
|
||
* @return bool - If was repeat or not.
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function must_not_repeat_shipping() {
|
||
--self::$updated_shipping_field_count;
|
||
if ( 1 === self::$updated_shipping_field_count ) {
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* Trigger 9106 (stock level change by 3rd party).
|
||
*
|
||
* @since 3.3.1
|
||
*
|
||
* @param int $meta_id - ID of the metadata entry to update.
|
||
* @param int $object_id - Object ID.
|
||
* @param string $meta_key - Meta key.
|
||
* @param mixed $meta_value - Meta value.
|
||
*/
|
||
public static function detect_stock_level_change( $meta_id, $object_id, $meta_key, $meta_value ) {
|
||
if ( '_stock' === $meta_key ) {
|
||
$post = get_post( $object_id );
|
||
$editor_link = self::get_editor_link( $post );
|
||
$old_stock = get_post_meta( $object_id, '_stock', true );
|
||
$product_status = get_post_meta( $object_id, '_stock_status', true );
|
||
|
||
$new_stock = ( empty( $meta_value ) ) ? 0 : $meta_value;
|
||
$old_stock = ( ! empty( $old_stock ) ) ? $old_stock : 0;
|
||
|
||
Alert_Manager::trigger_event_if(
|
||
9106,
|
||
array(
|
||
'PostID' => $post->ID,
|
||
'SKU' => esc_attr( self::get_product_sku( $post->ID ) ),
|
||
'ProductTitle' => $post->post_title,
|
||
'ProductStatus' => ! $product_status ? $post->post_status : $product_status,
|
||
'OldValue' => $old_stock,
|
||
'NewValue' => $meta_value,
|
||
$editor_link['name'] => $editor_link['value'],
|
||
),
|
||
array( __CLASS__, 'must_not_edit_or_order' )
|
||
);
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Check WooCommerce product changes before save.
|
||
*
|
||
* Support for Admin Columns Pro plugin and its add-on.
|
||
*
|
||
* @param WC_Product $product - WooCommerce product object.
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function check_product_changes_before_save( $product, $data_store ) {
|
||
// If we reach here without any POST data, the change is beong done directly so lets update the old item data in case anything changes.
|
||
if ( ! isset( $_POST['action'] ) ) {
|
||
// Update held data.
|
||
$product_id = $product->get_id();
|
||
self::$old_product = wc_get_product( $product_id );
|
||
self::$old_post = get_post( $product_id );
|
||
self::$old_data = self::get_product_data( self::$old_product );
|
||
self::$_old_meta_data = get_post_meta( $product_id, '', false );
|
||
}
|
||
|
||
if ( isset( $_POST['_ajax_nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['_ajax_nonce'] ) ), 'ac-ajax' ) || isset( $_REQUEST['rest_route'] ) && ( '/wc/v3/products/batch' === $_REQUEST['rest_route'] ) ) {
|
||
// Get product data.
|
||
$product_id = $product->get_id();
|
||
$old_product = wc_get_product( $product_id );
|
||
$old_product_post = get_post( $product_id );
|
||
|
||
// Check for stock quantity changes.
|
||
self::check_stock_quantity_change( $old_product_post, $old_product->get_stock_quantity(), $product->get_stock_quantity() );
|
||
}
|
||
|
||
if ( isset( $_REQUEST['action'] ) && ( 'woocommerce_feature_product' === $_REQUEST['action'] ) && check_admin_referer( 'woocommerce-feature-product' ) ) {
|
||
$product_id = $product->get_id();
|
||
$product_post = get_post( $product_id );
|
||
$editor_link = self::get_editor_link( $product_post );
|
||
Alert_Manager::trigger_event(
|
||
9043,
|
||
array(
|
||
'PostID' => esc_attr( $product->get_id() ),
|
||
'SKU' => esc_attr( self::get_product_sku( $product_id ) ),
|
||
'ProductTitle' => sanitize_text_field( $product_post->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $product_post->post_status ),
|
||
'EventType' => $product->get_featured() ? 'enabled' : 'disabled',
|
||
$editor_link['name'] => $editor_link['value'],
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Ensure not a repated order event.
|
||
*
|
||
* @return bool - If was repeated or not.
|
||
*
|
||
* @since 4.6.0
|
||
*/
|
||
public static function must_not_edit_or_order() {
|
||
if ( Alert_Manager::will_or_has_triggered( 9019 ) ) {
|
||
return false;
|
||
}
|
||
if ( Alert_Manager::will_or_has_triggered( 9018 ) ) {
|
||
return false;
|
||
}
|
||
if ( Alert_Manager::will_or_has_triggered( 9105 ) ) {
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
// 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();
|
||
*/
|