2792 lines
103 KiB
PHP
2792 lines
103 KiB
PHP
<?php
|
||
/**
|
||
* Sensor: WooCommerce
|
||
*
|
||
* WooCommerce sensor file.
|
||
*
|
||
* @package Wsal
|
||
*/
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace WSAL\WP_Sensors_Helpers;
|
||
|
||
use WC_Product;
|
||
use WSAL\Helpers\User_Helper;
|
||
use WSAL\Controllers\Alert_Manager;
|
||
use WSAL\WP_Sensors\WooCommerce_Sensor;
|
||
use WSAL\WP_Sensors\Helpers\Woocommerce_Helper;
|
||
|
||
// Exit if accessed directly.
|
||
if ( ! defined( 'ABSPATH' ) ) {
|
||
exit;
|
||
}
|
||
|
||
if ( ! class_exists( '\WSAL\Plugin_Sensors\WooCommerce_Sensor_Helper_Second' ) ) {
|
||
|
||
/**
|
||
* Support for WooCommerce Plugin.
|
||
*
|
||
* @package Wsal
|
||
*/
|
||
class WooCommerce_Sensor_Helper_Second {
|
||
|
||
/**
|
||
* 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;
|
||
|
||
/**
|
||
* 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;
|
||
|
||
/**
|
||
* 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
|
||
*/
|
||
public 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(),
|
||
'sold_individually' => $product->get_sold_individually(),
|
||
'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
|
||
*/
|
||
public 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
|
||
*/
|
||
public 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
|
||
*/
|
||
public static function get_editor_link( $post ) {
|
||
|
||
$post_type = '';
|
||
|
||
if ( ! isset( $post ) ) {
|
||
$editor_link = array(
|
||
'name' => '', // Meta key.
|
||
'value' => '', // Meta value.
|
||
);
|
||
|
||
return $editor_link;
|
||
}
|
||
|
||
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'] ) ? \sanitize_text_field( \wp_unslash( $server_array['SCRIPT_NAME'] ) ) . '?post=' . $product->ID : false;
|
||
|
||
if ( ! empty( $server_array['HTTP_REFERER'] )
|
||
&& ! empty( $current_path )
|
||
&& 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_recently( 9000 ) ) & ! Alert_Manager::was_triggered( 9001 ) ) {
|
||
$editor_link = self::get_editor_link( $product );
|
||
Alert_Manager::trigger_event_if(
|
||
$event,
|
||
array(
|
||
'PostID' => esc_attr( $product->ID ),
|
||
'SKU' => esc_attr( WooCommerce_Sensor::get_product_sku( $product->ID ) ),
|
||
'ProductStatus' => sanitize_text_field( $product->post_status ),
|
||
'PostStatus' => 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
|
||
*/
|
||
public static function get_currency_symbol( $currency = '' ) {
|
||
$symbols = \get_woocommerce_currency_symbols();
|
||
$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 ) {
|
||
$edit_link = self::get_editor_link( $order );
|
||
$event_data = array(
|
||
'OrderID' => \esc_attr( $order_id ),
|
||
'OrderTitle' => \sanitize_text_field( Woocommerce_Helper::wsal_woocommerce_extension_get_order_title( $order ) ),
|
||
'OrderStatus' => \wc_get_order_status_name( $status_to ),
|
||
'OrderStatusSlug' => \sanitize_text_field( $status_to ),
|
||
'PostStatus' => 'wc-' . $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' => WooCommerce_Sensor::get_product_sku( $product->get_id() ),
|
||
'OrderStatus' => \wc_get_order_status_name( $order_post->get_status() ),
|
||
'OrderStatusSlug' => $order_post->get_status(),
|
||
'PostStatus' => 'wc-' . $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' => \wc_get_order_status_name( $order_post->get_status() ),
|
||
'OrderStatusSlug' => $order_post->get_status(),
|
||
'PostStatus' => 'wc-' . $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' => \wc_get_order_status_name( $order_post->get_status() ),
|
||
'OrderStatusSlug' => $order_post->get_status(),
|
||
'PostStatus' => 'wc-' . $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' => \wc_get_order_status_name( $order_post->get_status() ),
|
||
'OrderStatusSlug' => $order_post->get_status(),
|
||
'PostStatus' => 'wc-' . $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' => \wc_get_order_status_name( $order_post->get_status() ),
|
||
'OrderStatusSlug' => $order_post->get_status(),
|
||
'PostStatus' => 'wc-' . $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 ( $order instanceof \WC_Order || $order instanceof \WC_Order_Refund ) {
|
||
if ( isset( $order->get_items()[ $item_id ] ) ) {
|
||
$item = $order->get_items()[ $item_id ];
|
||
|
||
if ( ! $item instanceof \WC_Order_Item_Product ) {
|
||
return;
|
||
}
|
||
|
||
$product = $item->get_product();
|
||
|
||
if ( $product instanceof WC_Product ) {
|
||
$product_name = $product->get_name();
|
||
$product_id = $product->get_id();
|
||
} else {
|
||
$product_name = $item->get_name();
|
||
$product_id = $item->get_product_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_name,
|
||
'ProductID' => $product_id,
|
||
'SKU' => WooCommerce_Sensor::get_product_sku( $product_id ),
|
||
'OrderStatus' => \wc_get_order_status_name( $order_post->get_status() ),
|
||
'OrderStatusSlug' => $order_post->get_status(),
|
||
'PostStatus' => 'wc-' . $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' => \wc_get_order_status_name( $order_post->get_status() ),
|
||
'OrderStatusSlug' => $order_post->get_status(),
|
||
'PostStatus' => 'wc-' . $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' => \wc_get_order_status_name( $order_post->get_status() ),
|
||
'OrderStatusSlug' => $order_post->get_status(),
|
||
'PostStatus' => 'wc-' . $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' => \wc_get_order_status_name( $order_post->get_status() ),
|
||
'OrderStatusSlug' => $order_post->get_status(),
|
||
'PostStatus' => 'wc-' . $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' => \wc_get_order_status_name( $order_post->get_status() ),
|
||
'OrderStatusSlug' => $order_post->get_status(),
|
||
'PostStatus' => 'wc-' . $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 ( $product instanceof WC_Product ) {
|
||
$product_name = $product->get_name();
|
||
$product_id = $product->get_id();
|
||
} else {
|
||
$product_name = $item->get_name();
|
||
$product_id = $item->get_product_id();
|
||
}
|
||
|
||
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_id,
|
||
'SKU' => WooCommerce_Sensor::get_product_sku( $product_id ),
|
||
'NewQuantity' => $output[ 'order_item_qty' . $item_id ],
|
||
'OldQuantity' => $old_quantity,
|
||
'ProductTitle' => $product_name,
|
||
'OrderStatus' => \wc_get_order_status_name( $order_post->get_status() ),
|
||
'OrderStatusSlug' => $order_post->get_status(),
|
||
'PostStatus' => 'wc-' . $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 ( isset( $output[ 'line_total' . $item_id ] ) && 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' => \wc_get_order_status_name( $order_post->get_status() ),
|
||
'OrderStatusSlug' => $order_post->get_status(),
|
||
'PostStatus' => 'wc-' . $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::has_triggered( 9040 ) ) {
|
||
return false;
|
||
}
|
||
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.
|
||
*/
|
||
public 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 );
|
||
$new_order = \wc_get_order( $neworder->ID );
|
||
$items = $order->get_items( array( 'fee' ) );
|
||
|
||
self::event_order_items_quantity_changed( $order_id, $items );
|
||
|
||
$difference = self::order_recursive_array_diff( (array) WooCommerce_Sensor::get_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' => \wc_get_order_status_name( $new_order->get_status() ),
|
||
'OrderStatusSlug' => \sanitize_text_field( $new_order->get_status() ),
|
||
'PostStatus' => 'wc-' . $order->get_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, (array) $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' => \wc_get_order_status_name( $order_post->get_status() ),
|
||
'OrderStatusSlug' => $order_post->get_status(),
|
||
'PostStatus' => 'wc-' . $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' => \wc_get_order_status_name( $order_obj->get_status() ),
|
||
'OrderStatusSlug' => $order_obj->get_status(),
|
||
'PostStatus' => 'wc-' . $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' => \wc_get_order_status_name( $order_obj->post_status ),
|
||
'OrderStatusSlug' => sanitize_text_field( $order_obj->post_status ),
|
||
'PostStatus' => 'wc-' . $order_obj->get_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
|
||
*/
|
||
public static function retrieve_attribute_data() {
|
||
$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;
|
||
|
||
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.
|
||
WooCommerce_Sensor::set_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( WooCommerce_Sensor::get_old_attr_data()->name ) && WooCommerce_Sensor::get_old_attr_data()->name !== $data['attribute_label'] ) {
|
||
$attr_event = self::get_attribute_event_data( $id, $data );
|
||
$attr_event['OldName'] = WooCommerce_Sensor::get_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( WooCommerce_Sensor::get_old_attr_data()->order_by ) && WooCommerce_Sensor::get_old_attr_data()->order_by !== $data['attribute_orderby'] ) {
|
||
|
||
$attr_event = self::get_attribute_event_data( $id, $data );
|
||
|
||
// Get user data.
|
||
if ( ! \is_user_logged_in() ) {
|
||
$attr_event['Username'] = 'Unregistered user';
|
||
$v['CurrentUserID'] = 0;
|
||
} else {
|
||
$attr_event['Username'] = User_Helper::get_current_user()->user_login;
|
||
$attr_event['CurrentUserID'] = User_Helper::get_current_user()->ID;
|
||
}
|
||
$attr_event['OldSortOrder'] = WooCommerce_Sensor::get_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( WooCommerce_Sensor::get_old_attr_data()->has_archives ) && (int) WooCommerce_Sensor::get_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
|
||
*/
|
||
public 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() {
|
||
$action = isset( $_POST['action'] ) ? sanitize_text_field( wp_unslash( $_POST['action'] ) ) : false;
|
||
$is_data = isset( $_POST['data'] ) ? true : false;
|
||
|
||
// 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.
|
||
parse_str( $_POST['data'], $data ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||
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() ? \wc_get_order_status_name( $order->get_status() ) : false,
|
||
'OrderStatusSlug' => $order->get_status(),
|
||
'PostStatus' => 'wc-' . $order->get_status(),
|
||
$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( WooCommerce_Sensor::get_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', WooCommerce_Sensor::get_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() ? \wc_get_order_status_name( $order->get_status() ) : false,
|
||
'OrderStatusSlug' => $order->get_status(),
|
||
'PostStatus' => 'wc-' . $order->get_status(),
|
||
$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
|
||
*/
|
||
public 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' => WooCommerce_Sensor::get_product_sku( $product_id ),
|
||
'ProductTitle' => sanitize_text_field( $title ),
|
||
'ProductStatus' => sanitize_text_field( $status ),
|
||
'PostStatus' => 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' => WooCommerce_Sensor::get_product_sku( $product_id ),
|
||
'ProductTitle' => sanitize_text_field( $title ),
|
||
'ProductStatus' => sanitize_text_field( $status ),
|
||
'PostStatus' => 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' => WooCommerce_Sensor::get_product_sku( $product_id ),
|
||
'ProductTitle' => sanitize_text_field( $title ),
|
||
'ProductStatus' => sanitize_text_field( $status ),
|
||
'PostStatus' => 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' => WooCommerce_Sensor::get_product_sku( $product_id ),
|
||
'ProductTitle' => sanitize_text_field( $title ),
|
||
'ProductStatus' => sanitize_text_field( $status ),
|
||
'PostStatus' => 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' => WooCommerce_Sensor::get_product_sku( $product_id ),
|
||
'ProductTitle' => sanitize_text_field( $title ),
|
||
'ProductStatus' => sanitize_text_field( $status ),
|
||
'PostStatus' => 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
|
||
*/
|
||
public static function check_image_change( $oldpost, $data = false ) {
|
||
|
||
if ( ! $data ) {
|
||
$data = array_map( 'sanitize_text_field', wp_unslash( $_POST ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
|
||
}
|
||
|
||
if ( ! isset( $data['_thumbnail_id'] ) ) {
|
||
return 0;
|
||
}
|
||
|
||
// Setup our variables.
|
||
$thumb_id = get_post_thumbnail_id( $oldpost->ID );
|
||
$old_attachment_metadata = Woocommerce_Sensor::get_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['PostStatus'] = sanitize_text_field( $oldpost->post_status );
|
||
$event_data['SKU'] = WooCommerce_Sensor::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'] = ( isset( $attachment_metadata['file'] ) && ! empty( $attachment_metadata['file'] ) ) ? basename( $attachment_metadata['file'] ) : __( 'File is missing', 'wp-security-audit-log' );
|
||
$event_data['path'] = ( isset( $attachment_metadata['file'] ) && ! empty( $attachment_metadata['file'] ) ) ? $get_upload_dir['basedir'] . DIRECTORY_SEPARATOR . $attachment_metadata['file'] : __( 'File is missing', 'wp-security-audit-log' );
|
||
$alert_needed = true;
|
||
}
|
||
|
||
// Featued image removed.
|
||
if ( empty( $attachment_metadata ) && ! empty( $old_attachment_metadata ) ) {
|
||
$event_data['EventType'] = 'deleted';
|
||
$event_data['name'] = ( isset( $old_attachment_metadata['file'] ) && ! empty( $old_attachment_metadata['file'] ) ) ? basename( $old_attachment_metadata['file'] ) : __( 'File is missing', 'wp-security-audit-log' );
|
||
$event_data['path'] = ( isset( $old_attachment_metadata['file'] ) && ! empty( $old_attachment_metadata['file'] ) ) ? $get_upload_dir['basedir'] . DIRECTORY_SEPARATOR . $old_attachment_metadata['file'] : __( 'File is missing', 'wp-security-audit-log' );
|
||
$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'] = ( isset( $old_attachment_metadata['file'] ) && ! empty( $old_attachment_metadata['file'] ) ) ? basename( $old_attachment_metadata['file'] ) : __( 'File is missing', 'wp-security-audit-log' );
|
||
$event_data['old_path'] = ( isset( $old_attachment_metadata['file'] ) && ! empty( $old_attachment_metadata['file'] ) ) ? $get_upload_dir['basedir'] . DIRECTORY_SEPARATOR . $old_attachment_metadata['file'] : __( 'File is missing', 'wp-security-audit-log' );
|
||
$event_data['name'] = ( isset( $attachment_metadata['file'] ) && ! empty( $attachment_metadata['file'] ) ) ? basename( $attachment_metadata['file'] ) : __( 'File is missing', 'wp-security-audit-log' );
|
||
$event_data['path'] = ( isset( $attachment_metadata['file'] ) && ! empty( $attachment_metadata['file'] ) ) ? $get_upload_dir['basedir'] . DIRECTORY_SEPARATOR . $attachment_metadata['file'] : __( 'File is missing', 'wp-security-audit-log' );
|
||
$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
|
||
*/
|
||
public static function check_download_limit_change( $oldpost, $data = false ) {
|
||
|
||
if ( ! $data ) {
|
||
$data = array_map( 'sanitize_text_field', wp_unslash( $_POST ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
|
||
}
|
||
|
||
if ( ! isset( $data['_download_expiry'] ) || ! isset( $data['_download_limit'] ) ) {
|
||
return 0;
|
||
}
|
||
|
||
$event_id = false;
|
||
$editor_link = self::get_editor_link( WooCommerce_Sensor::get_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'] ) ?? '';
|
||
$event_data['PostStatus'] = ( $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'] = WooCommerce_Sensor::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'] = WooCommerce_Sensor::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
|
||
*/
|
||
public 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( WooCommerce_Sensor::get_product_sku( $product->ID ) ),
|
||
'ProductTitle' => $product->post_title,
|
||
'ProductStatus' => $product->post_status,
|
||
'PostStatus' => $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( WooCommerce_Sensor::get_product_sku( $product->ID ) ),
|
||
'ProductTitle' => $product->post_title,
|
||
'ProductStatus' => $product->post_status,
|
||
'PostStatus' => $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
|
||
* @since 5.6.0 - Fixed false positives when old and new values are the same. This caused event 9119 to trigger unnecessarily.
|
||
*/
|
||
public static function check_low_stock_threshold_change( $product, $oldpost, $post ) {
|
||
// Get raw values, note: empty string means store default.
|
||
$old_raw = $oldpost['_low_stock_amount'][0] ?? '';
|
||
$new_raw = $post['low_stock_amount'] ?? '';
|
||
|
||
// Normalize for comparison: empty = null (store default), otherwise cast to int.
|
||
$old_normalized = ( '' === $old_raw || '' === trim( (string) $old_raw ) ) ? null : (int) $old_raw;
|
||
$new_normalized = ( '' === $new_raw || '' === trim( (string) $new_raw ) ) ? null : (int) $new_raw;
|
||
|
||
// Return early if we don't have a change.
|
||
if ( $old_normalized === $new_normalized ) {
|
||
return;
|
||
}
|
||
|
||
$store_default_label = \esc_html__( 'Store Default', 'wp-security-audit-log' );
|
||
|
||
$old_status = null === $old_normalized ? $store_default_label : (string) $old_normalized;
|
||
$new_status = null === $new_normalized ? $store_default_label : (string) $new_normalized;
|
||
|
||
$editor_link = self::get_editor_link( $product );
|
||
|
||
Alert_Manager::trigger_event(
|
||
9119,
|
||
array(
|
||
'PostID' => $product->ID,
|
||
'SKU' => \esc_attr( WooCommerce_Sensor::get_product_sku( $product->ID ) ),
|
||
'ProductTitle' => $product->post_title,
|
||
'ProductStatus' => $product->post_status,
|
||
'PostStatus' => $product->post_status,
|
||
'old_low_stock_amount' => $old_status,
|
||
'new_low_stock_amount' => $new_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
|
||
*/
|
||
public static function check_variations_change( $oldpost, $data = false ) {
|
||
if ( ! $data ) {
|
||
$data = array_map( 'sanitize_text_field', wp_unslash( $_POST ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||
}
|
||
|
||
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 = WooCommerce_Sensor_Helper::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 = WooCommerce_Sensor_Helper::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 = WooCommerce_Sensor_Helper::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 = WooCommerce_Sensor_Helper::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 = WooCommerce_Sensor_Helper::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 = WooCommerce_Sensor_Helper::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 = WooCommerce_Sensor_Helper::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 = WooCommerce_Sensor_Helper::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;
|
||
WooCommerce_Sensor_Helper::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() );
|
||
}
|
||
WooCommerce_Sensor_Helper::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;
|
||
WooCommerce_Sensor_Helper::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
|
||
*/
|
||
public 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
|
||
*/
|
||
public 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
|
||
*/
|
||
public 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, Woocommerce_Sensor::get_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, Woocommerce_Sensor::get_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 = WooCommerce_Sensor::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( WooCommerce_Sensor::get_old_meta_data()[ $meta_key ][0] ) ? WooCommerce_Sensor::get_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, Woocommerce_Sensor::get_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;
|
||
}
|
||
|
||
Woocommerce_Sensor::set_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( Woocommerce_Sensor::get_wc_user_meta()[ $meta_id ] ) || ! is_object( Woocommerce_Sensor::get_wc_user_meta()[ $meta_id ] ) ) {
|
||
Woocommerce_Sensor::get_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;
|
||
}
|
||
|
||
if ( isset( Woocommerce_Sensor::get_wc_user_meta()[ $meta_id ] ) ) {
|
||
$current_value = get_user_meta( $user_id, Woocommerce_Sensor::get_wc_user_meta()[ $meta_id ]->key, true );
|
||
}
|
||
|
||
if ( isset( Woocommerce_Sensor::get_wc_user_meta()[ $meta_id ] ) && Woocommerce_Sensor::get_wc_user_meta()[ $meta_id ]->value !== $current_value ) {
|
||
if ( Woocommerce_Sensor::get_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 ( Woocommerce_Sensor::get_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 ( Woocommerce_Sensor::get_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 - Post ID.
|
||
* @param string $meta_key - Meta key.
|
||
* @param mixed $meta_value - Meta value. This will be a PHP-serialized string representation of the value if the value is an array, an object, or itself a PHP-serialized string.
|
||
*/
|
||
public static function detect_stock_level_change( $meta_id, $object_id, $meta_key, $meta_value ) {
|
||
if ( '_stock' === $meta_key ) {
|
||
$post = get_post( $object_id );
|
||
|
||
if ( ! $post || ! isset( $post->ID ) ) {
|
||
return;
|
||
}
|
||
|
||
$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( WooCommerce_Sensor::get_product_sku( $post->ID ) ),
|
||
'ProductTitle' => $post->post_title ?? \esc_html__( 'No product title found', 'wp-security-audit-log' ),
|
||
'ProductStatus' => ! $product_status ? $post->post_status : $product_status,
|
||
'PostStatus' => ! $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.
|
||
* @param array $data_store - Data store array.
|
||
*
|
||
* @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();
|
||
WooCommerce_Sensor::set_old_product( wc_get_product( $product_id ) );
|
||
WooCommerce_Sensor::set_old_post( get_post( $product_id ) );
|
||
WooCommerce_Sensor::set_old_data( self::get_product_data( WooCommerce_Sensor::get_old_product() ) );
|
||
WooCommerce_Sensor::set_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.
|
||
WooCommerce_Sensor_Helper::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( WooCommerce_Sensor::get_product_sku( $product_id ) ),
|
||
'ProductTitle' => sanitize_text_field( $product_post->post_title ),
|
||
'ProductStatus' => sanitize_text_field( $product_post->post_status ),
|
||
'PostStatus' => 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();
|
||
*/
|