<?php
/**
 * Privacy class; added to let customer export personal data
 *
 * @author  YITH <plugins@yithemes.com>
 * @package YITH\Affiliates\Classes
 * @version 1.2.5
 */

if ( ! defined( 'YITH_WCAF' ) ) {
	exit;
} // Exit if accessed directly

if ( ! class_exists( 'YITH_WCAF_Privacy' ) ) {
	/**
	 * YITH WCAF Privacy
	 *
	 * @since 1.2.5
	 */
	class YITH_WCAF_Privacy extends YITH_Privacy_Plugin_Abstract {

		/**
		 * Constructor method
		 *
		 * @since 1.2.5
		 */
		public function __construct() {
			parent::__construct( 'YITH WooCommerce Affiliates' );

			// set up affiliates data exporter.
			add_filter( 'wp_privacy_personal_data_exporters', array( $this, 'register_exporter' ) );

			// set up affiliates data eraser.
			add_filter( 'wp_privacy_personal_data_erasers', array( $this, 'register_eraser' ) );
		}

		/**
		 * Retrieves privacy example text for affiliates plugin
		 *
		 * @param string $section Section of the message.
		 *
		 * @return string Privacy message
		 * @since 1.2.5
		 */
		public function get_privacy_message( $section ) {
			$content = '';

			switch ( $section ) {
				case 'collect_and_store':
					$content = '<p>' . _x( 'While you visit our site, we\'ll track:', '[PRIVACY] Privacy message', 'yith-woocommerce-affiliates' ) . '</p>' .
						'<ul>' .
						'<li>' . _x( 'Visits to the store: we\'ll use this to generate statistics for affiliates and administrators.', '[PRIVACY] Privacy message', 'yith-woocommerce-affiliates' ) . '</li>' .
						'<li>' . _x( 'Location, IP address and browser type: we\'ll use this just for statistics, and to let administrators supervise traffic generated by affiliates.', '[PRIVACY] Privacy message', 'yith-woocommerce-affiliates' ) . '</li>' .
						'<li>' . _x( 'Affiliate\'s name, username, email address: we\'ll use this information to register and keep track of affiliates.', '[PRIVACY] Privacy message', 'yith-woocommerce-affiliates' ) . '</li>' .
						'</ul>' .
						'<p>' . _x( 'We\'ll also use cookies to keep track of visits and sales generated by affiliates.', '[PRIVACY] Privacy message', 'yith-woocommerce-affiliates' ) . '</p>';
					break;
				case 'has_access':
					$content = '<p>' . _x( 'Members of our team have access to the information you provide us. For example, both Administrators and Shop Managers can access:', '[PRIVACY] Privacy message', 'yith-woocommerce-affiliates' ) . '</p>' .
						'<ul>' .
						'<li>' . _x( 'Affiliates\' personal details;', '[PRIVACY] Privacy message', 'yith-woocommerce-affiliates' ) . '</li>' .
						'<li>' . _x( 'System-generated commissions;', '[PRIVACY] Privacy message', 'yith-woocommerce-affiliates' ) . '</li>' .
						'<li>' . _x( 'Payments sent to the affiliates;', '[PRIVACY] Privacy message', 'yith-woocommerce-affiliates' ) . '</li>' .
						'<li>' . _x( 'Visits and sales generated through the referral links.', '[PRIVACY] Privacy message', 'yith-woocommerce-affiliates' ) . '</li>' .
						'</ul>' .
						'<p>' . _x( 'Our team members have access to this information to correctly manage the affiliation system, and perform the required actions in order to prevent customers from any inappropriate usage of the affiliate program.', '[PRIVACY] Privacy message', 'yith-woocommerce-affiliates' ) . '</p>';
					break;
				case 'share':
					$content = '<p>' . _x( 'We send payments through PayPal. When processing payments, some of your data will be passed to PayPal, including information required to process or support the payment, such as the commission total and payment information.', '[PRIVACY] Privacy message', 'yith-woocommerce-affiliates' ) . '</p>' .
						'<p>' . _x( 'Please see the <a href="https://www.paypal.com/us/webapps/mpp/ua/privacy-full">PayPal Privacy Policy</a> for more details.', '[PRIVACY] Privacy message', 'yith-woocommerce-affiliates' ) . '</p>';
					break;
				case 'payments':
				default:
					break;
			}

			/**
			 * APPLY_FILTERS: yith_wcaf_privacy_policy_content
			 *
			 * Filter the content of the privacy policy.
			 *
			 * @param string $content Privacy policy content
			 * @param string $section Privacy policy section
			 *
			 * @return string
			 */
			return apply_filters( 'yith_wcaf_privacy_policy_content', $content, $section );
		}

		/**
		 * Register exporters for affiliates plugin
		 *
		 * @param array $exporters Array of currently registered exporters.
		 *
		 * @return array Array of filtered exporters
		 * @since 1.2.5
		 */
		public function register_exporter( $exporters ) {

			// exports data about affiliate, and overall activity on the site.
			$exporters['yith_wcaf_affiliate_details'] = array(
				'exporter_friendly_name' => _x( 'Affiliate Data', '[PRIVACY] Exporter name', 'yith-woocommerce-affiliates' ),
				'callback'               => array( $this, 'affiliate_exporter' ),
			);

			// exports affiliate's commissions.
			/**
			 * APPLY_FILTERS: yith_wcaf_privacy_export_commissions
			 *
			 * Filters whether to register the commissions exporter.
			 *
			 * @param bool $register_exporter Whether to register commissions exporter or not.
			 */
			if ( apply_filters( 'yith_wcaf_privacy_export_commissions', false ) ) {
				$exporters['yith_wcaf_commissions'] = array(
					'exporter_friendly_name' => _x( 'Affiliate Commissions', '[PRIVACY] Exporter name', 'yith-woocommerce-affiliates' ),
					'callback'               => array( $this, 'commissions_exporter' ),
				);
			}

			// exports affiliate's payments.
			/**
			 * APPLY_FILTERS: yith_wcaf_privacy_export_payments
			 *
			 * Filters whether to register the payments exporter.
			 *
			 * @param bool $register_exporter Whether to register payments exporter or not.
			 */
			if ( apply_filters( 'yith_wcaf_privacy_export_payments', false ) ) {
				$exporters['yith_wcaf_payments'] = array(
					'exporter_friendly_name' => _x( 'Affiliate Payments', '[PRIVACY] Exporter name', 'yith-woocommerce-affiliates' ),
					'callback'               => array( $this, 'payments_exporter' ),
				);
			}

			// exports affiliate's clicks.
			/**
			 * APPLY_FILTERS: yith_wcaf_privacy_export_clicks
			 *
			 * Filters whether to register the clicks exporter.
			 *
			 * @param bool $register_exporter Whether to register clicks exporter or not.
			 */
			if ( apply_filters( 'yith_wcaf_privacy_export_clicks', false ) ) {
				$exporters['yith_wcaf_clicks'] = array(
					'exporter_friendly_name' => _x( 'Affiliate Visits', '[PRIVACY] Exporter name', 'yith-woocommerce-affiliates' ),
					'callback'               => array( $this, 'clicks_exporter' ),
				);
			}

			return $exporters;
		}

		/**
		 * Register eraser for affiliate plugin
		 *
		 * @param array $erasers Array of currently registered erasers.
		 *
		 * @return array Array of filtered erasers
		 * @since 1.2.5
		 */
		public function register_eraser( $erasers ) {
			// erases data about affiliate, and overall activity on the site.
			$erasers['yith_wcaf_affiliate_details'] = array(
				'eraser_friendly_name' => _x( 'Affiliate Data', '[PRIVACY] Eraser name', 'yith-woocommerce-affiliates' ),
				'callback'             => array( $this, 'affiliate_eraser' ),
			);

			// erases affiliate's payments.
			/**
			 * APPLY_FILTERS: yith_wcaf_privacy_erase_payments
			 *
			 * Filters whether to register the payments eraser.
			 *
			 * @param bool $register_eraser Whether to register payments eraser or not.
			 */
			if ( apply_filters( 'yith_wcaf_privacy_erase_payments', false ) ) {
				$erasers['yith_wcaf_payments'] = array(
					'eraser_friendly_name' => _x( 'Affiliate Payments', '[PRIVACY] Eraser name', 'yith-woocommerce-affiliates' ),
					'callback'             => array( $this, 'payments_eraser' ),
				);
			}

			// erases affiliate's clicks.
			/**
			 * APPLY_FILTERS: yith_wcaf_privacy_erase_clicks
			 *
			 * Filters whether to register the clicks eraser.
			 *
			 * @param bool $register_eraser Whether to register clicks eraser or not.
			 */
			if ( apply_filters( 'yith_wcaf_privacy_erase_clicks', false ) ) {
				$erasers['yith_wcaf_clicks'] = array(
					'eraser_friendly_name' => _x( 'Affiliate Visits', '[PRIVACY] Eraser name', 'yith-woocommerce-affiliates' ),
					'callback'             => array( $this, 'clicks_eraser' ),
				);
			}

			return $erasers;
		}

		/**
		 * Export affiliate details
		 *
		 * @param string $email_address Email of the users that requested export.
		 *
		 * @return array Array of data to export
		 * @since 1.2.5
		 */
		public function affiliate_exporter( $email_address ) {
			$user     = get_user_by( 'email', $email_address ); // Check if user has an ID in the DB to load stored personal data.
			$response = array(
				'data' => array(),
				'done' => true,
			);

			if ( ! $user instanceof WP_User ) {
				return $response;
			}

			$affiliate = YITH_WCAF_Affiliate_Factory::get_affiliate_by_user_id( $user->ID );

			if ( ! $affiliate ) {
				return $response;
			}

			/**
			 * APPLY_FILTERS: yith_wcaf_privacy_export_affiliate_personal_data_props
			 *
			 * Filters the affiliate's personal data props to export.
			 *
			 * @param array $data_to_export Personal data to export.
			 */
			$props_to_export = apply_filters(
				'yith_wcaf_privacy_export_affiliate_personal_data_props',
				array(
					'referral_link' => _x( 'Referral link', '[PRIVACY] Exporter property', 'yith-woocommerce-affiliates' ),
					'token'         => _x( 'Token', '[PRIVACY] Exporter property', 'yith-woocommerce-affiliates' ),
					'earnings'      => _x( 'Commissions earned', '[PRIVACY] Exporter property', 'yith-woocommerce-affiliates' ),
					'paid'          => _x( 'Total paid', '[PRIVACY] Exporter property', 'yith-woocommerce-affiliates' ),
					'click'         => _x( 'Total visits', '[PRIVACY] Exporter property', 'yith-woocommerce-affiliates' ),
					'conversions'   => _x( 'Total conversions', '[PRIVACY] Exporter property', 'yith-woocommerce-affiliates' ),
					'meta_data'     => _x( 'Additional info', '[PRIVACY] Exporter property', 'yith-woocommerce-affiliates' ),
				)
			);

			$response['data'][] = array(
				'group_id'    => 'yith_wcwl_affiliate_data',
				'group_label' => _x( 'Affiliate Data', '[PRIVACY] Exporter label', 'yith-woocommerce-affiliates' ),
				'item_id'     => 'affiliate-' . $affiliate->get_id(),
				'data'        => $this->object_exporter( $affiliate, $props_to_export ),
			);

			return $response;
		}

		/**
		 * Export affiliate commissions
		 *
		 * @param string $email_address Email of the users that requested export.
		 * @param int    $page          Current page processed.
		 *
		 * @return array Array of data to export
		 * @since 1.2.5
		 */
		public function commissions_exporter( $email_address, $page = 1 ) {
			$page     = (int) $page;
			$offset   = 50 * ( $page - 1 );
			$user     = get_user_by( 'email', $email_address ); // Check if user has an ID in the DB to load stored personal data.
			$response = array(
				'data' => array(),
				'done' => true,
			);

			if ( ! $user instanceof WP_User ) {
				return $response;
			}

			$affiliate = YITH_WCAF_Affiliate_Factory::get_affiliate_by_user_id( $user->ID );

			if ( ! $affiliate ) {
				return $response;
			}

			$commissions = $affiliate->get_commissions(
				array(
					'limit'  => 50,
					'offset' => $offset,
				)
			);

			/**
			 * APPLY_FILTERS: yith_wcaf_privacy_export_commission_props
			 *
			 * Filters the commission props to export.
			 *
			 * @param array $commission_props Commission props to export.
			 */
			$props_to_export = apply_filters(
				'yith_wcaf_privacy_export_commission_props',
				array(
					'id'           => _x( 'ID', '[PRIVACY] Exporter property', 'yith-woocommerce-affiliates' ),
					'status'       => _x( 'Status', '[PRIVACY] Exporter property', 'yith-woocommerce-affiliates' ),
					'order_id'     => _x( 'Order id', '[PRIVACY] Exporter property', 'yith-woocommerce-affiliates' ),
					'product_name' => _x( 'Product', '[PRIVACY] Exporter property', 'yith-woocommerce-affiliates' ),
					'created_at'   => _x( 'Created on', '[PRIVACY] Exporter property', 'yith-woocommerce-affiliates' ),
					'amount'       => _x( 'Amount', '[PRIVACY] Exporter property', 'yith-woocommerce-affiliates' ),
				)
			);

			if ( 0 < count( $commissions ) ) {
				foreach ( $commissions as $commission ) {
					$response['data'][] = array(
						'group_id'    => 'yith_wcaf_commissions',
						'group_label' => _x( 'Affiliate Commissions', '[PRIVACY] Exporter label', 'yith-woocommerce-affiliates' ),
						'item_id'     => 'commission-' . $commission->get_id(),
						'data'        => $this->object_exporter( $commission, $props_to_export ),
					);
				}
				$response['done'] = ! $commissions->has_next_page();
			} else {
				$response['done'] = true;
			}

			return $response;
		}

		/**
		 * Export affiliate payments
		 *
		 * @param string $email_address Email of the users that requested export.
		 * @param int    $page          Current page processed.
		 *
		 * @return array Array of data to export
		 * @since 1.2.5
		 */
		public function payments_exporter( $email_address, $page = 1 ) {
			$page     = (int) $page;
			$offset   = 50 * ( $page - 1 );
			$user     = get_user_by( 'email', $email_address ); // Check if user has an ID in the DB to load stored personal data.
			$response = array(
				'data' => array(),
				'done' => true,
			);

			if ( ! $user instanceof WP_User ) {
				return $response;
			}

			$affiliate = YITH_WCAF_Affiliate_Factory::get_affiliate_by_user_id( $user->ID );

			if ( ! $affiliate ) {
				return $response;
			}

			$payments = $affiliate->get_payments(
				array(
					'limit'  => 50,
					'offset' => $offset,
				)
			);

			/**
			 * APPLY_FILTERS: yith_wcaf_privacy_export_payment_props
			 *
			 * Filters the payment props to export.
			 *
			 * @param array $payment_props Payment props to export.
			 */
			$props_to_export = apply_filters(
				'yith_wcaf_privacy_export_payment_props',
				array(
					'if'              => _x( 'ID', '[PRIVACY] Exporter property', 'yith-woocommerce-affiliates' ),
					'status'          => _x( 'Status', '[PRIVACY] Exporter property', 'yith-woocommerce-affiliates' ),
					'email'           => _x( 'Payment email', '[PRIVACY] Exporter property', 'yith-woocommerce-affiliates' ),
					'created_at'      => _x( 'Created on', '[PRIVACY] Exporter property', 'yith-woocommerce-affiliates' ),
					'completed_at'    => _x( 'Completed on', '[PRIVACY] Exporter property', 'yith-woocommerce-affiliates' ),
					'amount'          => _x( 'Amount', '[PRIVACY] Exporter property', 'yith-woocommerce-affiliates' ),
					'gateway'         => _x( 'Gateway', '[PRIVACY] Exporter property', 'yith-woocommerce-affiliates' ),
					'gateway_details' => _x( 'Gateway details', '[PRIVACY] Exporter property', 'yith-woocommerce-affiliates' ),

				)
			);

			if ( 0 < count( $payments ) ) {
				foreach ( $payments as $payment ) {
					$response['data'][] = array(
						'group_id'    => 'yith_wcaf_payments',
						'group_label' => _x( 'Affiliate Payments', '[PRIVACY] Exporter label', 'yith-woocommerce-affiliates' ),
						'item_id'     => 'payment-' . $payment->get_id(),
						'data'        => $this->object_exporter( $payment, $props_to_export ),
					);
				}
				$response['done'] = ! $payments->has_next_page();
			} else {
				$response['done'] = true;
			}

			return $response;
		}

		/**
		 * Export affiliate clicks
		 *
		 * @param string $email_address Email of the users that requested export.
		 * @param int    $page          Current page processed.
		 *
		 * @return array Array of data to export
		 * @since 1.2.5
		 */
		public function clicks_exporter( $email_address, $page = 1 ) {
			$page     = (int) $page;
			$offset   = 50 * ( $page - 1 );
			$user     = get_user_by( 'email', $email_address ); // Check if user has an ID in the DB to load stored personal data.
			$response = array(
				'data' => array(),
				'done' => true,
			);

			if ( ! $user instanceof WP_User ) {
				return $response;
			}

			$affiliate = YITH_WCAF_Affiliate_Factory::get_affiliate_by_user_id( $user->ID );

			if ( ! $affiliate ) {
				return $response;
			}

			$clicks = $affiliate->get_clicks(
				array(
					'limit'  => 50,
					'offset' => $offset,
				)
			);

			/**
			 * APPLY_FILTERS: yith_wcaf_privacy_export_click_props
			 *
			 * Filters the click props to export.
			 *
			 * @param array $click_props Click props to export.
			 */
			$props_to_export = apply_filters(
				'yith_wcaf_privacy_export_click_props',
				array(
					'id'         => _x( 'ID', '[PRIVACY] Exporter property', 'yith-woocommerce-affiliates' ),
					'link'       => _x( 'Link', '[PRIVACY] Exporter property', 'yith-woocommerce-affiliates' ),
					'origin'     => _x( 'Origin', '[PRIVACY] Exporter property', 'yith-woocommerce-affiliates' ),
					'click_date' => _x( 'Date', '[PRIVACY] Exporter property', 'yith-woocommerce-affiliates' ),
					'conv_date'  => _x( 'Converted on', '[PRIVACY] Exporter property', 'yith-woocommerce-affiliates' ),
				)
			);

			if ( 0 < count( $clicks ) ) {
				foreach ( $clicks as $click ) {
					$response['data'][] = array(
						'group_id'    => 'yith_wcaf_clicks',
						'group_label' => _x( 'Affiliate views', '[PRIVACY] Exporter label', 'yith-woocommerce-affiliates' ),
						'item_id'     => 'hit-' . $click->get_id(),
						'data'        => $this->object_exporter( $click, $props_to_export ),
					);
				}
				$response['done'] = ! $clicks->has_next_page();
			} else {
				$response['done'] = true;
			}

			return $response;
		}

		/**
		 * Erase affiliate personal details
		 *
		 * @param string $email_address Email of the users that requested export.
		 *
		 * @return array Result of the operation
		 */
		public function affiliate_eraser( $email_address ) {
			$user     = get_user_by( 'email', $email_address ); // Check if user has an ID in the DB to load stored personal data.
			$response = array(
				'items_removed'  => false,
				'items_retained' => false,
				'messages'       => array(),
				'done'           => true,
			);

			if ( ! $user instanceof WP_User ) {
				return $response;
			}

			$affiliate = YITH_WCAF_Affiliate_Factory::get_affiliate_by_user_id( $user->ID );

			if ( ! $affiliate ) {
				return $response;
			}

			/**
			 * APPLY_FILTERS: yith_wcaf_privacy_remove_affiliate_personal_data_props
			 *
			 * Filters the affiliate's personal data props to remove.
			 *
			 * @param array $data_to_remove Personal data to remove.
			 */
			$props_to_remove = apply_filters(
				'yith_wcaf_privacy_remove_affiliate_personal_data_props',
				array(
					'payment_email' => 'email',
					'token'         => 'text',
				)
			);

			$res = $this->object_eraser( $affiliate, $props_to_remove );

			if ( $res ) {
				$affiliate->get_data_store()->delete_all_meta( $affiliate );

				// translators: 1. Affiliate ID.
				$response['messages'][]    = sprintf( _x( 'Anonymized affiliate %s.', '[PRIVACY] Eraser message', 'yith-woocommerce-affiliates' ), $affiliate->get_id() );
				$response['items_removed'] = true;
			}

			return $response;
		}

		/**
		 * Erase affiliate's payments
		 *
		 * @param string $email_address Email of the users that requested export.
		 * @param int    $page          Current page processed.
		 *
		 * @return array Result of the operation
		 */
		public function payments_eraser( $email_address, $page = 1 ) {
			$page     = (int) $page;
			$offset   = 10 * ( $page - 1 );
			$user     = get_user_by( 'email', $email_address ); // Check if user has an ID in the DB to load stored personal data.
			$response = array(
				'items_removed'  => false,
				'items_retained' => false,
				'messages'       => array(),
				'done'           => true,
			);

			if ( ! $user instanceof WP_User ) {
				return $response;
			}

			$affiliate = YITH_WCAF_Affiliate_Factory::get_affiliate_by_user_id( $user->ID );

			if ( ! $affiliate ) {
				return $response;
			}

			$payments = $affiliate->get_payments(
				array(
					'limit'   => 10,
					'offset'  => $offset,
					'orderby' => 'ID',
					'order'   => 'ASC',
				)
			);

			/**
			 * APPLY_FILTERS: yith_wcaf_privacy_remove_payment_personal_data_props
			 *
			 * Filters the payment props to remove.
			 *
			 * @param array $payment_props Payment props to remove.
			 */
			$props_to_remove = apply_filters(
				'yith_wcaf_privacy_remove_payment_personal_data_props',
				array(
					'email'           => 'email',
					'gateway_details' => 'array',
				)
			);

			if ( 0 < count( $payments ) ) {
				foreach ( $payments as $payment ) {
					$res = $this->object_eraser( $payment, $props_to_remove );

					if ( $res ) {
						// Translators: 1. Payment id.
						$response['messages'][]    = sprintf( _x( 'Anonymized payment %s.', '[PRIVACY] Eraser message', 'yith-woocommerce-affiliates' ), $payment->get_id() );
						$response['items_removed'] = true;
					} else {
						// Translators: 1. Payment id.
						$response['messages'][]     = sprintf( _x( 'Payment %s has been retained.', '[PRIVACY] Eraser message', 'yith-woocommerce-affiliates' ), $payment->get_id() );
						$response['items_retained'] = true;
					}
				}
				$response['done'] = $payments->has_next_page();
			} else {
				$response['done'] = true;
			}

			return $response;
		}

		/**
		 * Erase affiliate's clicks
		 *
		 * @param string $email_address Email of the users that requested export.
		 * @param int    $page          Current page processed.
		 *
		 * @return array Result of the operation
		 */
		public function clicks_eraser( $email_address, $page = 1 ) {
			$page     = (int) $page;
			$offset   = 10 * ( $page - 1 );
			$user     = get_user_by( 'email', $email_address ); // Check if user has an ID in the DB to load stored personal data.
			$response = array(
				'items_removed'  => false,
				'items_retained' => false,
				'messages'       => array(),
				'done'           => true,
			);

			if ( ! $user instanceof WP_User ) {
				return $response;
			}

			$affiliate = YITH_WCAF_Affiliate_Factory::get_affiliate_by_user_id( $user->ID );

			if ( ! $affiliate ) {
				return $response;
			}

			$clicks = $affiliate->get_clicks(
				array(
					'limit'   => 10,
					'offset'  => $offset,
					'orderby' => 'ID',
					'order'   => 'ASC',
				)
			);

			/**
			 * APPLY_FILTERS: yith_wcaf_privacy_remove_click_personal_data_props
			 *
			 * Filters the click props to remove.
			 *
			 * @param array $click_props Click props to remove.
			 */
			$props_to_remove = apply_filters(
				'yith_wcaf_privacy_remove_click_personal_data_props',
				array(
					'link'        => 'url',
					'origin'      => 'url',
					'origin_base' => 'url',
					'ip'          => 'ip',
				)
			);

			if ( 0 < count( $clicks ) ) {
				foreach ( $clicks as $click ) {
					$res = $this->object_eraser( $click, $props_to_remove );

					if ( $res ) {
						// Translators: 1. Click ID.
						$response['messages'][]    = sprintf( _x( 'Anonymized hit %s.', '[PRIVACY] Eraser message', 'yith-woocommerce-affiliates' ), $click->get_id() );
						$response['items_removed'] = true;
					} else {
						// Translators: 1. Click ID.
						$response['messages'][]     = sprintf( _x( 'Visit %s has been retained.', '[PRIVACY] Eraser message', 'yith-woocommerce-affiliates' ), $click->get_id() );
						$response['items_retained'] = true;
					}
				}
				$response['done'] = $clicks->has_next_page();
			} else {
				$response['done'] = true;
			}

			return $response;
		}

		/**
		 * Retrieve data to export for a specific object
		 *
		 * @param YITH_WCAF_Abstract_Object $object          Object to export.
		 * @param array                     $props_to_export Props to export, in the form of an array of labels indexed by prop key.
		 *
		 * @return array Array of data ready to be exported.
		 */
		protected function object_exporter( $object, $props_to_export ) {
			$personal_data = array();

			foreach ( $props_to_export as $prop => $prop_name ) {
				$getter           = "get_$prop";
				$formatted_getter = "get_formatted_$prop";

				if ( ! method_exists( $object, $getter ) ) {
					continue;
				}

				if ( method_exists( $object, $formatted_getter ) ) {
					$value = $object->$formatted_getter();
				} else {
					$value = $object->$getter();
				}

				/**
				 * APPLY_FILTERS: yith_wcaf_privacy_export_object_prop
				 *
				 * Filters the object prop to export.
				 *
				 * @param string $value  Prop value to export.
				 * @param string $prop   Prop to export.
				 * @param object $object Object to export.
				 */
				$value = apply_filters( 'yith_wcaf_privacy_export_object_prop', $value, $prop, $object );

				if ( $value ) {
					$personal_data[] = array(
						'name'  => $prop_name,
						'value' => $this->serialize( $value ),
					);
				}
			}

			/**
			 * APPLY_FILTERS: yith_wcaf_privacy_export_object
			 *
			 * Filters the personal data of the object to export.
			 *
			 * @param array  $personal_data Personal data to export.
			 * @param object $object        Object to export.
			 */
			$personal_data = apply_filters( 'yith_wcaf_privacy_export_object', $personal_data, $object );

			return $personal_data;
		}

		/**
		 * Anonymize props from a specific object
		 *
		 * @param YITH_WCAF_Abstract_Object $object          Object to anonymize.
		 * @param array                     $props_to_remove Props to anonymize, in the form of an array of data types indexed by prop key.
		 *
		 * @return bool Status of the operation; true if object was anonymized, false if it was retained unmodified.
		 */
		protected function object_eraser( $object, $props_to_remove ) {
			/**
			 * APPLY_FILTERS: yith_wcaf_privacy_erase_object
			 *
			 * Filters whether to remove the object data.
			 *
			 * @param bool   $erase_object_data Whether to remove the object data or not.
			 * @param object $object            Object to remove data from.
			 */
			if ( apply_filters( 'yith_wcaf_privacy_erase_object', true, $object ) ) {
				/**
				 * DO_ACTION: yith_wcaf_privacy_before_remove_object
				 *
				 * Allows to trigger some action before anonymizing props from a specific object.
				 *
				 * @param object $object Object to anonymize data from.
				 */
				do_action( 'yith_wcaf_privacy_before_remove_object', $object );

				foreach ( $props_to_remove as $prop => $data_type ) {
					$getter = "get_$prop";
					$setter = "set_$prop";

					if ( ! method_exists( $object, $getter ) || ! method_exists( $object, $setter ) ) {
						continue;
					}

					$value = $object->$getter();

					if ( function_exists( 'wp_privacy_anonymize_data' ) ) {
						$anon_value = wp_privacy_anonymize_data( $data_type, $value );
					} else {
						$anon_value = '';
					}

					/**
					 * APPLY_FILTERS: yith_wcaf_privacy_remove_object_personal_data_prop_value
					 *
					 * Filters the object prop to remove.
					 *
					 * @param string $anon_value Prop value to remove.
					 * @param string $prop       Prop to export.
					 * @param string $value      Value to remove.
					 * @param string $data_type  Data type.
					 * @param object $object     Object.
					 */
					$object->$setter( apply_filters( 'yith_wcaf_privacy_remove_object_personal_data_prop_value', $anon_value, $prop, $value, $data_type, $object ) );
				}

				$object->save();

				/**
				 * DO_ACTION: yith_wcaf_privacy_remove_object
				 *
				 * Allows to trigger some action after anonymizing props from a specific object.
				 *
				 * @param object $object Object to anonymize data from.
				 */
				do_action( 'yith_wcaf_privacy_remove_object', $object );

				return true;
			}

			return false;
		}

		/**
		 * Serialize value to export
		 *
		 * @param mixed $value Value to export; could be scalar or non-scalar value; method will reduce it to string form.
		 * @return string Serialized version of the passed value.
		 */
		protected function serialize( $value ) {
			if ( is_scalar( $value ) ) {
				return $value;
			}

			if ( $value instanceof WC_Meta_data ) {
				$data = $value->get_data();

				$value = array(
					$data['key'] => $data['value'],
				);
			}

			if ( is_object( $value ) ) {
				$value = (array) $value;
			}

			if ( is_array( $value ) ) {
				foreach ( $value as & $array_value ) {
					$array_value = $this->serialize( $array_value );
				}
			}

			return wp_json_encode( $value, 1 );
		}
	}
}
