<?php
/**
 * What is removed when the plugin is deleted.
 *
 * Two halves, and the difference between them matters.
 *
 * Caches and capabilities go unconditionally: they are derived data, they mean
 * nothing once the plugin is gone, and leaving them behind puts a dead
 * capability on every shop manager's account.
 *
 * Warranty records, claims and settings go only if the shop asked. A policy is a
 * promise the shop has made and a claim is the record of honouring it; deleting
 * that because somebody removed a plugin to test something is not tidying up,
 * it is destroying a liability history. The setting lives under
 * Settings -> After the sale and is off unless somebody turns it on.
 *
 * This file used to be gated on a `WARRANTY_CART_UNINSTALL` constant that
 * nothing defined, so none of it had ever run — and what it would have done was
 * written for a different plugin. It deleted two of about twenty-five options,
 * deleted a transient nothing sets, called wp_cache_flush() on the whole site,
 * and said in a comment that this plugin creates no custom tables. It creates
 * five.
 *
 * @package WarrantyCart
 */

// Prevent direct access.
if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
	exit;
}

global $wpdb;

/*
 * The caches, always.
 *
 * Named individually rather than flushed: wp_cache_flush() empties the entire
 * site's object cache, including every other plugin's, which is a rude thing to
 * do on the way out of the door.
 */
$warranty_cart_transients = array(
	'warranty_dashboard_data',
	'warranty_reports_data',
	'warranty_sales_data',
	'warranty_product_count',
	'warranty_order_count',
);

foreach ( $warranty_cart_transients as $warranty_cart_transient ) {
	delete_transient( $warranty_cart_transient );
}

/*
 * The report caches are keyed by date range, and the guest lookup counts
 * failures per address, so both produce names this file cannot list. Removed by
 * pattern, options table only — an external object cache expires them on its
 * own.
 */
$wpdb->query(
	$wpdb->prepare(
		"DELETE FROM {$wpdb->options} WHERE option_name LIKE %s OR option_name LIKE %s",
		$wpdb->esc_like( '_transient_warranty_' ) . '%',
		$wpdb->esc_like( '_transient_timeout_warranty_' ) . '%'
	)
);

/*
 * The capability, always.
 *
 * It is ours, it does nothing without us, and a shop manager left holding
 * `manage_warranty_cart` after the plugin is gone is a permission nobody can
 * explain a year from now.
 */
foreach ( array( 'administrator', 'shop_manager' ) as $warranty_cart_role_name ) {
	$warranty_cart_role = get_role( $warranty_cart_role_name );

	if ( $warranty_cart_role ) {
		$warranty_cart_role->remove_cap( 'manage_warranty_cart' );
	}
}

// Everything below is the shop's data, and only goes if the shop said so.
if ( 'yes' !== get_option( 'warranty_cart_remove_data', 'no' ) ) {
	return;
}

$warranty_cart_tables = array(
	'warranty_cart_claim_attachments',
	'warranty_cart_claim_messages',
	'warranty_cart_claims',
	'warranty_cart_renewals',
	'warranty_cart_warranties',
);

foreach ( $warranty_cart_tables as $warranty_cart_table ) {
	// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
	$wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}{$warranty_cart_table}" );
}

/*
 * Claim evidence lives outside the media library, in a closed directory under
 * uploads, so nothing else will ever clear it up.
 */
$warranty_cart_uploads = wp_upload_dir();

if ( empty( $warranty_cart_uploads['error'] ) ) {
	$warranty_cart_dir = trailingslashit( $warranty_cart_uploads['basedir'] ) . 'warranty-cart-claims/';

	if ( is_dir( $warranty_cart_dir ) ) {
		$warranty_cart_files = glob( $warranty_cart_dir . '*' );

		foreach ( is_array( $warranty_cart_files ) ? $warranty_cart_files : array() as $warranty_cart_file ) {
			if ( is_file( $warranty_cart_file ) ) {
				wp_delete_file( $warranty_cart_file );
			}
		}

		/*
		 * The directory only goes if it is empty. Anything left in it is
		 * something this file did not put there, and removing it would be
		 * deleting a stranger's data on the way out.
		 */
		// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_rmdir, WordPress.PHP.NoSilencedErrors.Discouraged
		@rmdir( $warranty_cart_dir ); // phpcs:ignore
	}
}

/*
 * Every option the plugin owns, by name.
 *
 * Listed rather than matched on a prefix, because the prefix is not consistent —
 * some options are `warranty_cart_`, some are `warranty_`, and a LIKE broad
 * enough to catch the second would also catch another plugin's.
 */
$warranty_cart_options = array(
	'warranty_cart_db_version',
	'warranty_cart_settings',
	'warranty_cart_settings_saved',
	'warranty_cart_activated',
	'warranty_cart_setup_complete',
	'warranty_cart_caps_version',
	'warranty_cart_flush_rewrites',
	'warranty_cart_default_duration',
	'warranty_cart_default_unit',
	'warranty_cart_reminder_days',
	'warranty_cart_reminder_enabled',
	'warranty_cart_expiry_notice_enabled',
	'warranty_cart_require_terms',
	'warranty_cart_require_billing_phone',
	'warranty_cart_terms_page',
	'warranty_cart_page',
	'warranty_cart_claim_page',
	'warranty_cart_selector_layout',
	'warranty_cart_offer_placement',
	'warranty_cart_myaccount_enabled',
	'warranty_cart_myaccount_label',
	'warranty_cart_account_per_page',
	'warranty_cart_serials_enabled',
	'warranty_cart_claims_enabled',
	'warranty_cart_guest_claims',
	'warranty_cart_claim_max_file_size',
	'warranty_cart_claim_attachment_limit',
	'warranty_cart_renewals_enabled',
	'warranty_cart_renewal_window',
	'warranty_cart_renewal_grace',
	'warranty_cart_remove_data',
	'warranty_checkout_fields',
	'warranty_enable_email_notifications',
	'warranty_enable_pdf_certificates',
	'warranty_guest_checkout',
	'warranty_max_file_size',
	'warranty_require_claim_proof',
	'warranty_require_billing_phone',
);

foreach ( $warranty_cart_options as $warranty_cart_option ) {
	delete_option( $warranty_cart_option );
}

/*
 * Warranty products are ordinary WooCommerce products and the orders that
 * bought them are ordinary orders. Neither is deleted: they are the store's
 * catalogue and its accounts, and a plugin has no business removing either.
 * Their warranty meta goes, so nothing is left describing cover that no longer
 * exists.
 */
$wpdb->query(
	$wpdb->prepare(
		"DELETE FROM {$wpdb->postmeta} WHERE meta_key LIKE %s OR meta_key LIKE %s",
		$wpdb->esc_like( '_warranty_cart_' ) . '%',
		$wpdb->esc_like( '_warranty_product_type' )
	)
);
