woocommerce-subscriptions/includes/upgrades/class-wcs-repair-line-item-...

114 lines
3.9 KiB
PHP
Executable File

<?php
/**
* Between WCS 2.2.0 and WCS 2.6.0 subscription purchases of free trial products haven't set the `_has_trial` line item meta
* on subscription line items.
*
* This script will repair that missing data by:
* 1. Getting all subscriptions which were purchased with a free trial. Those with '_trial_period' subscription meta.
* 2. Schedule a background job, via Action Scheduler, to repair each of those subscriptions.
* 3. For each subscription line item that was purchased in the parent order (has not been switched or added manually), set the _has_trial line item meta.
*
* All line items on subscriptions with _trial_period meta, that were purchased in the parent order must have had a free trial because subscriptions are grouped in the cart by trial period and length.
* For more details @see https://github.com/Prospress/woocommerce-subscriptions/pull/3239
*
* @author WooCommerce
* @category Admin
* @package WooCommerce Subscriptions/Admin/Upgrades
* @version 2.6.0
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class WCS_Repair_Line_Item_Has_Trial_Meta extends WCS_Background_Repairer {
/**
* Constructor
*
* @param WC_Logger_Interface $logger The WC_Logger instance.
*
* @since 2.6.0
*/
public function __construct( WC_Logger_Interface $logger ) {
$this->scheduled_hook = 'wcs_schedule_trial_subscription_repairs';
$this->repair_hook = 'wcs_free_trial_line_item_meta_repair';
$this->log_handle = 'wcs-repair-line-item-has-trial-meta';
$this->logger = $logger;
}
/**
* Get a batch of subscriptions which have or had free trials at the time of purchase.
*
* @param int $page The page number to get results from.
* @return array A list of subscription ids.
*
* @since 2.6.0
*/
protected function get_items_to_repair( $page ) {
$query = new WP_Query();
$query_args = array(
'post_type' => 'shop_subscription',
'posts_per_page' => 20,
'paged' => $page,
'orderby' => 'ID',
'order' => 'ASC', // Get the subscriptions in ascending order by ID so any new subscriptions created after the repairs start running will be at the end and not cause issues with paging.
'post_status' => 'any',
'fields' => 'ids',
'meta_query' => array(
array(
'key' => '_trial_period',
'compare' => '!=',
'value' => '',
),
),
);
return $query->query( $query_args );
}
/**
* Repair the line item meta for a given subscription ID.
*
* @param int $subscription_id
*
* @since 2.6.0
*/
public function repair_item( $subscription_id ) {
try {
$subscription = wcs_get_subscription( $subscription_id );
if ( false === $subscription ) {
throw new Exception( 'Failed to instantiate subscription object' );
}
$parent_order = $subscription->get_parent();
if ( ! $parent_order ) {
$this->log( sprintf( "Subscription ID %d doesn't have a parent order -- skipping", $subscription_id ) );
return;
}
// Build an array of product IDs so we can match corresponding subscription items.
$parent_order_product_ids = array();
foreach ( $parent_order->get_items() as $line_item ) {
$parent_order_product_ids[ wcs_get_canonical_product_id( $line_item ) ] = true;
}
// Set the has_trial meta if this subscription line item exists in the parent order,
foreach ( $subscription->get_items() as $line_item ) {
if ( isset( $parent_order_product_ids[ wcs_get_canonical_product_id( $line_item ) ] ) && ! $line_item->meta_exists( '_has_trial' ) ) {
$line_item->update_meta_data( '_has_trial', 'true' );
$line_item->save();
}
}
$this->log( sprintf( 'Subscription ID %d "_has_trial" line item meta repaired.', $subscription_id ) );
} catch ( Exception $e ) {
$this->log( sprintf( 'ERROR: Exception caught trying to repair free trial line item meta for subscription %d - exception message: %s ---', $subscription_id, $e->getMessage() ) );
}
}
}