mirror of
https://github.com/pronamic/woocommerce-subscriptions.git
synced 2025-10-10 11:32:54 +00:00
Updates to 7.7.0
This commit is contained in:
@@ -566,6 +566,19 @@ a.close-subscriptions-search {
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#woocommerce-subscription-schedule .date-fields.has-error {
|
||||||
|
color: #d63638;
|
||||||
|
}
|
||||||
|
|
||||||
|
#woocommerce-subscription-schedule .date-fields .message {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#woocommerce-subscription-schedule .date-fields.has-error input {
|
||||||
|
border-color: #d63638;
|
||||||
|
}
|
||||||
|
|
||||||
#woocommerce-subscription-schedule
|
#woocommerce-subscription-schedule
|
||||||
.wcs-date-input
|
.wcs-date-input
|
||||||
input[type='text']:first-of-type {
|
input[type='text']:first-of-type {
|
||||||
|
@@ -242,22 +242,66 @@ jQuery( function ( $ ) {
|
|||||||
// Update the UTC timestamp sent to the server
|
// Update the UTC timestamp sent to the server
|
||||||
date_pieces = $date_input.val().split( '-' );
|
date_pieces = $date_input.val().split( '-' );
|
||||||
|
|
||||||
|
var newTimeStampValue = moment( {
|
||||||
|
years: date_pieces[ 0 ],
|
||||||
|
months: date_pieces[ 1 ] - 1,
|
||||||
|
date: date_pieces[ 2 ],
|
||||||
|
hours: $hour_input.val(),
|
||||||
|
minutes: $minute_input.val(),
|
||||||
|
seconds: one_hour_from_now.format( 'ss' ),
|
||||||
|
} )
|
||||||
|
.utc()
|
||||||
|
.unix();
|
||||||
|
|
||||||
|
|
||||||
|
// Moment will return NaN if the date is invalid, that's why we need to check for NaN only.
|
||||||
|
if ( isNaN( newTimeStampValue ) ) {
|
||||||
|
wcsShowDateFieldError( date_type );
|
||||||
|
} else {
|
||||||
|
wcsHideDateFieldError( date_type );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Intentionally do not prevent timestamp updates if the date is invalid.
|
||||||
|
// This way it's easier to catch invalid fields during submit event if attempted without editing invalid values.
|
||||||
$( '#' + date_type + '_timestamp_utc' ).val(
|
$( '#' + date_type + '_timestamp_utc' ).val(
|
||||||
moment( {
|
newTimeStampValue
|
||||||
years: date_pieces[ 0 ],
|
|
||||||
months: date_pieces[ 1 ] - 1,
|
|
||||||
date: date_pieces[ 2 ],
|
|
||||||
hours: $hour_input.val(),
|
|
||||||
minutes: $minute_input.val(),
|
|
||||||
seconds: one_hour_from_now.format( 'ss' ),
|
|
||||||
} )
|
|
||||||
.utc()
|
|
||||||
.unix()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$( 'body' ).trigger( 'wcs-updated-date', date_type );
|
$( 'body' ).trigger( 'wcs-updated-date', date_type );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
function wcsShowDateFieldError( date_type ) {
|
||||||
|
var $fieldContainer = $( '#subscription-' + date_type + '-date' );
|
||||||
|
$fieldContainer.addClass( 'has-error' );
|
||||||
|
var $messageContainer = $fieldContainer.find( '.message' );
|
||||||
|
var $messageContent = $messageContainer.find( '.message-content' );
|
||||||
|
|
||||||
|
// Clear and set content before showing to ensure screen readers announce the new message
|
||||||
|
$messageContent.text('');
|
||||||
|
$messageContainer.show();
|
||||||
|
|
||||||
|
// Use setTimeout to ensure DOM update occurs before adding new text
|
||||||
|
setTimeout(function() {
|
||||||
|
// If the focus switched to the next field voice over skips announcing the error message.
|
||||||
|
// This is a workaround to ensure the error message is announced.
|
||||||
|
$fieldContainer
|
||||||
|
.find( `input#${date_type}` )
|
||||||
|
.trigger( 'focus' )
|
||||||
|
.trigger( 'blur' );
|
||||||
|
$messageContent.text( wcs_admin_meta_boxes.i18n_invalid_date_notice );
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
function wcsHideDateFieldError( date_type ) {
|
||||||
|
var $fieldContainer = $( '#subscription-' + date_type + '-date' );
|
||||||
|
$fieldContainer.removeClass( 'has-error' );
|
||||||
|
var $messageContainer = $fieldContainer.find( '.message' );
|
||||||
|
var $messageContent = $messageContainer.find( '.message-content' );
|
||||||
|
|
||||||
|
$messageContainer.hide();
|
||||||
|
$messageContent.text('');
|
||||||
|
}
|
||||||
|
|
||||||
function zeroise( val ) {
|
function zeroise( val ) {
|
||||||
return val > 9 ? val : '0' + val;
|
return val > 9 ? val : '0' + val;
|
||||||
}
|
}
|
||||||
@@ -327,6 +371,26 @@ jQuery( function ( $ ) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$( 'body.post-type-shop_subscription #post, body.woocommerce_page_wc-orders--shop_subscription #order' ).on( 'submit', function ( evt ) {
|
||||||
|
var invalid_dates = [];
|
||||||
|
$( '.woocommerce-subscriptions.date-picker' ).each( function () {
|
||||||
|
var $date_input = $( this );
|
||||||
|
var date_type = $date_input.attr( 'id' );
|
||||||
|
var timestamp = $( '#' + date_type + '_timestamp_utc' ).val();
|
||||||
|
// At this point, timestamp is a string, not a number.
|
||||||
|
// We check for NaN only because everything else should be a valid timestamp set during the change event.
|
||||||
|
if ( timestamp === 'NaN' ) {
|
||||||
|
invalid_dates.push( date_type );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
if ( invalid_dates.length > 0 ) {
|
||||||
|
// Focus the first invalid date to make it noticeable.
|
||||||
|
$( '#subscription-' + invalid_dates[0] + '-date' ).find( '.wcs-date-input input' ).first().focus();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} )
|
||||||
|
|
||||||
$( 'body.post-type-shop_subscription #post, body.woocommerce_page_wc-orders--shop_subscription #order' ).on( 'submit', function () {
|
$( 'body.post-type-shop_subscription #post, body.woocommerce_page_wc-orders--shop_subscription #order' ).on( 'submit', function () {
|
||||||
if (
|
if (
|
||||||
'wcs_process_renewal' ==
|
'wcs_process_renewal' ==
|
||||||
|
@@ -1,5 +1,18 @@
|
|||||||
*** WooCommerce Subscriptions Changelog ***
|
*** WooCommerce Subscriptions Changelog ***
|
||||||
|
|
||||||
|
2025-07-09 - version 7.7.0
|
||||||
|
* Fix: Restores normal behavior for the report caching updates scheduled action, which was failing due to a bad filepath.
|
||||||
|
* Fix: Fix error when placing an order with a valid card after using a declined one.
|
||||||
|
* Fix: Fix order renewal errors when using some plugins.
|
||||||
|
* Fix: Prevent fatal errors when loading or deleting subscriptions with corrupted date values stored in a database.
|
||||||
|
* Fix: Prevent fatal errors when trying to save invalid date values and display better error messages instead.
|
||||||
|
* Fix: Fix broken blocks and javascript translations.
|
||||||
|
* Fix: Keep newly created subscriptions in pending status when initial payment fails instead of putting them on hold.
|
||||||
|
* Dev: Improve test suite bootstrap process by postponing interactions with Action Scheduler until it has fully initialized.
|
||||||
|
* Dev: Plugin upgrade routines will now be triggered by changes in the main plugin version (and not the core library version).
|
||||||
|
* Dev: Update wcs_is_paypal_profile_a() so it handles non-string parameters more gracefully. This is principally to reduce noise levels when running the test suite.
|
||||||
|
* Dev: Proactively reviewed and hardened code to improve our security posture going forward.
|
||||||
|
|
||||||
2025-06-11 - version 7.6.0
|
2025-06-11 - version 7.6.0
|
||||||
* Update: Allow updating billing info on existing subscriptions when customer changes account details.
|
* Update: Allow updating billing info on existing subscriptions when customer changes account details.
|
||||||
* Fix: Use floats instead of integers for tax calculation in subscription switching when prices include tax.
|
* Fix: Use floats instead of integers for tax calculation in subscription switching when prices include tax.
|
||||||
|
@@ -217,7 +217,16 @@ class WCS_Report_Cache_Manager {
|
|||||||
// Load report class dependencies
|
// Load report class dependencies
|
||||||
require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
|
require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
|
||||||
|
|
||||||
$wc_core_dir = getenv( 'CI' ) ? ( getenv( 'WC_CORE_DIR' ) ? getenv( 'WC_CORE_DIR' ) : '/tmp/woocommerce' ) : WC()->plugin_path() . '/woocommerce';
|
$within_ci_environment = getenv( 'CI' );
|
||||||
|
$wc_core_dir_from_env = getenv( 'WC_CORE_DIR' );
|
||||||
|
|
||||||
|
if ( $within_ci_environment && ! empty( $wc_core_dir_from_env ) ) {
|
||||||
|
$wc_core_dir = $wc_core_dir_from_env;
|
||||||
|
} elseif ( $within_ci_environment ) {
|
||||||
|
$wc_core_dir = '/tmp/woocommerce';
|
||||||
|
} else {
|
||||||
|
$wc_core_dir = WC()->plugin_path();
|
||||||
|
}
|
||||||
|
|
||||||
require_once( $wc_core_dir . '/includes/admin/reports/class-wc-admin-report.php' );
|
require_once( $wc_core_dir . '/includes/admin/reports/class-wc-admin-report.php' );
|
||||||
|
|
||||||
|
@@ -98,7 +98,7 @@ abstract class WCS_Background_Repairer extends WCS_Background_Upgrader {
|
|||||||
*/
|
*/
|
||||||
protected function update_item( $item ) {
|
protected function update_item( $item ) {
|
||||||
// Schedule the individual repair actions to run in 1 hr to give us the best chance at scheduling all the actions before they start running and clogging up the queue.
|
// Schedule the individual repair actions to run in 1 hr to give us the best chance at scheduling all the actions before they start running and clogging up the queue.
|
||||||
as_schedule_single_action( gmdate( 'U' ) + HOUR_IN_SECONDS, $this->repair_hook, array( 'repair_object' => $item ) );
|
as_schedule_single_action( (int) gmdate( 'U' ) + HOUR_IN_SECONDS, $this->repair_hook, array( 'repair_object' => $item ) );
|
||||||
unset( $this->items_to_repair[ $item ] );
|
unset( $this->items_to_repair[ $item ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -97,7 +97,8 @@ abstract class WCS_Background_Updater {
|
|||||||
$this->schedule_background_update();
|
$this->schedule_background_update();
|
||||||
|
|
||||||
// If the update is being run via WP CLI, we don't need to worry about the request time, just the processing time for this method
|
// If the update is being run via WP CLI, we don't need to worry about the request time, just the processing time for this method
|
||||||
$start_time = $this->is_wp_cli_request() ? gmdate( 'U' ) : WCS_INIT_TIMESTAMP;
|
// @phpstan-ignore constant.notFound
|
||||||
|
$start_time = $this->is_wp_cli_request() ? (int) gmdate( 'U' ) : WCS_INIT_TIMESTAMP;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
@@ -107,7 +108,7 @@ abstract class WCS_Background_Updater {
|
|||||||
|
|
||||||
$this->update_item( $item );
|
$this->update_item( $item );
|
||||||
|
|
||||||
$time_elapsed = ( gmdate( 'U' ) - $start_time );
|
$time_elapsed = (int) gmdate( 'U' ) - $start_time;
|
||||||
|
|
||||||
if ( $time_elapsed >= $this->time_limit ) {
|
if ( $time_elapsed >= $this->time_limit ) {
|
||||||
break 2;
|
break 2;
|
||||||
@@ -127,7 +128,7 @@ abstract class WCS_Background_Updater {
|
|||||||
protected function schedule_background_update() {
|
protected function schedule_background_update() {
|
||||||
// A timestamp is returned if there's a pending action already scheduled. Otherwise true if its running or false if one doesn't exist.
|
// A timestamp is returned if there's a pending action already scheduled. Otherwise true if its running or false if one doesn't exist.
|
||||||
if ( ! is_numeric( as_next_scheduled_action( $this->scheduled_hook ) ) ) {
|
if ( ! is_numeric( as_next_scheduled_action( $this->scheduled_hook ) ) ) {
|
||||||
as_schedule_single_action( gmdate( 'U' ) + $this->time_limit, $this->scheduled_hook );
|
as_schedule_single_action( (int) gmdate( 'U' ) + $this->time_limit, $this->scheduled_hook );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -58,7 +58,6 @@ abstract class WCS_Related_Order_Store {
|
|||||||
/**
|
/**
|
||||||
* Allow third-parties to register their own custom order relationship types which should be handled by this store.
|
* Allow third-parties to register their own custom order relationship types which should be handled by this store.
|
||||||
*
|
*
|
||||||
* @param array An array of order relationship types.
|
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.5.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.5.0
|
||||||
*/
|
*/
|
||||||
foreach ( (array) apply_filters( 'wcs_additional_related_order_relation_types', array() ) as $relation_type ) {
|
foreach ( (array) apply_filters( 'wcs_additional_related_order_relation_types', array() ) as $relation_type ) {
|
||||||
@@ -153,7 +152,7 @@ abstract class WCS_Related_Order_Store {
|
|||||||
* Get related order IDs grouped by relation type.
|
* Get related order IDs grouped by relation type.
|
||||||
*
|
*
|
||||||
* @param WC_Order $subscription The subscription to find related orders.
|
* @param WC_Order $subscription The subscription to find related orders.
|
||||||
* @param array $relation_type An array of relation types to fetch. Must be an array containing 'renewal', 'switch' or 'resubscribe' unless custom relationships are implemented.
|
* @param array $relation_types An array of relation types to fetch. Must be an array containing 'renewal', 'switch' or 'resubscribe' unless custom relationships are implemented.
|
||||||
*
|
*
|
||||||
* @return array An associative array where keys are relation types and values are arrays of related order IDs.
|
* @return array An associative array where keys are relation types and values are arrays of related order IDs.
|
||||||
*/
|
*/
|
||||||
|
@@ -35,7 +35,8 @@ abstract class WCS_Table_Maker {
|
|||||||
foreach ( $this->tables as $table ) {
|
foreach ( $this->tables as $table ) {
|
||||||
$wpdb->tables[] = $table;
|
$wpdb->tables[] = $table;
|
||||||
$name = $this->get_full_table_name( $table );
|
$name = $this->get_full_table_name( $table );
|
||||||
$wpdb->$table = $name;
|
// phpcs:disable QITStandard.DB.DynamicWpdbMethodCall.DynamicMethod
|
||||||
|
$wpdb->$table = $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the tables
|
// create the tables
|
||||||
|
@@ -160,12 +160,10 @@ class WC_Subscriptions_Admin {
|
|||||||
* triggered.
|
* triggered.
|
||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.1.1
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.1.1
|
||||||
*
|
|
||||||
* @return null
|
|
||||||
*/
|
*/
|
||||||
public static function clear_subscriptions_transients() {
|
public static function clear_subscriptions_transients() {
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
if ( empty( $_GET['action'] ) || empty( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'debug_action' ) ) {
|
if ( empty( $_GET['action'] ) || empty( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( wc_clean( wp_unslash( $_REQUEST['_wpnonce'] ) ), 'debug_action' ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,7 +200,7 @@ class WC_Subscriptions_Admin {
|
|||||||
/**
|
/**
|
||||||
* Add the 'subscriptions' product type to the WooCommerce product type select box.
|
* Add the 'subscriptions' product type to the WooCommerce product type select box.
|
||||||
*
|
*
|
||||||
* @param array Array of Product types & their labels, excluding the Subscription product type.
|
* @param array $product_types Array of Product types & their labels, excluding the Subscription product type.
|
||||||
* @return array Array of Product types & their labels, including the Subscription product type.
|
* @return array Array of Product types & their labels, including the Subscription product type.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
||||||
*/
|
*/
|
||||||
@@ -331,7 +329,10 @@ class WC_Subscriptions_Admin {
|
|||||||
<?php } ?>
|
<?php } ?>
|
||||||
</select>
|
</select>
|
||||||
</span>
|
</span>
|
||||||
<?php echo wcs_help_tip( $price_tooltip ); ?>
|
<?php
|
||||||
|
// @phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
|
echo wcs_help_tip( $price_tooltip );
|
||||||
|
?>
|
||||||
</p>
|
</p>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
@@ -381,7 +382,10 @@ class WC_Subscriptions_Admin {
|
|||||||
<?php } ?>
|
<?php } ?>
|
||||||
</select>
|
</select>
|
||||||
</span>
|
</span>
|
||||||
<?php echo wcs_help_tip( $trial_tooltip ); ?>
|
<?php
|
||||||
|
// @phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
|
echo wcs_help_tip( $trial_tooltip );
|
||||||
|
?>
|
||||||
</p>
|
</p>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
@@ -493,13 +497,12 @@ class WC_Subscriptions_Admin {
|
|||||||
/**
|
/**
|
||||||
* Save meta data for simple subscription product type when the "Edit Product" form is submitted.
|
* Save meta data for simple subscription product type when the "Edit Product" form is submitted.
|
||||||
*
|
*
|
||||||
* @param array Array of Product types & their labels, excluding the Subscription product type.
|
* @param int $post_id The ID of the post being saved.
|
||||||
* @return array Array of Product types & their labels, including the Subscription product type.
|
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
||||||
*/
|
*/
|
||||||
public static function save_subscription_meta( $post_id ) {
|
public static function save_subscription_meta( $post_id ) {
|
||||||
|
|
||||||
if ( empty( $_POST['_wcsnonce'] ) || ! wp_verify_nonce( $_POST['_wcsnonce'], 'wcs_subscription_meta' ) || false === self::is_subscription_product_save_request( $post_id, apply_filters( 'woocommerce_subscription_product_types', array( WC_Subscriptions_Core_Plugin::instance()->get_product_type_name() ) ) ) ) {
|
if ( empty( $_POST['_wcsnonce'] ) || ! wp_verify_nonce( wc_clean( wp_unslash( $_POST['_wcsnonce'] ) ), 'wcs_subscription_meta' ) || false === self::is_subscription_product_save_request( $post_id, apply_filters( 'woocommerce_subscription_product_types', array( WC_Subscriptions_Core_Plugin::instance()->get_product_type_name() ) ) ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -544,7 +547,7 @@ class WC_Subscriptions_Admin {
|
|||||||
$_POST['_subscription_trial_length'] = $max_trial_length;
|
$_POST['_subscription_trial_length'] = $max_trial_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
update_post_meta( $post_id, '_subscription_trial_length', $_POST['_subscription_trial_length'] );
|
update_post_meta( $post_id, '_subscription_trial_length', wc_clean( wp_unslash( $_POST['_subscription_trial_length'] ) ) );
|
||||||
|
|
||||||
$_REQUEST['_subscription_sign_up_fee'] = wc_format_decimal( $_REQUEST['_subscription_sign_up_fee'] );
|
$_REQUEST['_subscription_sign_up_fee'] = wc_format_decimal( $_REQUEST['_subscription_sign_up_fee'] );
|
||||||
$_REQUEST['_subscription_one_time_shipping'] = isset( $_REQUEST['_subscription_one_time_shipping'] ) ? 'yes' : 'no';
|
$_REQUEST['_subscription_one_time_shipping'] = isset( $_REQUEST['_subscription_one_time_shipping'] ) ? 'yes' : 'no';
|
||||||
@@ -572,13 +575,12 @@ class WC_Subscriptions_Admin {
|
|||||||
/**
|
/**
|
||||||
* Save meta data for variable subscription product type when the "Edit Product" form is submitted.
|
* Save meta data for variable subscription product type when the "Edit Product" form is submitted.
|
||||||
*
|
*
|
||||||
* @param array Array of Product types & their labels, excluding the Subscription product type.
|
* @param int $post_id The ID of the post being saved.
|
||||||
* @return array Array of Product types & their labels, including the Subscription product type.
|
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
public static function save_variable_subscription_meta( $post_id ) {
|
public static function save_variable_subscription_meta( $post_id ) {
|
||||||
|
|
||||||
if ( empty( $_POST['_wcsnonce'] ) || ! wp_verify_nonce( $_POST['_wcsnonce'], 'wcs_subscription_meta' ) || false === self::is_subscription_product_save_request( $post_id, apply_filters( 'woocommerce_subscription_variable_product_types', array( 'variable-subscription' ) ) ) ) {
|
if ( empty( $_POST['_wcsnonce'] ) || ! wp_verify_nonce( wc_clean( wp_unslash( $_POST['_wcsnonce'] ) ), 'wcs_subscription_meta' ) || false === self::is_subscription_product_save_request( $post_id, apply_filters( 'woocommerce_subscription_variable_product_types', array( 'variable-subscription' ) ) ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -596,7 +598,6 @@ class WC_Subscriptions_Admin {
|
|||||||
* Calculate and set a simple subscription's prices when edited via the bulk edit
|
* Calculate and set a simple subscription's prices when edited via the bulk edit
|
||||||
*
|
*
|
||||||
* @param object $product An instance of a WC_Product_* object.
|
* @param object $product An instance of a WC_Product_* object.
|
||||||
* @return null
|
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.3.9
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.3.9
|
||||||
*/
|
*/
|
||||||
public static function bulk_edit_save_subscription_meta( $product ) {
|
public static function bulk_edit_save_subscription_meta( $product ) {
|
||||||
@@ -621,7 +622,7 @@ class WC_Subscriptions_Admin {
|
|||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if ( strstr( $regular_price, '%' ) ) {
|
if ( strstr( $regular_price, '%' ) ) {
|
||||||
$percent = str_replace( '%', '', $regular_price ) / 100;
|
$percent = (float) str_replace( '%', '', $regular_price ) / 100;
|
||||||
$new_price = $old_regular_price + ( $old_regular_price * $percent );
|
$new_price = $old_regular_price + ( $old_regular_price * $percent );
|
||||||
} else {
|
} else {
|
||||||
$new_price = $old_regular_price + $regular_price;
|
$new_price = $old_regular_price + $regular_price;
|
||||||
@@ -629,7 +630,7 @@ class WC_Subscriptions_Admin {
|
|||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
if ( strstr( $regular_price, '%' ) ) {
|
if ( strstr( $regular_price, '%' ) ) {
|
||||||
$percent = str_replace( '%', '', $regular_price ) / 100;
|
$percent = (float) str_replace( '%', '', $regular_price ) / 100;
|
||||||
$new_price = $old_regular_price - ( $old_regular_price * $percent );
|
$new_price = $old_regular_price - ( $old_regular_price * $percent );
|
||||||
} else {
|
} else {
|
||||||
$new_price = $old_regular_price - $regular_price;
|
$new_price = $old_regular_price - $regular_price;
|
||||||
@@ -655,7 +656,7 @@ class WC_Subscriptions_Admin {
|
|||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if ( strstr( $sale_price, '%' ) ) {
|
if ( strstr( $sale_price, '%' ) ) {
|
||||||
$percent = str_replace( '%', '', $sale_price ) / 100;
|
$percent = (float) str_replace( '%', '', $sale_price ) / 100;
|
||||||
$new_price = $old_sale_price + ( $old_sale_price * $percent );
|
$new_price = $old_sale_price + ( $old_sale_price * $percent );
|
||||||
} else {
|
} else {
|
||||||
$new_price = $old_sale_price + $sale_price;
|
$new_price = $old_sale_price + $sale_price;
|
||||||
@@ -663,7 +664,7 @@ class WC_Subscriptions_Admin {
|
|||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
if ( strstr( $sale_price, '%' ) ) {
|
if ( strstr( $sale_price, '%' ) ) {
|
||||||
$percent = str_replace( '%', '', $sale_price ) / 100;
|
$percent = (float) str_replace( '%', '', $sale_price ) / 100;
|
||||||
$new_price = $old_sale_price - ( $old_sale_price * $percent );
|
$new_price = $old_sale_price - ( $old_sale_price * $percent );
|
||||||
} else {
|
} else {
|
||||||
$new_price = $old_sale_price - $sale_price;
|
$new_price = $old_sale_price - $sale_price;
|
||||||
@@ -671,7 +672,7 @@ class WC_Subscriptions_Admin {
|
|||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
if ( strstr( $sale_price, '%' ) ) {
|
if ( strstr( $sale_price, '%' ) ) {
|
||||||
$percent = str_replace( '%', '', $sale_price ) / 100;
|
$percent = (float) str_replace( '%', '', $sale_price ) / 100;
|
||||||
$new_price = $product->get_regular_price() - ( $product->get_regular_price() * $percent );
|
$new_price = $product->get_regular_price() - ( $product->get_regular_price() * $percent );
|
||||||
} else {
|
} else {
|
||||||
$new_price = $product->get_regular_price() - $sale_price;
|
$new_price = $product->get_regular_price() - $sale_price;
|
||||||
@@ -706,17 +707,16 @@ class WC_Subscriptions_Admin {
|
|||||||
* subscription product type (or the bulk edit product is saved).
|
* subscription product type (or the bulk edit product is saved).
|
||||||
*
|
*
|
||||||
* @param int $post_id ID of the parent WC_Product_Variable_Subscription
|
* @param int $post_id ID of the parent WC_Product_Variable_Subscription
|
||||||
* @return null
|
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.3
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.3
|
||||||
*/
|
*/
|
||||||
public static function process_product_meta_variable_subscription( $post_id ) {
|
public static function process_product_meta_variable_subscription( $post_id ) {
|
||||||
|
|
||||||
if ( ! WC_Subscriptions_Product::is_subscription( $post_id ) || empty( $_POST['_wcsnonce'] ) || ! wp_verify_nonce( $_POST['_wcsnonce'], 'wcs_subscription_meta' ) ) {
|
if ( ! WC_Subscriptions_Product::is_subscription( $post_id ) || empty( $_POST['_wcsnonce'] ) || ! wp_verify_nonce( wc_clean( wp_unslash( $_POST['_wcsnonce'] ) ), 'wcs_subscription_meta' ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure WooCommerce calculates correct prices
|
// Make sure WooCommerce calculates correct prices
|
||||||
$_POST['variable_regular_price'] = isset( $_POST['variable_subscription_price'] ) ? $_POST['variable_subscription_price'] : 0;
|
$_POST['variable_regular_price'] = isset( $_POST['variable_subscription_price'] ) ? wc_clean( wp_unslash( $_POST['variable_subscription_price'] ) ) : 0;
|
||||||
|
|
||||||
// Sync the min variation price
|
// Sync the min variation price
|
||||||
if ( wcs_is_woocommerce_pre( '3.0' ) ) {
|
if ( wcs_is_woocommerce_pre( '3.0' ) ) {
|
||||||
@@ -731,13 +731,12 @@ class WC_Subscriptions_Admin {
|
|||||||
* Save meta info for subscription variations
|
* Save meta info for subscription variations
|
||||||
*
|
*
|
||||||
* @param int $variation_id
|
* @param int $variation_id
|
||||||
* @param int $i
|
* @param int $index
|
||||||
* return void
|
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
public static function save_product_variation( $variation_id, $index ) {
|
public static function save_product_variation( $variation_id, $index ) {
|
||||||
|
|
||||||
if ( ! WC_Subscriptions_Product::is_subscription( $variation_id ) || empty( $_POST['_wcsnonce_save_variations'] ) || ! wp_verify_nonce( $_POST['_wcsnonce_save_variations'], 'wcs_subscription_variations' ) ) {
|
if ( ! WC_Subscriptions_Product::is_subscription( $variation_id ) || empty( $_POST['_wcsnonce_save_variations'] ) || ! wp_verify_nonce( wc_clean( wp_unslash( $_POST['_wcsnonce_save_variations'] ) ), 'wcs_subscription_variations' ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -793,15 +792,14 @@ class WC_Subscriptions_Admin {
|
|||||||
*
|
*
|
||||||
* @param string $old_status Previous status of the subscription in update_status
|
* @param string $old_status Previous status of the subscription in update_status
|
||||||
* @param string $new_status New status of the subscription in update_status
|
* @param string $new_status New status of the subscription in update_status
|
||||||
* @param WC_Subscription $subscription The subscription being saved
|
* @param WC_Subscription $subscription The subscription being savedf
|
||||||
*
|
*
|
||||||
* @return null
|
|
||||||
* @throws Exception in case there was no user found / there's no customer attached to it
|
* @throws Exception in case there was no user found / there's no customer attached to it
|
||||||
*/
|
*/
|
||||||
public static function check_customer_is_set( $old_status, $new_status, $subscription ) {
|
public static function check_customer_is_set( $old_status, $new_status, $subscription ) {
|
||||||
global $post;
|
global $post;
|
||||||
|
|
||||||
if ( is_admin() && 'active' == $new_status && isset( $_POST['woocommerce_meta_nonce'] ) && wp_verify_nonce( $_POST['woocommerce_meta_nonce'], 'woocommerce_save_data' ) && isset( $_POST['customer_user'] ) && ! empty( $post ) && 'shop_subscription' === $post->post_type ) {
|
if ( is_admin() && 'active' == $new_status && isset( $_POST['woocommerce_meta_nonce'] ) && wp_verify_nonce( wc_clean( wp_unslash( $_POST['woocommerce_meta_nonce'] ) ), 'woocommerce_save_data' ) && isset( $_POST['customer_user'] ) && ! empty( $post ) && 'shop_subscription' === $post->post_type ) {
|
||||||
|
|
||||||
$user = new WP_User( absint( $_POST['customer_user'] ) );
|
$user = new WP_User( absint( $_POST['customer_user'] ) );
|
||||||
|
|
||||||
@@ -816,7 +814,6 @@ class WC_Subscriptions_Admin {
|
|||||||
* Set default values for subscription dropdown fields when bulk adding variations to fix issue #1342
|
* Set default values for subscription dropdown fields when bulk adding variations to fix issue #1342
|
||||||
*
|
*
|
||||||
* @param int $variation_id ID the post_id of the variation being added
|
* @param int $variation_id ID the post_id of the variation being added
|
||||||
* @return null
|
|
||||||
*/
|
*/
|
||||||
public static function set_variation_meta_defaults_on_bulk_add( $variation_id ) {
|
public static function set_variation_meta_defaults_on_bulk_add( $variation_id ) {
|
||||||
|
|
||||||
@@ -831,8 +828,6 @@ class WC_Subscriptions_Admin {
|
|||||||
/**
|
/**
|
||||||
* Adds all necessary admin styles.
|
* Adds all necessary admin styles.
|
||||||
*
|
*
|
||||||
* @param array Array of Product types & their labels, excluding the Subscription product type.
|
|
||||||
* @return array Array of Product types & their labels, including the Subscription product type.
|
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
||||||
*/
|
*/
|
||||||
public static function enqueue_styles_scripts() {
|
public static function enqueue_styles_scripts() {
|
||||||
@@ -1008,7 +1003,7 @@ class WC_Subscriptions_Admin {
|
|||||||
<?php $subscriptions_table->search_box( __( 'Search Subscriptions', 'woocommerce-subscriptions' ), 'subscription' ); ?>
|
<?php $subscriptions_table->search_box( __( 'Search Subscriptions', 'woocommerce-subscriptions' ), 'subscription' ); ?>
|
||||||
<input type="hidden" name="page" value="subscriptions" />
|
<input type="hidden" name="page" value="subscriptions" />
|
||||||
<?php if ( isset( $_REQUEST['status'] ) ) { ?>
|
<?php if ( isset( $_REQUEST['status'] ) ) { ?>
|
||||||
<input type="hidden" name="status" value="<?php echo esc_attr( $_REQUEST['status'] ); ?>" />
|
<input type="hidden" name="status" value="<?php echo esc_attr( wc_clean( wp_unslash( $_REQUEST['status'] ) ) ); ?>" />
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
</form>
|
</form>
|
||||||
<form id="subscriptions-filter" action="" method="get">
|
<form id="subscriptions-filter" action="" method="get">
|
||||||
@@ -1070,6 +1065,7 @@ class WC_Subscriptions_Admin {
|
|||||||
public static function get_subscriptions_list_table() {
|
public static function get_subscriptions_list_table() {
|
||||||
|
|
||||||
if ( ! isset( self::$subscriptions_list_table ) ) {
|
if ( ! isset( self::$subscriptions_list_table ) ) {
|
||||||
|
// @phpstan-ignore class.notFound
|
||||||
self::$subscriptions_list_table = new WC_Subscriptions_List_Table();
|
self::$subscriptions_list_table = new WC_Subscriptions_List_Table();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1085,7 +1081,7 @@ class WC_Subscriptions_Admin {
|
|||||||
*/
|
*/
|
||||||
public static function update_subscription_settings() {
|
public static function update_subscription_settings() {
|
||||||
|
|
||||||
if ( empty( $_POST['_wcsnonce'] ) || ! wp_verify_nonce( $_POST['_wcsnonce'], 'wcs_subscription_settings' ) ) {
|
if ( empty( $_POST['_wcsnonce'] ) || ! wp_verify_nonce( wc_clean( wp_unslash( $_POST['_wcsnonce'] ) ), 'wcs_subscription_settings' ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1484,7 +1480,7 @@ class WC_Subscriptions_Admin {
|
|||||||
|
|
||||||
// Map the order or subscription type to their respective keys and type key.
|
// Map the order or subscription type to their respective keys and type key.
|
||||||
$object_type = 'shop_order' === $typenow ? 'order' : 'subscription';
|
$object_type = 'shop_order' === $typenow ? 'order' : 'subscription';
|
||||||
$cache_report_key = isset( $_GET[ "_{$object_type}s_list_key" ] ) ? $_GET[ "_{$object_type}s_list_key" ] : '';
|
$cache_report_key = isset( $_GET[ "_{$object_type}s_list_key" ] ) ? wc_clean( wp_unslash( $_GET[ "_{$object_type}s_list_key" ] ) ) : '';
|
||||||
|
|
||||||
// If the report key or report arg is empty exit early.
|
// If the report key or report arg is empty exit early.
|
||||||
if ( empty( $cache_report_key ) || empty( $_GET['_report'] ) ) {
|
if ( empty( $cache_report_key ) || empty( $_GET['_report'] ) ) {
|
||||||
@@ -1492,7 +1488,7 @@ class WC_Subscriptions_Admin {
|
|||||||
return $where;
|
return $where;
|
||||||
}
|
}
|
||||||
|
|
||||||
$cache = get_transient( $_GET['_report'] );
|
$cache = get_transient( wc_clean( wp_unslash( $_GET['_report'] ) ) );
|
||||||
|
|
||||||
// Display an admin notice if we cannot find the report data requested.
|
// Display an admin notice if we cannot find the report data requested.
|
||||||
if ( ! isset( $cache[ $cache_report_key ] ) ) {
|
if ( ! isset( $cache[ $cache_report_key ] ) ) {
|
||||||
@@ -1522,6 +1518,7 @@ class WC_Subscriptions_Admin {
|
|||||||
|
|
||||||
// $format = '%d, %d, %d, %d, %d, [...]'
|
// $format = '%d, %d, %d, %d, %d, [...]'
|
||||||
$format = implode( ', ', array_fill( 0, count( $ids ), '%d' ) );
|
$format = implode( ', ', array_fill( 0, count( $ids ), '%d' ) );
|
||||||
|
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
|
||||||
$where .= $wpdb->prepare( " AND {$wpdb->posts}.ID IN ($format)", $ids );
|
$where .= $wpdb->prepare( " AND {$wpdb->posts}.ID IN ($format)", $ids );
|
||||||
|
|
||||||
return $where;
|
return $where;
|
||||||
@@ -1541,7 +1538,7 @@ class WC_Subscriptions_Admin {
|
|||||||
return $where;
|
return $where;
|
||||||
}
|
}
|
||||||
|
|
||||||
$user_id = $_GET['_paid_subscription_orders_for_customer_user'];
|
$user_id = wc_clean( wp_unslash( $_GET['_paid_subscription_orders_for_customer_user'] ) );
|
||||||
|
|
||||||
// Unset the GET arg so that it doesn't interfere with the query for user's subscriptions.
|
// Unset the GET arg so that it doesn't interfere with the query for user's subscriptions.
|
||||||
unset( $_GET['_paid_subscription_orders_for_customer_user'] );
|
unset( $_GET['_paid_subscription_orders_for_customer_user'] );
|
||||||
@@ -1559,7 +1556,7 @@ class WC_Subscriptions_Admin {
|
|||||||
$where .= " AND {$wpdb->posts}.ID = 0";
|
$where .= " AND {$wpdb->posts}.ID = 0";
|
||||||
} else {
|
} else {
|
||||||
// Orders with paid status
|
// Orders with paid status
|
||||||
$where .= $wpdb->prepare( " AND {$wpdb->posts}.post_status IN ( 'wc-processing', 'wc-completed' )" );
|
$where .= " AND {$wpdb->posts}.post_status IN ( 'wc-processing', 'wc-completed' )";
|
||||||
$where .= sprintf( " AND {$wpdb->posts}.ID IN (%s)", implode( ',', array_unique( $users_subscription_orders ) ) );
|
$where .= sprintf( " AND {$wpdb->posts}.ID IN (%s)", implode( ',', array_unique( $users_subscription_orders ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1711,7 +1708,7 @@ class WC_Subscriptions_Admin {
|
|||||||
/**
|
/**
|
||||||
* Adds Subscriptions specific details to the WooCommerce System Status report.
|
* Adds Subscriptions specific details to the WooCommerce System Status report.
|
||||||
*
|
*
|
||||||
* @param array $attributes Shortcode attributes.
|
* @param array $debug_data
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public static function add_system_status_items( $debug_data ) {
|
public static function add_system_status_items( $debug_data ) {
|
||||||
@@ -1946,14 +1943,15 @@ class WC_Subscriptions_Admin {
|
|||||||
/**
|
/**
|
||||||
* Check if subscription product meta data should be saved for the current request.
|
* Check if subscription product meta data should be saved for the current request.
|
||||||
*
|
*
|
||||||
* @param array Array of product types.
|
* @param int $post_id The ID of the post being saved.
|
||||||
|
* @param array $product_types Array of product types.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.9
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.9
|
||||||
*/
|
*/
|
||||||
private static function is_subscription_product_save_request( $post_id, $product_types ) {
|
private static function is_subscription_product_save_request( $post_id, $product_types ) {
|
||||||
|
|
||||||
if ( self::$saved_product_meta ) {
|
if ( self::$saved_product_meta ) {
|
||||||
$is_subscription_product_save_request = false;
|
$is_subscription_product_save_request = false;
|
||||||
} elseif ( empty( $_POST['_wcsnonce'] ) || ! wp_verify_nonce( $_POST['_wcsnonce'], 'wcs_subscription_meta' ) ) {
|
} elseif ( empty( $_POST['_wcsnonce'] ) || ! wp_verify_nonce( wc_clean( wp_unslash( $_POST['_wcsnonce'] ) ), 'wcs_subscription_meta' ) ) {
|
||||||
$is_subscription_product_save_request = false;
|
$is_subscription_product_save_request = false;
|
||||||
} elseif ( ! isset( $_POST['product-type'] ) || ! in_array( $_POST['product-type'], $product_types ) ) {
|
} elseif ( ! isset( $_POST['product-type'] ) || ! in_array( $_POST['product-type'], $product_types ) ) {
|
||||||
$is_subscription_product_save_request = false;
|
$is_subscription_product_save_request = false;
|
||||||
@@ -2059,7 +2057,7 @@ class WC_Subscriptions_Admin {
|
|||||||
*/
|
*/
|
||||||
public static function validate_product_type_change( $product_id ) {
|
public static function validate_product_type_change( $product_id ) {
|
||||||
|
|
||||||
if ( empty( $_POST['woocommerce_meta_nonce'] ) || ! wp_verify_nonce( wp_unslash( $_POST['woocommerce_meta_nonce'] ), 'woocommerce_save_data' ) || empty( $_POST['product-type'] ) ) {
|
if ( empty( $_POST['woocommerce_meta_nonce'] ) || ! wp_verify_nonce( wc_clean( wp_unslash( $_POST['woocommerce_meta_nonce'] ) ), 'woocommerce_save_data' ) || empty( $_POST['product-type'] ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -49,7 +49,7 @@ class WCS_Admin_Meta_Boxes {
|
|||||||
add_action( 'woocommerce_order_action_wcs_retry_renewal_payment', array( __CLASS__, 'process_retry_renewal_payment_action_request' ), 10, 1 );
|
add_action( 'woocommerce_order_action_wcs_retry_renewal_payment', array( __CLASS__, 'process_retry_renewal_payment_action_request' ), 10, 1 );
|
||||||
|
|
||||||
// Disable stock management while adding line items to a subscription via AJAX.
|
// Disable stock management while adding line items to a subscription via AJAX.
|
||||||
add_action( 'option_woocommerce_manage_stock', array( __CLASS__, 'override_stock_management' ) );
|
add_filter( 'option_woocommerce_manage_stock', array( __CLASS__, 'override_stock_management' ) );
|
||||||
|
|
||||||
// Parent order line item price lock option.
|
// Parent order line item price lock option.
|
||||||
add_action( 'woocommerce_order_item_add_action_buttons', array( __CLASS__, 'output_price_lock_html' ) );
|
add_action( 'woocommerce_order_item_add_action_buttons', array( __CLASS__, 'output_price_lock_html' ) );
|
||||||
@@ -178,6 +178,7 @@ class WCS_Admin_Meta_Boxes {
|
|||||||
'i18n_trial_end_start_notice' => __( 'Please enter a date after the start date.', 'woocommerce-subscriptions' ),
|
'i18n_trial_end_start_notice' => __( 'Please enter a date after the start date.', 'woocommerce-subscriptions' ),
|
||||||
'i18n_trial_end_next_notice' => __( 'Please enter a date before the next payment.', 'woocommerce-subscriptions' ),
|
'i18n_trial_end_next_notice' => __( 'Please enter a date before the next payment.', 'woocommerce-subscriptions' ),
|
||||||
'i18n_end_date_notice' => __( 'Please enter a date after the next payment.', 'woocommerce-subscriptions' ),
|
'i18n_end_date_notice' => __( 'Please enter a date after the next payment.', 'woocommerce-subscriptions' ),
|
||||||
|
'i18n_invalid_date_notice' => __( 'Invalid date', 'woocommerce-subscriptions' ),
|
||||||
'process_renewal_action_warning' => __( "Are you sure you want to process a renewal?\n\nThis will charge the customer and email them the renewal order (if emails are enabled).", 'woocommerce-subscriptions' ),
|
'process_renewal_action_warning' => __( "Are you sure you want to process a renewal?\n\nThis will charge the customer and email them the renewal order (if emails are enabled).", 'woocommerce-subscriptions' ),
|
||||||
'payment_method' => $subscription->get_payment_method(),
|
'payment_method' => $subscription->get_payment_method(),
|
||||||
'search_customers_nonce' => wp_create_nonce( 'search-customers' ),
|
'search_customers_nonce' => wp_create_nonce( 'search-customers' ),
|
||||||
@@ -244,7 +245,7 @@ class WCS_Admin_Meta_Boxes {
|
|||||||
/**
|
/**
|
||||||
* Handles the action request to process a renewal order.
|
* Handles the action request to process a renewal order.
|
||||||
*
|
*
|
||||||
* @param array $subscription
|
* @param WC_Subscription $subscription
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
public static function process_renewal_action_request( $subscription ) {
|
public static function process_renewal_action_request( $subscription ) {
|
||||||
@@ -321,7 +322,7 @@ class WCS_Admin_Meta_Boxes {
|
|||||||
/**
|
/**
|
||||||
* Handles the action request to create a pending parent order.
|
* Handles the action request to create a pending parent order.
|
||||||
*
|
*
|
||||||
* @param array $subscription
|
* @param WC_Subscription $subscription
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.3
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.3
|
||||||
*/
|
*/
|
||||||
public static function create_pending_parent_action_request( $subscription ) {
|
public static function create_pending_parent_action_request( $subscription ) {
|
||||||
@@ -351,7 +352,7 @@ class WCS_Admin_Meta_Boxes {
|
|||||||
/**
|
/**
|
||||||
* Removes order related emails from the available actions.
|
* Removes order related emails from the available actions.
|
||||||
*
|
*
|
||||||
* @param array $available_emails
|
* @param array $email_actions
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
public static function remove_order_email_actions( $email_actions ) {
|
public static function remove_order_email_actions( $email_actions ) {
|
||||||
@@ -398,6 +399,7 @@ class WCS_Admin_Meta_Boxes {
|
|||||||
private static function can_renewal_order_be_retried( $order ) {
|
private static function can_renewal_order_be_retried( $order ) {
|
||||||
|
|
||||||
$can_be_retried = false;
|
$can_be_retried = false;
|
||||||
|
$is_automatic = false;
|
||||||
|
|
||||||
if ( wcs_order_contains_renewal( $order ) && $order->needs_payment() && '' != wcs_get_objects_property( $order, 'payment_method' ) ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
|
if ( wcs_order_contains_renewal( $order ) && $order->needs_payment() && '' != wcs_get_objects_property( $order, 'payment_method' ) ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
|
||||||
$supports_date_changes = false;
|
$supports_date_changes = false;
|
||||||
@@ -461,11 +463,14 @@ class WCS_Admin_Meta_Boxes {
|
|||||||
|
|
||||||
$needs_price_lock = false;
|
$needs_price_lock = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var WC_Order_Item_Product $line_item
|
||||||
|
*/
|
||||||
foreach ( $order->get_items() as $line_item ) {
|
foreach ( $order->get_items() as $line_item ) {
|
||||||
$product = $line_item->get_product();
|
$product = $line_item->get_product();
|
||||||
|
|
||||||
// If the line item price is above the current live price.
|
// If the line item price is above the current live price.
|
||||||
if ( $product && ( $line_item->get_subtotal() / $line_item->get_quantity() ) > $product->get_price() ) {
|
if ( $product && ( (float) $line_item->get_subtotal() / $line_item->get_quantity() ) > $product->get_price() ) {
|
||||||
$needs_price_lock = true;
|
$needs_price_lock = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -520,7 +525,7 @@ class WCS_Admin_Meta_Boxes {
|
|||||||
*
|
*
|
||||||
* @param int $item_id The ID of the order item added.
|
* @param int $item_id The ID of the order item added.
|
||||||
* @param WC_Order_Item_Product $line_item The line item added.
|
* @param WC_Order_Item_Product $line_item The line item added.
|
||||||
* @param WC_Abstract_Order $order The order or subscription the product was added to.
|
* @param WC_Order $order The order or subscription the product was added to.
|
||||||
*/
|
*/
|
||||||
public static function store_item_base_location_tax( $item_id, $line_item, $order ) {
|
public static function store_item_base_location_tax( $item_id, $line_item, $order ) {
|
||||||
if ( ! apply_filters( 'woocommerce_adjust_non_base_location_prices', true ) ) {
|
if ( ! apply_filters( 'woocommerce_adjust_non_base_location_prices', true ) ) {
|
||||||
@@ -687,21 +692,25 @@ class WCS_Admin_Meta_Boxes {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var WC_Order_Item_Product $line_item
|
||||||
|
*/
|
||||||
$new_line_subtotal = wc_format_decimal( $new_line_subtotal );
|
$new_line_subtotal = wc_format_decimal( $new_line_subtotal );
|
||||||
$current_base_location_taxes = $line_item->get_meta( '_subtracted_base_location_taxes' );
|
$current_base_location_taxes = $line_item->get_meta( '_subtracted_base_location_taxes' );
|
||||||
$old_line_subtotal = $line_item->get_subtotal();
|
$old_line_subtotal = $line_item->get_subtotal();
|
||||||
$old_line_quantity = $line_item->get_quantity();
|
$old_line_quantity = $line_item->get_quantity();
|
||||||
$new_line_quantity = absint( $item_data['order_item_qty'][ $line_item_id ] );
|
$new_line_quantity = absint( $item_data['order_item_qty'][ $line_item_id ] );
|
||||||
|
$new_base_taxes = array();
|
||||||
|
|
||||||
if ( $line_item->meta_exists( '_subtracted_base_location_rates' ) ) {
|
if ( $line_item->meta_exists( '_subtracted_base_location_rates' ) ) {
|
||||||
$base_tax_rates = $line_item->get_meta( '_subtracted_base_location_rates' );
|
$base_tax_rates = $line_item->get_meta( '_subtracted_base_location_rates' );
|
||||||
$product_price = ( $new_line_subtotal + array_sum( WC_Tax::calc_exclusive_tax( $new_line_subtotal, $base_tax_rates ) ) ) / $new_line_quantity;
|
$product_price = ( (float) $new_line_subtotal + array_sum( WC_Tax::calc_exclusive_tax( $new_line_subtotal, $base_tax_rates ) ) ) / $new_line_quantity;
|
||||||
|
|
||||||
$new_base_taxes = WC_Tax::calc_tax( $product_price, $base_tax_rates, true );
|
$new_base_taxes = WC_Tax::calc_tax( $product_price, $base_tax_rates, true );
|
||||||
} else {
|
} else {
|
||||||
// Update all the base taxes for the new product subtotal.
|
// Update all the base taxes for the new product subtotal.
|
||||||
foreach ( $current_base_location_taxes as $rate_id => $tax_amount ) {
|
foreach ( $current_base_location_taxes as $rate_id => $tax_amount ) {
|
||||||
$new_base_taxes[ $rate_id ] = ( ( $new_line_subtotal / $new_line_quantity ) / ( $old_line_subtotal / $old_line_quantity ) ) * $tax_amount;
|
$new_base_taxes[ $rate_id ] = ( ( (float) $new_line_subtotal / $new_line_quantity ) / ( (float) $old_line_subtotal / $old_line_quantity ) ) * $tax_amount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -82,7 +82,7 @@ class WCS_Admin_Post_Types {
|
|||||||
// Add Subscription list table status views when HPOS is enabled.
|
// Add Subscription list table status views when HPOS is enabled.
|
||||||
add_filter( 'views_woocommerce_page_wc-orders--shop_subscription', array( $this, 'filter_subscription_list_table_views' ) );
|
add_filter( 'views_woocommerce_page_wc-orders--shop_subscription', array( $this, 'filter_subscription_list_table_views' ) );
|
||||||
|
|
||||||
add_action( 'list_table_primary_column', array( $this, 'list_table_primary_column' ), 10, 2 );
|
add_filter( 'list_table_primary_column', array( $this, 'list_table_primary_column' ), 10, 2 );
|
||||||
add_filter( 'post_row_actions', array( $this, 'shop_subscription_row_actions' ), 10, 2 );
|
add_filter( 'post_row_actions', array( $this, 'shop_subscription_row_actions' ), 10, 2 );
|
||||||
|
|
||||||
add_filter( 'handle_bulk_actions-woocommerce_page_wc-orders--shop_subscription', [ $this, 'handle_subscription_bulk_actions' ], 10, 3 );
|
add_filter( 'handle_bulk_actions-woocommerce_page_wc-orders--shop_subscription', [ $this, 'handle_subscription_bulk_actions' ], 10, 3 );
|
||||||
@@ -212,8 +212,6 @@ class WCS_Admin_Post_Types {
|
|||||||
* Displays the dropdown for the product filter
|
* Displays the dropdown for the product filter
|
||||||
*
|
*
|
||||||
* @param string $order_type The type of order. This will be 'shop_subscription' for Subscriptions.
|
* @param string $order_type The type of order. This will be 'shop_subscription' for Subscriptions.
|
||||||
*
|
|
||||||
* @return string the html dropdown element
|
|
||||||
*/
|
*/
|
||||||
public function restrict_by_product( $order_type = '' ) {
|
public function restrict_by_product( $order_type = '' ) {
|
||||||
if ( '' === $order_type ) {
|
if ( '' === $order_type ) {
|
||||||
@@ -1171,6 +1169,7 @@ class WCS_Admin_Post_Types {
|
|||||||
<option value="none" <?php echo esc_attr( 'none' === $selected_gateway_id ? 'selected' : '' ) . '>' . esc_html__( 'None', 'woocommerce-subscriptions' ); ?></option>
|
<option value="none" <?php echo esc_attr( 'none' === $selected_gateway_id ? 'selected' : '' ) . '>' . esc_html__( 'None', 'woocommerce-subscriptions' ); ?></option>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
// @phpstan-ignore property.notFound
|
||||||
foreach ( WC()->payment_gateways->get_available_payment_gateways() as $gateway_id => $gateway ) {
|
foreach ( WC()->payment_gateways->get_available_payment_gateways() as $gateway_id => $gateway ) {
|
||||||
echo '<option value="' . esc_attr( $gateway_id ) . '"' . ( $selected_gateway_id === $gateway_id ? 'selected' : '' ) . '>' . esc_html( $gateway->title ) . '</option>';
|
echo '<option value="' . esc_attr( $gateway_id ) . '"' . ( $selected_gateway_id === $gateway_id ? 'selected' : '' ) . '>' . esc_html( $gateway->title ) . '</option>';
|
||||||
}
|
}
|
||||||
@@ -1243,7 +1242,7 @@ class WCS_Admin_Post_Types {
|
|||||||
* Get the HTML for order item meta to display on the Subscription list table.
|
* Get the HTML for order item meta to display on the Subscription list table.
|
||||||
*
|
*
|
||||||
* @param WC_Order_Item $item
|
* @param WC_Order_Item $item
|
||||||
* @param WC_Product $product
|
* @param WC_Product $_product
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected static function get_item_name_html( $item, $_product, $include_quantity = 'include_quantity' ) {
|
protected static function get_item_name_html( $item, $_product, $include_quantity = 'include_quantity' ) {
|
||||||
@@ -1276,9 +1275,9 @@ class WCS_Admin_Post_Types {
|
|||||||
* On the Subscriptions list table, subscriptions with multiple items display those line items in a table.
|
* On the Subscriptions list table, subscriptions with multiple items display those line items in a table.
|
||||||
* This function generates an individual row for a specific line item.
|
* This function generates an individual row for a specific line item.
|
||||||
*
|
*
|
||||||
* @param WC_Line_Item_Product $item The line item product object.
|
* @param WC_Order_Item_Product $item The line item product object.
|
||||||
* @param string $item_name The line item's name.
|
* @param string $item_name The line item's name.
|
||||||
* @param string $item_meta_html The line item's meta HTML generated by @see wc_display_item_meta().
|
* @param string $item_meta_html The line item's meta HTML generated by @see wc_display_item_meta().
|
||||||
*
|
*
|
||||||
* @return string The table row HTML content for a line item.
|
* @return string The table row HTML content for a line item.
|
||||||
*/
|
*/
|
||||||
@@ -1489,7 +1488,7 @@ class WCS_Admin_Post_Types {
|
|||||||
/**
|
/**
|
||||||
* Handles bulk updating the status subscriptions.
|
* Handles bulk updating the status subscriptions.
|
||||||
*
|
*
|
||||||
* @param array $ids Subscription IDs to be trashed or deleted.
|
* @param array $subscription_ids Subscription IDs to be trashed or deleted.
|
||||||
* @param string $new_status The new status to update the subscriptions to.
|
* @param string $new_status The new status to update the subscriptions to.
|
||||||
*
|
*
|
||||||
* @return array Array of query args to redirect to after handling the bulk action request.
|
* @return array Array of query args to redirect to after handling the bulk action request.
|
||||||
@@ -1529,7 +1528,7 @@ class WCS_Admin_Post_Types {
|
|||||||
/**
|
/**
|
||||||
* Handles bulk trashing and deleting of subscriptions.
|
* Handles bulk trashing and deleting of subscriptions.
|
||||||
*
|
*
|
||||||
* @param array $ids Subscription IDs to be trashed or deleted.
|
* @param array $subscription_ids Subscription IDs to be trashed or deleted.
|
||||||
* @param bool $force_delete When set, the subscription will be completed deleted. Otherwise, it will be trashed.
|
* @param bool $force_delete When set, the subscription will be completed deleted. Otherwise, it will be trashed.
|
||||||
*
|
*
|
||||||
* @return array Array of query args to redirect to after handling the bulk action request.
|
* @return array Array of query args to redirect to after handling the bulk action request.
|
||||||
@@ -1557,7 +1556,7 @@ class WCS_Admin_Post_Types {
|
|||||||
/**
|
/**
|
||||||
* Handles bulk untrashing of subscriptions.
|
* Handles bulk untrashing of subscriptions.
|
||||||
*
|
*
|
||||||
* @param array $ids Subscription IDs to be restored.
|
* @param array $subscription_ids Subscription IDs to be restored.
|
||||||
*
|
*
|
||||||
* @return array Array of query args to redirect to after handling the bulk action request.
|
* @return array Array of query args to redirect to after handling the bulk action request.
|
||||||
*/
|
*/
|
||||||
@@ -1696,13 +1695,13 @@ class WCS_Admin_Post_Types {
|
|||||||
*
|
*
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v3.0.7
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v3.0.7
|
||||||
*
|
*
|
||||||
* @param WC_Line_Item_Product $item The subscription line item object.
|
* @param WC_Order_Item_Product $item The subscription line item object.
|
||||||
* @param WC_Subscription $subscription The subscription object. This variable is no longer used.
|
* @param WC_Subscription $subscription The subscription object. This variable is no longer used.
|
||||||
* @param string $element The type of element to generate. Can be 'div' or 'row'. Default is 'div'.
|
* @param string $element The type of element to generate. Can be 'div' or 'row'. Default is 'div'.
|
||||||
*
|
*
|
||||||
* @return string The line item column HTML content for a line item.
|
* @return string The line item column HTML content for a line item.
|
||||||
*/
|
*/
|
||||||
protected static function get_item_display( $item, $subscription = '', $element = 'div' ) {
|
protected static function get_item_display( $item, $subscription = null, $element = 'div' ) {
|
||||||
wcs_deprecated_function( __METHOD__, '3.0.7' );
|
wcs_deprecated_function( __METHOD__, '3.0.7' );
|
||||||
$_product = $item->get_product();
|
$_product = $item->get_product();
|
||||||
$item_meta_html = self::get_item_meta_html( $item );
|
$item_meta_html = self::get_item_meta_html( $item );
|
||||||
@@ -1723,9 +1722,9 @@ class WCS_Admin_Post_Types {
|
|||||||
*
|
*
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v3.0.7
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v3.0.7
|
||||||
*
|
*
|
||||||
* @param WC_Line_Item_Product $item The line item object.
|
* @param WC_Order_Item_Product $item The line item object.
|
||||||
* @param string $item_name The line item's name.
|
* @param string $item_name The line item's name.
|
||||||
* @param string $item_meta_html The line item's meta HTML.
|
* @param string $item_meta_html The line item's meta HTML.
|
||||||
*
|
*
|
||||||
* @return string The subscription line item column HTML content.
|
* @return string The subscription line item column HTML content.
|
||||||
*/
|
*/
|
||||||
@@ -1814,7 +1813,7 @@ class WCS_Admin_Post_Types {
|
|||||||
* - Low performance: This method uses a subquery to get the last payment date for each subscription.
|
* - Low performance: This method uses a subquery to get the last payment date for each subscription.
|
||||||
*
|
*
|
||||||
* @param string[] $pieces Associative array of the clauses for the query.
|
* @param string[] $pieces Associative array of the clauses for the query.
|
||||||
* @param OrdersTableQuery $query The query object.
|
* @param string $query The query object.
|
||||||
* @param array $args Query args.
|
* @param array $args Query args.
|
||||||
*
|
*
|
||||||
* @return string[] $pieces Associative array of the clauses for the query.
|
* @return string[] $pieces Associative array of the clauses for the query.
|
||||||
@@ -1869,6 +1868,7 @@ class WCS_Admin_Post_Types {
|
|||||||
* @return string[] $pieces Updated associative array of clauses for the query.
|
* @return string[] $pieces Updated associative array of clauses for the query.
|
||||||
*/
|
*/
|
||||||
private function orders_table_clauses_low_performance( $pieces ) {
|
private function orders_table_clauses_low_performance( $pieces ) {
|
||||||
|
// @phpstan-ignore-next-line
|
||||||
$order_datastore = wc_get_container()->get( \Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore::class );
|
$order_datastore = wc_get_container()->get( \Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore::class );
|
||||||
$order_table = $order_datastore::get_orders_table_name();
|
$order_table = $order_datastore::get_orders_table_name();
|
||||||
$meta_table = $order_datastore::get_meta_table_name();
|
$meta_table = $order_datastore::get_meta_table_name();
|
||||||
@@ -1899,6 +1899,7 @@ class WCS_Admin_Post_Types {
|
|||||||
private function orders_table_clauses_high_performance( $pieces ) {
|
private function orders_table_clauses_high_performance( $pieces ) {
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
|
|
||||||
|
// @phpstan-ignore-next-line
|
||||||
$order_datastore = wc_get_container()->get( \Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore::class );
|
$order_datastore = wc_get_container()->get( \Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore::class );
|
||||||
$order_table = $order_datastore::get_orders_table_name();
|
$order_table = $order_datastore::get_orders_table_name();
|
||||||
$meta_table = $order_datastore::get_meta_table_name();
|
$meta_table = $order_datastore::get_meta_table_name();
|
||||||
|
@@ -53,7 +53,7 @@ final class WCS_Debug_Tool_Factory {
|
|||||||
/**
|
/**
|
||||||
* Get the string used to identify the tool.
|
* Get the string used to identify the tool.
|
||||||
*
|
*
|
||||||
* @param string The name of the cache tool being created
|
* @param string $tool_name The name of the cache tool being created
|
||||||
* @return string The key used to identify the tool - sanitized name with wcs_ prefix.
|
* @return string The key used to identify the tool - sanitized name with wcs_ prefix.
|
||||||
*/
|
*/
|
||||||
protected static function get_tool_key( $tool_name ) {
|
protected static function get_tool_key( $tool_name ) {
|
||||||
|
@@ -46,8 +46,8 @@ class WCS_Meta_Box_Schedule {
|
|||||||
*
|
*
|
||||||
* @see woocommerce_process_shop_order_meta
|
* @see woocommerce_process_shop_order_meta
|
||||||
*
|
*
|
||||||
* @param int $subscription_id The subscription ID to save the schedule for.
|
* @param int $subscription_id The subscription ID to save the schedule for.
|
||||||
* @param WC_Subscription/WP_Post $subscription The subscription object to save the schedule for.
|
* @param WC_Subscription $subscription The subscription object to save the schedule for.
|
||||||
*/
|
*/
|
||||||
public static function save( $subscription_id, $subscription ) {
|
public static function save( $subscription_id, $subscription ) {
|
||||||
|
|
||||||
@@ -71,7 +71,8 @@ class WCS_Meta_Box_Schedule {
|
|||||||
$subscription->set_billing_period( wc_clean( wp_unslash( $_POST['_billing_period'] ) ) );
|
$subscription->set_billing_period( wc_clean( wp_unslash( $_POST['_billing_period'] ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
$dates = array();
|
$dates = array();
|
||||||
|
$invalid_dates = array();
|
||||||
|
|
||||||
foreach ( wcs_get_subscription_date_types() as $date_type => $date_label ) {
|
foreach ( wcs_get_subscription_date_types() as $date_type => $date_label ) {
|
||||||
$date_key = wcs_normalise_date_type_key( $date_type );
|
$date_key = wcs_normalise_date_type_key( $date_type );
|
||||||
@@ -91,7 +92,13 @@ class WCS_Meta_Box_Schedule {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$dates[ $date_key ] = gmdate( 'Y-m-d H:i:s', $datetime );
|
$timestamp = wcs_date_to_time( $datetime );
|
||||||
|
|
||||||
|
if ( null !== $timestamp ) {
|
||||||
|
$dates[ $date_key ] = $timestamp;
|
||||||
|
} else {
|
||||||
|
$invalid_dates[ $date_key ] = $datetime;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -101,10 +108,57 @@ class WCS_Meta_Box_Schedule {
|
|||||||
if ( ! wcs_is_custom_order_tables_usage_enabled() ) {
|
if ( ! wcs_is_custom_order_tables_usage_enabled() ) {
|
||||||
wp_cache_delete( $subscription_id, 'posts' );
|
wp_cache_delete( $subscription_id, 'posts' );
|
||||||
}
|
}
|
||||||
} catch ( Exception $e ) {
|
|
||||||
|
$subscription->save();
|
||||||
|
|
||||||
|
if ( ! empty( $invalid_dates ) ) {
|
||||||
|
$subscription_date_types = wcs_get_subscription_date_types();
|
||||||
|
$invalid_dates_labels = array_map(
|
||||||
|
function ( $date_type ) use ( $subscription_date_types ) {
|
||||||
|
// Fallback to the date type key in case there is no translation string.
|
||||||
|
return isset( $subscription_date_types[ $date_type ] ) ? $subscription_date_types[ $date_type ] : $date_type;
|
||||||
|
},
|
||||||
|
array_keys( $invalid_dates )
|
||||||
|
);
|
||||||
|
|
||||||
|
$warning_message = sprintf(
|
||||||
|
// translators: 1$ is a comma-separated list of invalid dates fields like "Start Date", "Next Payment", 2$-3$: opening and closing <strong> tags.
|
||||||
|
__( 'Some subscription dates could not be updated because they contain invalid values: %2$s%1$s%3$s. Please correct these dates and save the changes.', 'woocommerce-subscriptions' ),
|
||||||
|
esc_html( implode( ', ', $invalid_dates_labels ) ),
|
||||||
|
'<strong>',
|
||||||
|
'</strong>'
|
||||||
|
);
|
||||||
|
|
||||||
|
wc_get_logger()->warning(
|
||||||
|
$warning_message,
|
||||||
|
array(
|
||||||
|
'subscription_id' => $subscription_id,
|
||||||
|
'invalid_dates' => $invalid_dates,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
wcs_add_admin_notice(
|
||||||
|
$warning_message,
|
||||||
|
'error', // There is no warning level for admin notices, so using error level.
|
||||||
|
get_current_user_id(),
|
||||||
|
get_current_screen()->id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch ( \Throwable $e ) {
|
||||||
|
// Log the error.
|
||||||
|
wc_get_logger()->error(
|
||||||
|
sprintf(
|
||||||
|
'Error updating subscription #%d: %s',
|
||||||
|
$subscription_id,
|
||||||
|
$e->getMessage(),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'stack_trace' => $e->getTraceAsString(),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Display an admin notice.
|
||||||
wcs_add_admin_notice( $e->getMessage(), 'error' );
|
wcs_add_admin_notice( $e->getMessage(), 'error' );
|
||||||
}
|
}
|
||||||
|
|
||||||
$subscription->save();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -44,7 +44,10 @@ class WCS_Meta_Box_Subscription_Data extends WC_Meta_Box_Order_Data {
|
|||||||
#post-body-content, #titlediv, #major-publishing-actions, #minor-publishing-actions, #visibility, #submitdiv { display:none }
|
#post-body-content, #titlediv, #major-publishing-actions, #minor-publishing-actions, #visibility, #submitdiv { display:none }
|
||||||
</style>
|
</style>
|
||||||
<div class="panel-wrap woocommerce">
|
<div class="panel-wrap woocommerce">
|
||||||
<input name="post_title" type="hidden" value="<?php echo empty( $order_title ) ? esc_attr( get_post_type_object( $subscription->get_type() )->labels->singular_name ) : esc_attr( $subscription_title ); ?>" />
|
<input name="post_title" type="hidden" value="<?php
|
||||||
|
// @phpstan-ignore empty.variable
|
||||||
|
echo empty( $order_title ) ? esc_attr( get_post_type_object( $subscription->get_type() )->labels->singular_name ) : esc_attr( $subscription_title );
|
||||||
|
?>" />
|
||||||
<input name="post_status" type="hidden" value="<?php echo esc_attr( 'wc-' . $subscription->get_status() ); ?>" />
|
<input name="post_status" type="hidden" value="<?php echo esc_attr( 'wc-' . $subscription->get_status() ); ?>" />
|
||||||
<div id="order_data" class="panel">
|
<div id="order_data" class="panel">
|
||||||
|
|
||||||
|
@@ -61,6 +61,10 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
<?php else : ?>
|
<?php else : ?>
|
||||||
<?php echo esc_html( $the_subscription->get_date_to_display( $internal_date_key ) ); ?>
|
<?php echo esc_html( $the_subscription->get_date_to_display( $internal_date_key ) ); ?>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
<div class="message" aria-live="assertive" aria-atomic="true" role="alert" style="display: none;">
|
||||||
|
<span class="screen-reader-text"><?php esc_html_e( 'Error:', 'woocommerce-subscriptions' ); ?></span>
|
||||||
|
<span class="message-content"></span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
<p><?php esc_html_e( 'Timezone:', 'woocommerce-subscriptions' ); ?> <span id="wcs-timezone"><?php esc_html_e( 'Error: unable to find timezone of your browser.', 'woocommerce-subscriptions' ); ?></span></p>
|
<p><?php esc_html_e( 'Timezone:', 'woocommerce-subscriptions' ); ?> <span id="wcs-timezone"><?php esc_html_e( 'Error: unable to find timezone of your browser.', 'woocommerce-subscriptions' ); ?></span></p>
|
||||||
|
@@ -287,8 +287,10 @@ class WC_Product_Variable_Subscription extends WC_Product_Variable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Use WC core add-to-cart handlers for subscription products.
|
||||||
*
|
*
|
||||||
* @param string $product_type A string representation of a product type
|
* @param string $handler The name of the handler to use when adding product to the cart
|
||||||
|
* @param WC_Product $product
|
||||||
*/
|
*/
|
||||||
public function add_to_cart_handler( $handler, $product ) {
|
public function add_to_cart_handler( $handler, $product ) {
|
||||||
wcs_deprecated_function( __METHOD__, '2.2.0', 'WC_Subscriptions_Cart::add_to_cart_handler( $handler, $product )' );
|
wcs_deprecated_function( __METHOD__, '2.2.0', 'WC_Subscriptions_Cart::add_to_cart_handler( $handler, $product )' );
|
||||||
@@ -298,10 +300,11 @@ class WC_Product_Variable_Subscription extends WC_Product_Variable {
|
|||||||
/**
|
/**
|
||||||
* Sync variable product prices with the children lowest/highest prices.
|
* Sync variable product prices with the children lowest/highest prices.
|
||||||
*
|
*
|
||||||
* @access public
|
* @param int $product_id The ID of the product to sync.
|
||||||
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function variable_product_sync( $product_id = '' ) {
|
public function variable_product_sync( $product_id = 0 ) {
|
||||||
wcs_deprecated_function( __METHOD__, '2.2,0', 'WC_Subscriptions_Product::variable_subscription_product_sync( $this )' );
|
wcs_deprecated_function( __METHOD__, '2.2,0', 'WC_Subscriptions_Product::variable_subscription_product_sync( $this )' );
|
||||||
|
|
||||||
if ( empty( $product_id ) ) {
|
if ( empty( $product_id ) ) {
|
||||||
|
@@ -75,8 +75,8 @@ class WC_Subscription_Query_Controller {
|
|||||||
/**
|
/**
|
||||||
* Filters the subscription query results by product ID or variation ID.
|
* Filters the subscription query results by product ID or variation ID.
|
||||||
*
|
*
|
||||||
* @param WC_Subscriptions[] $subscriptions
|
* @param WC_Subscription[] $subscriptions
|
||||||
* @return WC_Subscriptions[] The filtered subscriptions.
|
* @return WC_Subscription[] The filtered subscriptions.
|
||||||
*/
|
*/
|
||||||
public function filter_subscriptions( $subscriptions ) {
|
public function filter_subscriptions( $subscriptions ) {
|
||||||
$filtered_subscriptions = [];
|
$filtered_subscriptions = [];
|
||||||
|
@@ -332,7 +332,7 @@ class WC_Subscription extends WC_Order {
|
|||||||
|
|
||||||
switch ( $new_status ) {
|
switch ( $new_status ) {
|
||||||
case 'pending':
|
case 'pending':
|
||||||
if ( $this->has_status( array( 'auto-draft', 'draft' ) ) ) {
|
if ( $this->has_status( array( 'auto-draft', 'draft', 'on-hold' ) ) ) {
|
||||||
$can_be_updated = true;
|
$can_be_updated = true;
|
||||||
} else {
|
} else {
|
||||||
$can_be_updated = false;
|
$can_be_updated = false;
|
||||||
@@ -358,7 +358,7 @@ class WC_Subscription extends WC_Order {
|
|||||||
break;
|
break;
|
||||||
case 'failed': // core WC order status mapped internally to avoid exceptions
|
case 'failed': // core WC order status mapped internally to avoid exceptions
|
||||||
case 'on-hold':
|
case 'on-hold':
|
||||||
if ( $this->payment_method_supports( 'subscription_suspension' ) && $this->has_status( array( 'active', 'pending' ) ) ) {
|
if ( $this->payment_method_supports( 'subscription_suspension' ) && $this->has_status( array( 'active' ) ) ) {
|
||||||
$can_be_updated = true;
|
$can_be_updated = true;
|
||||||
} else {
|
} else {
|
||||||
$can_be_updated = false;
|
$can_be_updated = false;
|
||||||
@@ -420,11 +420,12 @@ class WC_Subscription extends WC_Order {
|
|||||||
*
|
*
|
||||||
* @param string $new_status Status to change the order to. No internal wc- prefix is required.
|
* @param string $new_status Status to change the order to. No internal wc- prefix is required.
|
||||||
* @param string $note (default: '') Optional note to add
|
* @param string $note (default: '') Optional note to add
|
||||||
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function update_status( $new_status, $note = '', $manual = false ) {
|
public function update_status( $new_status, $note = '', $manual = false ) {
|
||||||
|
|
||||||
if ( ! $this->get_id() ) {
|
if ( ! $this->get_id() ) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Standardise status names.
|
// Standardise status names.
|
||||||
@@ -574,6 +575,8 @@ class WC_Subscription extends WC_Order {
|
|||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -662,9 +665,9 @@ class WC_Subscription extends WC_Order {
|
|||||||
*
|
*
|
||||||
* @since 5.1.0
|
* @since 5.1.0
|
||||||
*
|
*
|
||||||
* @param string $new_status The new status.
|
* @param string $new_status The new status.
|
||||||
* @param string $note Optional. The note to add to the subscription.
|
* @param string $note Optional. The note to add to the subscription.
|
||||||
* @param bool $manual Optional. Is the status change triggered manually? Default is false.
|
* @param bool $manual_update Optional. Is the status change triggered manually? Default is false.
|
||||||
*/
|
*/
|
||||||
public function set_status( $new_status, $note = '', $manual_update = false ) {
|
public function set_status( $new_status, $note = '', $manual_update = false ) {
|
||||||
if ( ! $this->object_read && in_array( $new_status, [ 'draft', 'auto-draft' ], true ) ) {
|
if ( ! $this->object_read && in_array( $new_status, [ 'draft', 'auto-draft' ], true ) ) {
|
||||||
@@ -1191,7 +1194,7 @@ class WC_Subscription extends WC_Order {
|
|||||||
* Used for WC 3.0 compatibility and for WC_Subscription_Legacy to override.
|
* Used for WC 3.0 compatibility and for WC_Subscription_Legacy to override.
|
||||||
*
|
*
|
||||||
* @param string $date_type 'trial_end', 'next_payment', 'cancelled', 'payment_retry' or 'end'
|
* @param string $date_type 'trial_end', 'next_payment', 'cancelled', 'payment_retry' or 'end'
|
||||||
* @param string|integer|null $date UTC timestamp, or ISO 8601 DateTime. If the DateTime string has no timezone or offset, WordPress site timezone will be assumed. Null if their is no date.
|
* @param string|integer|null $value UTC timestamp, or ISO 8601 DateTime. If the DateTime string has no timezone or offset, WordPress site timezone will be assumed. Null if their is no date.
|
||||||
*/
|
*/
|
||||||
protected function set_date_prop( $date_type, $value ) {
|
protected function set_date_prop( $date_type, $value ) {
|
||||||
parent::set_date_prop( $this->get_date_prop_key( $date_type ), $value );
|
parent::set_date_prop( $this->get_date_prop_key( $date_type ), $value );
|
||||||
@@ -1323,7 +1326,7 @@ class WC_Subscription extends WC_Order {
|
|||||||
/**
|
/**
|
||||||
* Formats a subscription date timestamp for display.
|
* Formats a subscription date timestamp for display.
|
||||||
*
|
*
|
||||||
* @param int $timestamp The subscription date in a timestamp format.
|
* @param int $timestamp_gmt The subscription date in a timestamp format.
|
||||||
* @param string $date_type The subscription date type to display. @see WC_Subscription::get_valid_date_types()
|
* @param string $date_type The subscription date type to display. @see WC_Subscription::get_valid_date_types()
|
||||||
*
|
*
|
||||||
* @return string The formatted date to display.
|
* @return string The formatted date to display.
|
||||||
@@ -1385,14 +1388,67 @@ class WC_Subscription extends WC_Order {
|
|||||||
/**
|
/**
|
||||||
* Set the dates on the subscription.
|
* Set the dates on the subscription.
|
||||||
*
|
*
|
||||||
* Because dates are interdependent on each other, this function will take an array of dates, make sure that all
|
* This method is more strict than update_valid_dates() in that it will throw an exception if any of the dates are not in the correct format or are not compatible with the current subscription dates.
|
||||||
* dates are in the right order in the right format, that there is at least something to update.
|
*
|
||||||
|
* @see update_valid_dates() for a more permissive alternative that allows ignoring invalid dates.
|
||||||
*
|
*
|
||||||
* @param array $dates array containing dates with keys: 'date_created', 'trial_end', 'next_payment', 'last_order_date_created' or 'end'. Values are MySQL formatted date/time strings in UTC timezone.
|
* @param array $dates array containing dates with keys: 'date_created', 'trial_end', 'next_payment', 'last_order_date_created' or 'end'. Values are MySQL formatted date/time strings in UTC timezone.
|
||||||
* @param string $timezone The timezone of the $datetime param. Default 'gmt'.
|
* @param string $timezone The timezone of the $datetime param. Default 'gmt'.
|
||||||
|
* @return bool True if the dates were updated, false otherwise.
|
||||||
|
* @throws InvalidArgumentException if the dates are not in the correct format or are not compatible with the current subscription dates.
|
||||||
*/
|
*/
|
||||||
public function update_dates( $dates, $timezone = 'gmt' ) {
|
public function update_dates( $dates, $timezone = 'gmt' ): bool {
|
||||||
$dates = $this->validate_date_updates( $dates, $timezone );
|
return $this->flexible_update_dates(
|
||||||
|
$dates,
|
||||||
|
array(
|
||||||
|
'timezone' => $timezone,
|
||||||
|
'ignore_invalid_dates' => false,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the dates on the subscription.
|
||||||
|
*
|
||||||
|
* This method is more permissive than update_dates() in that it will ignore invalid date values and save only valid values.
|
||||||
|
* It still throws an exception if the date values are in the wrong order.
|
||||||
|
*
|
||||||
|
* @see update_dates() for a more strict alternative that will throw an exception if any of the dates are not in the correct format or are not compatible with the current subscription dates.
|
||||||
|
*
|
||||||
|
* @param array $dates array containing dates with keys: 'date_created', 'trial_end', 'next_payment', 'last_order_date_created' or 'end'. Values are MySQL formatted date/time strings in UTC timezone.
|
||||||
|
* @param string $timezone The timezone of the $datetime param. Default 'gmt'.
|
||||||
|
* @return bool True if the dates were updated, false otherwise.
|
||||||
|
* @throws InvalidArgumentException if the dates are not in the correct format or are not compatible with the current subscription dates.
|
||||||
|
*
|
||||||
|
* @since 7.7.0 More permissive alternative to update_dates().
|
||||||
|
*/
|
||||||
|
public function update_valid_dates( $dates, $timezone = 'gmt' ): bool {
|
||||||
|
return $this->flexible_update_dates(
|
||||||
|
$dates,
|
||||||
|
array(
|
||||||
|
'timezone' => $timezone,
|
||||||
|
'ignore_invalid_dates' => true,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the dates on the subscription.
|
||||||
|
*
|
||||||
|
* Because dates are interdependent on each other, this function will take an array of dates,
|
||||||
|
* make sure that all dates are in the right order in the right format, and that there is at least something to update.
|
||||||
|
*
|
||||||
|
* @param array $dates array containing dates with keys: 'date_created', 'trial_end', 'next_payment', 'last_order_date_created' or 'end'. Values are MySQL formatted date/time strings in UTC timezone.
|
||||||
|
* @param array $validation_options array containing the following validation options:
|
||||||
|
* - timezone: The timezone of the $datetime param. Default 'gmt'.
|
||||||
|
* - ignore_invalid_dates: Whether to ignore invalid dates. Default false. When invalid date is ignored, the current value stored on subscription (if any) is used instead.
|
||||||
|
* @return bool True if the dates were updated, false otherwise.
|
||||||
|
* @throws InvalidArgumentException if the dates are not in the correct format or are not compatible with the current subscription dates.
|
||||||
|
*
|
||||||
|
* @since 7.7.0 Shared logic for update_dates() and update_valid_dates().
|
||||||
|
*/
|
||||||
|
private function flexible_update_dates( $dates, $validation_options = array() ): bool {
|
||||||
|
$dates = $this->prepare_dates_for_update( $dates, $validation_options );
|
||||||
|
|
||||||
// If an exception hasn't been thrown by this point, we can safely update the dates
|
// If an exception hasn't been thrown by this point, we can safely update the dates
|
||||||
$is_updated = false;
|
$is_updated = false;
|
||||||
@@ -1454,6 +1510,8 @@ class WC_Subscription extends WC_Order {
|
|||||||
do_action( 'woocommerce_subscription_date_updated', $this, $date_type, $datetime );
|
do_action( 'woocommerce_subscription_date_updated', $this, $date_type, $datetime );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $is_updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1907,11 +1965,12 @@ class WC_Subscription extends WC_Order {
|
|||||||
* Process payment on the subscription, which mainly means processing it for the last order on the subscription.
|
* Process payment on the subscription, which mainly means processing it for the last order on the subscription.
|
||||||
*
|
*
|
||||||
* @param $transaction_id string Optional transaction id to store in post meta
|
* @param $transaction_id string Optional transaction id to store in post meta
|
||||||
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function payment_complete( $transaction_id = '' ) {
|
public function payment_complete( $transaction_id = '' ) {
|
||||||
|
|
||||||
if ( WC_Subscriptions_Change_Payment_Gateway::$is_request_to_change_payment ) {
|
if ( WC_Subscriptions_Change_Payment_Gateway::$is_request_to_change_payment ) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear the cached renewal payment counts, kept here for backward compat even though it's also reset in $this->process_payment_complete()
|
// Clear the cached renewal payment counts, kept here for backward compat even though it's also reset in $this->process_payment_complete()
|
||||||
@@ -1927,12 +1986,14 @@ class WC_Subscription extends WC_Order {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->payment_complete_for_order( $last_order );
|
$this->payment_complete_for_order( $last_order );
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When payment is completed for a related order, reset any renewal related counters and reactive the subscription.
|
* When payment is completed for a related order, reset any renewal related counters and reactive the subscription.
|
||||||
*
|
*
|
||||||
* @param WC_Order $order
|
* @param WC_Order $last_order
|
||||||
*/
|
*/
|
||||||
public function payment_complete_for_order( $last_order ) {
|
public function payment_complete_for_order( $last_order ) {
|
||||||
|
|
||||||
@@ -2370,6 +2431,7 @@ class WC_Subscription extends WC_Order {
|
|||||||
if ( is_a( $payment_method, 'WC_Payment_Gateway' ) ) {
|
if ( is_a( $payment_method, 'WC_Payment_Gateway' ) ) {
|
||||||
$payment_gateway = $payment_method;
|
$payment_gateway = $payment_method;
|
||||||
} else {
|
} else {
|
||||||
|
// @phpstan-ignore property.notFound
|
||||||
$payment_gateways = WC()->payment_gateways->payment_gateways();
|
$payment_gateways = WC()->payment_gateways->payment_gateways();
|
||||||
$payment_gateway = isset( $payment_gateways[ $payment_method_id ] ) ? $payment_gateways[ $payment_method_id ] : null;
|
$payment_gateway = isset( $payment_gateways[ $payment_method_id ] ) ? $payment_gateways[ $payment_method_id ] : null;
|
||||||
}
|
}
|
||||||
@@ -2444,7 +2506,7 @@ class WC_Subscription extends WC_Order {
|
|||||||
/**
|
/**
|
||||||
* Check if the subscription has a line item for a specific product, by ID.
|
* Check if the subscription has a line item for a specific product, by ID.
|
||||||
*
|
*
|
||||||
* @param int A product or variation ID to check for.
|
* @param int $product_id A product or variation ID to check for.
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function has_product( $product_id ) {
|
public function has_product( $product_id ) {
|
||||||
@@ -2498,14 +2560,15 @@ class WC_Subscription extends WC_Order {
|
|||||||
* The single quantity sign-up fee will be returned instead of the total sign-up fee paid. For example, if 3 x a product
|
* The single quantity sign-up fee will be returned instead of the total sign-up fee paid. For example, if 3 x a product
|
||||||
* with a 10 BTC sign-up fee was purchased, a total 30 BTC was paid as the sign-up fee but this function will return 10 BTC.
|
* with a 10 BTC sign-up fee was purchased, a total 30 BTC was paid as the sign-up fee but this function will return 10 BTC.
|
||||||
*
|
*
|
||||||
* @param array|int Either an order item (in the array format returned by self::get_items()) or the ID of an order item.
|
* @param WC_Order_Item_Product|int $line_item Either an order item (in the array format returned by self::get_items()) or the ID of an order item.
|
||||||
* @param string $tax_inclusive_or_exclusive Whether or not to adjust sign up fee if prices inc tax - ensures that the sign up fee paid amount includes the paid tax if inc
|
* @param string $tax_inclusive_or_exclusive Whether or not to adjust sign up fee if prices inc tax - ensures that the sign up fee paid amount includes the paid tax if inc
|
||||||
* @return bool
|
* @return bool
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
public function get_items_sign_up_fee( $line_item, $tax_inclusive_or_exclusive = 'exclusive_of_tax' ) {
|
public function get_items_sign_up_fee( $line_item, $tax_inclusive_or_exclusive = 'exclusive_of_tax' ) {
|
||||||
|
|
||||||
if ( ! is_object( $line_item ) ) {
|
if ( ! is_object( $line_item ) ) {
|
||||||
|
/** @var WC_Order_Item_Product $line_item */
|
||||||
$line_item = wcs_get_order_item( $line_item, $this );
|
$line_item = wcs_get_order_item( $line_item, $this );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2517,12 +2580,10 @@ class WC_Subscription extends WC_Order {
|
|||||||
$sign_up_fee = 0;
|
$sign_up_fee = 0;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
$original_order_item = '';
|
|
||||||
|
|
||||||
// Find the matching item on the order
|
// Find the matching item on the order
|
||||||
foreach ( $parent_order->get_items() as $order_item ) {
|
foreach ( $parent_order->get_items() as $order_item ) {
|
||||||
if ( wcs_get_canonical_product_id( $line_item ) == wcs_get_canonical_product_id( $order_item ) ) {
|
if ( wcs_get_canonical_product_id( $line_item ) == wcs_get_canonical_product_id( $order_item ) ) {
|
||||||
|
/** @var WC_Order_Item_Product $original_order_item */
|
||||||
$original_order_item = $order_item;
|
$original_order_item = $order_item;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2541,7 +2602,7 @@ class WC_Subscription extends WC_Order {
|
|||||||
|
|
||||||
// The synced sign up fee meta contains the raw product sign up fee, if the subscription totals are inclusive of tax, we need to adjust the synced sign up fee to match tax inclusivity.
|
// The synced sign up fee meta contains the raw product sign up fee, if the subscription totals are inclusive of tax, we need to adjust the synced sign up fee to match tax inclusivity.
|
||||||
if ( $this->get_prices_include_tax() ) {
|
if ( $this->get_prices_include_tax() ) {
|
||||||
$line_item_total = (float) $original_order_item->get_total( 'edit' ) + $original_order_item->get_total_tax( 'edit' );
|
$line_item_total = (float) $original_order_item->get_total( 'edit' ) + (float) $original_order_item->get_total_tax( 'edit' );
|
||||||
$signup_fee_portion = $sign_up_fee / $line_item_total;
|
$signup_fee_portion = $sign_up_fee / $line_item_total;
|
||||||
$sign_up_fee = (float) $original_order_item->get_total( 'edit' ) * $signup_fee_portion;
|
$sign_up_fee = (float) $original_order_item->get_total( 'edit' ) * $signup_fee_portion;
|
||||||
}
|
}
|
||||||
@@ -2555,8 +2616,8 @@ class WC_Subscription extends WC_Order {
|
|||||||
|
|
||||||
// If prices don't inc tax, ensure that the sign up fee amount includes the tax.
|
// If prices don't inc tax, ensure that the sign up fee amount includes the tax.
|
||||||
if ( 'inclusive_of_tax' === $tax_inclusive_or_exclusive && ! empty( $original_order_item ) && ! empty( $sign_up_fee ) ) {
|
if ( 'inclusive_of_tax' === $tax_inclusive_or_exclusive && ! empty( $original_order_item ) && ! empty( $sign_up_fee ) ) {
|
||||||
$sign_up_fee_proportion = $sign_up_fee / ( $original_order_item->get_total( 'edit' ) / $original_order_item->get_quantity( 'edit' ) );
|
$sign_up_fee_proportion = $sign_up_fee / ( (float) $original_order_item->get_total( 'edit' ) / $original_order_item->get_quantity( 'edit' ) );
|
||||||
$sign_up_fee_tax = $original_order_item->get_total_tax( 'edit' ) * $sign_up_fee_proportion;
|
$sign_up_fee_tax = (float) $original_order_item->get_total_tax( 'edit' ) * $sign_up_fee_proportion;
|
||||||
|
|
||||||
$sign_up_fee += $sign_up_fee_tax;
|
$sign_up_fee += $sign_up_fee_tax;
|
||||||
$sign_up_fee = wc_format_decimal( $sign_up_fee, wc_get_price_decimals() );
|
$sign_up_fee = wc_format_decimal( $sign_up_fee, wc_get_price_decimals() );
|
||||||
@@ -2632,11 +2693,43 @@ class WC_Subscription extends WC_Order {
|
|||||||
* Validates subscription date updates ensuring the proposed date changes are in the correct format and are compatible with
|
* Validates subscription date updates ensuring the proposed date changes are in the correct format and are compatible with
|
||||||
* the current subscription dates. Also returns the dates in the gmt timezone - ready for setting/deleting.
|
* the current subscription dates. Also returns the dates in the gmt timezone - ready for setting/deleting.
|
||||||
*
|
*
|
||||||
* @param array $dates array containing dates with keys: 'date_created', 'trial_end', 'next_payment', 'last_order_date_created' or 'end'. Values are MySQL formatted date/time strings in UTC timezone.
|
* @see prepare_dates_for_update() as a preferrable and more flexible alternative.
|
||||||
|
*
|
||||||
|
* @param array $dates array containing dates with keys: 'date_created', 'trial_end', 'next_payment', 'last_order_date_created' or 'end'. Values are timestamps or MySQL formatted date/time strings in UTC timezone.
|
||||||
* @param string $timezone The timezone of the $datetime param. Default 'gmt'.
|
* @param string $timezone The timezone of the $datetime param. Default 'gmt'.
|
||||||
* @return array $dates array of dates in gmt timezone.
|
* @return array $dates array of dates in gmt timezone.
|
||||||
|
* @throws InvalidArgumentException if the dates are not in the correct format or are not compatible with the current subscription dates.
|
||||||
|
*
|
||||||
|
* @deprecated 7.7.0 - Use prepare_dates_for_update() instead. This method remains in place for backwards compatibility.
|
||||||
*/
|
*/
|
||||||
public function validate_date_updates( $dates, $timezone = 'gmt' ) {
|
public function validate_date_updates( array $dates, string $timezone = 'gmt' ): array {
|
||||||
|
return $this->prepare_dates_for_update(
|
||||||
|
$dates,
|
||||||
|
array(
|
||||||
|
'timezone' => $timezone,
|
||||||
|
'ignore_invalid_dates' => false,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepares the dates for setting/deleting by validating values and adjusting to the gmt timezone.
|
||||||
|
*
|
||||||
|
* Validates subscription date updates ensuring the proposed date changes are in the correct format and are compatible with
|
||||||
|
* the current subscription dates. Also allows excluding invalid dates from the results.
|
||||||
|
*
|
||||||
|
* @param array $dates array containing dates with keys: 'date_created', 'trial_end', 'next_payment', 'last_order_date_created' or 'end'. Values are timestamps or MySQL formatted date/time strings in UTC timezone.
|
||||||
|
* @param array $options array containing the following validation options:
|
||||||
|
* - timezone: The timezone of the $datetime param. Default 'gmt'.
|
||||||
|
* - ignore_invalid_dates: Whether to ignore invalid dates. Default false. When invalid date is ignored, the current value stored on subscription (if any) is used instead.
|
||||||
|
* @return array $dates array of dates in gmt timezone.
|
||||||
|
* @throws InvalidArgumentException if the dates are not in the correct format or are not compatible with the current subscription dates.
|
||||||
|
*
|
||||||
|
* @since 7.7.0 Alternative to validate_date_updates() for more flexible validation options.
|
||||||
|
*/
|
||||||
|
public function prepare_dates_for_update( $dates, $options = array() ): array {
|
||||||
|
$timezone = isset( $options['timezone'] ) ? $options['timezone'] : 'gmt';
|
||||||
|
$ignore_invalid_dates = isset( $options['ignore_invalid_dates'] ) ? $options['ignore_invalid_dates'] : false;
|
||||||
|
|
||||||
if ( ! is_array( $dates ) ) {
|
if ( ! is_array( $dates ) ) {
|
||||||
throw new InvalidArgumentException( __( 'Invalid format. First parameter needs to be an array.', 'woocommerce-subscriptions' ) );
|
throw new InvalidArgumentException( __( 'Invalid format. First parameter needs to be an array.', 'woocommerce-subscriptions' ) );
|
||||||
@@ -2654,9 +2747,10 @@ class WC_Subscription extends WC_Order {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Use the normalised keys for the array
|
// Use the normalised keys for the array
|
||||||
$dates = array_combine( $passed_date_keys, array_values( $dates ) );
|
$dates = array_combine( $passed_date_keys, array_values( $dates ) );
|
||||||
|
$timestamps = array();
|
||||||
$timestamps = $delete_date_types = array();
|
$delete_date_types = array();
|
||||||
|
$messages = array();
|
||||||
|
|
||||||
// Get a full set of subscription dates made up of passed and current dates
|
// Get a full set of subscription dates made up of passed and current dates
|
||||||
foreach ( $this->get_valid_date_types() as $date_type ) {
|
foreach ( $this->get_valid_date_types() as $date_type ) {
|
||||||
@@ -2675,15 +2769,39 @@ class WC_Subscription extends WC_Order {
|
|||||||
if ( isset( $dates[ $date_type ] ) ) {
|
if ( isset( $dates[ $date_type ] ) ) {
|
||||||
$datetime = $dates[ $date_type ];
|
$datetime = $dates[ $date_type ];
|
||||||
|
|
||||||
if ( ! empty( $datetime ) && false === wcs_is_datetime_mysql_format( $datetime ) ) {
|
// When timestamp is passed, we don't need to convert into time string and backwards.
|
||||||
// translators: placeholder is date type (e.g. "end", "next_payment"...)
|
if ( wcs_is_timestamp( $datetime ) ) {
|
||||||
throw new InvalidArgumentException( sprintf( _x( 'Invalid %s date. The date must be of the format: "Y-m-d H:i:s".', 'appears in an error message if date is wrong format', 'woocommerce-subscriptions' ), $date_type ) );
|
// Timestamps could be passed as strings, so we need to cast them to int.
|
||||||
}
|
$timestamps[ $date_type ] = (int) $datetime;
|
||||||
|
} elseif ( empty( $datetime ) ) {
|
||||||
if ( empty( $datetime ) ) {
|
|
||||||
|
|
||||||
$timestamps[ $date_type ] = 0;
|
$timestamps[ $date_type ] = 0;
|
||||||
|
} elseif ( false === wcs_is_datetime_mysql_format( $datetime ) ) {
|
||||||
|
// Date in invalid format passed, so we might need to handle it gracefully.
|
||||||
|
if ( $ignore_invalid_dates ) {
|
||||||
|
// Fallback to the current subscription time instead.
|
||||||
|
$timestamps[ $date_type ] = $this->get_time( $date_type );
|
||||||
|
|
||||||
|
// Skip invalid date formats instead of throwing an exception - corrupted dates are ignored during update.
|
||||||
|
$logger = wc_get_logger();
|
||||||
|
$logger->warning(
|
||||||
|
sprintf(
|
||||||
|
'Value for %1$s is ignored due to invalid date format. Value: %2$s',
|
||||||
|
$date_type,
|
||||||
|
esc_html( $datetime ),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'subscription_id' => $this->get_id(),
|
||||||
|
'date_type' => $date_type,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$timestamps[ $date_type ] = 0;
|
||||||
|
$messages[] = sprintf(
|
||||||
|
// translators: placeholder is date type (e.g. "end", "next_payment"...)
|
||||||
|
_x( 'Invalid %s date. The date must be of the format: "Y-m-d H:i:s".', 'appears in an error message if date is wrong format', 'woocommerce-subscriptions' ),
|
||||||
|
esc_html( $date_type )
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if ( 'gmt' !== strtolower( $timezone ) ) {
|
if ( 'gmt' !== strtolower( $timezone ) ) {
|
||||||
@@ -2692,14 +2810,14 @@ class WC_Subscription extends WC_Order {
|
|||||||
|
|
||||||
$timestamps[ $date_type ] = wcs_date_to_time( $datetime );
|
$timestamps[ $date_type ] = wcs_date_to_time( $datetime );
|
||||||
}
|
}
|
||||||
// otherwise get the current subscription time
|
// Otherwise get the current subscription time.
|
||||||
} else {
|
} else {
|
||||||
$timestamps[ $date_type ] = $this->get_time( $date_type );
|
$timestamps[ $date_type ] = $this->get_time( $date_type );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( 0 == $timestamps[ $date_type ] ) {
|
if ( 0 === (int) $timestamps[ $date_type ] ) {
|
||||||
// Last payment is not in the UI, and it should NOT be deleted as that would mess with scheduling
|
// Last payment is not in the UI, and it should NOT be deleted as that would mess with scheduling
|
||||||
if ( 'last_order_date_created' != $date_type && 'date_created' != $date_type ) {
|
if ( 'last_order_date_created' !== $date_type && 'date_created' !== $date_type ) {
|
||||||
// We need to separate the dates which need deleting, so they don't interfere in the remaining validation
|
// We need to separate the dates which need deleting, so they don't interfere in the remaining validation
|
||||||
$delete_date_types[ $date_type ] = 0;
|
$delete_date_types[ $date_type ] = 0;
|
||||||
}
|
}
|
||||||
@@ -2707,8 +2825,6 @@ class WC_Subscription extends WC_Order {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$messages = array();
|
|
||||||
|
|
||||||
// And then iterate over them checking the relationships between them.
|
// And then iterate over them checking the relationships between them.
|
||||||
foreach ( $timestamps as $date_type => $timestamp ) {
|
foreach ( $timestamps as $date_type => $timestamp ) {
|
||||||
switch ( $date_type ) {
|
switch ( $date_type ) {
|
||||||
@@ -2741,7 +2857,7 @@ class WC_Subscription extends WC_Order {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$dates[ $date_type ] = gmdate( 'Y-m-d H:i:s', $timestamp );
|
$dates[ $date_type ] = gmdate( wcs_get_db_datetime_format(), $timestamp );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't validate dates while the subscription is being read, only dates set outside of instantiation require the strict validation rules to apply
|
// Don't validate dates while the subscription is being read, only dates set outside of instantiation require the strict validation rules to apply
|
||||||
@@ -2757,9 +2873,9 @@ class WC_Subscription extends WC_Order {
|
|||||||
* Add a product line item to the subscription.
|
* Add a product line item to the subscription.
|
||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.1.4
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.1.4
|
||||||
* @param WC_Product product
|
* @param WC_Product $product
|
||||||
* @param int line item quantity.
|
* @param int $qty quantity.
|
||||||
* @param array args
|
* @param array $args
|
||||||
* @return int|bool Item ID or false.
|
* @return int|bool Item ID or false.
|
||||||
*/
|
*/
|
||||||
public function add_product( $product, $qty = 1, $args = array() ) {
|
public function add_product( $product, $qty = 1, $args = array() ) {
|
||||||
|
@@ -82,7 +82,7 @@ class WC_Subscriptions_Addresses {
|
|||||||
|
|
||||||
if ( ! self::can_user_edit_subscription_address( absint( $_GET['subscription'] ) ) ) {
|
if ( ! self::can_user_edit_subscription_address( absint( $_GET['subscription'] ) ) ) {
|
||||||
wc_add_notice( 'Invalid subscription.', 'error' );
|
wc_add_notice( 'Invalid subscription.', 'error' );
|
||||||
wp_redirect( wc_get_account_endpoint_url( 'dashboard' ) );
|
wp_safe_redirect( wc_get_account_endpoint_url( 'dashboard' ) );
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -252,7 +252,7 @@ class WC_Subscriptions_Addresses {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$address_type = ( 'billing' === $address_type || 'shipping' === $address_type ) ? $address_type : '';
|
$address_type = ( 'billing' === $address_type || 'shipping' === $address_type ) ? $address_type : '';
|
||||||
$address_fields = WC()->countries->get_address_fields( esc_attr( $_POST[ $address_type . '_country' ] ), $address_type . '_' );
|
$address_fields = WC()->countries->get_address_fields( esc_attr( wc_clean( wp_unslash( $_POST[ $address_type . '_country' ] ) ) ), $address_type . '_' );
|
||||||
$address = array();
|
$address = array();
|
||||||
|
|
||||||
foreach ( $address_fields as $key => $field ) {
|
foreach ( $address_fields as $key => $field ) {
|
||||||
|
@@ -132,7 +132,7 @@ class WC_Subscriptions_Cart_Validator {
|
|||||||
*
|
*
|
||||||
* @return bool Whether the product can be added to the cart.
|
* @return bool Whether the product can be added to the cart.
|
||||||
*/
|
*/
|
||||||
public static function can_add_product_to_cart( $can_add, $product_id, $quantity, $variation_id = '', $variations = array(), $item_data = array() ) {
|
public static function can_add_product_to_cart( $can_add, $product_id, $quantity, $variation_id = 0, $variations = array(), $item_data = array() ) {
|
||||||
if ( $can_add && ! isset( $item_data['subscription_renewal'] ) && wcs_cart_contains_renewal() ) {
|
if ( $can_add && ! isset( $item_data['subscription_renewal'] ) && wcs_cart_contains_renewal() ) {
|
||||||
wc_add_notice( __( 'That product can not be added to your cart as it already contains a subscription renewal.', 'woocommerce-subscriptions' ), 'error' );
|
wc_add_notice( __( 'That product can not be added to your cart as it already contains a subscription renewal.', 'woocommerce-subscriptions' ), 'error' );
|
||||||
|
|
||||||
@@ -161,7 +161,7 @@ class WC_Subscriptions_Cart_Validator {
|
|||||||
|
|
||||||
# Force error on add_to_cart() to redirect
|
# Force error on add_to_cart() to redirect
|
||||||
add_filter( 'woocommerce_add_to_cart_validation', '__return_false', 10 );
|
add_filter( 'woocommerce_add_to_cart_validation', '__return_false', 10 );
|
||||||
add_filter( 'woocommerce_cart_redirect_after_error', 'wc_get_cart_url', 10, 2 );
|
add_filter( 'woocommerce_cart_redirect_after_error', 'wc_get_cart_url', 10 );
|
||||||
do_action( 'wc_ajax_add_to_cart' );
|
do_action( 'wc_ajax_add_to_cart' );
|
||||||
|
|
||||||
return $fragments;
|
return $fragments;
|
||||||
|
@@ -502,7 +502,6 @@ class WC_Subscriptions_Cart {
|
|||||||
* This is attached as a callback to hooks triggered whenever a product is removed from the cart.
|
* This is attached as a callback to hooks triggered whenever a product is removed from the cart.
|
||||||
*
|
*
|
||||||
* @param $cart_item_key string The key for a cart item about to be removed from the cart.
|
* @param $cart_item_key string The key for a cart item about to be removed from the cart.
|
||||||
* @return null
|
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0.15
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0.15
|
||||||
*/
|
*/
|
||||||
public static function maybe_reset_chosen_shipping_methods( $cart_item_key ) {
|
public static function maybe_reset_chosen_shipping_methods( $cart_item_key ) {
|
||||||
@@ -1131,7 +1130,7 @@ class WC_Subscriptions_Cart {
|
|||||||
/**
|
/**
|
||||||
* Checks the cart to see if it contains a specific product.
|
* Checks the cart to see if it contains a specific product.
|
||||||
*
|
*
|
||||||
* @param int The product ID or variation ID to look for.
|
* @param int $product_id The product ID or variation ID to look for.
|
||||||
* @return bool Whether the product is in the cart.
|
* @return bool Whether the product is in the cart.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0.13
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0.13
|
||||||
*/
|
*/
|
||||||
@@ -1154,7 +1153,7 @@ class WC_Subscriptions_Cart {
|
|||||||
/**
|
/**
|
||||||
* Checks the cart to see if it contains any subscription product other than a specific product.
|
* Checks the cart to see if it contains any subscription product other than a specific product.
|
||||||
*
|
*
|
||||||
* @param int The product ID or variation ID other than which to look for.
|
* @param int $product_id The product ID or variation ID other than which to look for.
|
||||||
* @return bool Whether another subscription product is in the cart.
|
* @return bool Whether another subscription product is in the cart.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v3.0.5
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v3.0.5
|
||||||
*/
|
*/
|
||||||
@@ -1252,7 +1251,7 @@ class WC_Subscriptions_Cart {
|
|||||||
/**
|
/**
|
||||||
* Allow third-parties to apply fees which apply to the cart to recurring carts.
|
* Allow third-parties to apply fees which apply to the cart to recurring carts.
|
||||||
*
|
*
|
||||||
* @param WC_Cart
|
* @param WC_Cart $cart
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.16
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.16
|
||||||
*/
|
*/
|
||||||
public static function apply_recurring_fees( $cart ) {
|
public static function apply_recurring_fees( $cart ) {
|
||||||
@@ -1367,7 +1366,7 @@ class WC_Subscriptions_Cart {
|
|||||||
* @param array $available_methods set of shipping rates for this calculation
|
* @param array $available_methods set of shipping rates for this calculation
|
||||||
* @param int $package_index WC doesn't pass the package index to callbacks on the 'woocommerce_shipping_chosen_method' filter (yet) so we set a default value of 0 for it in the function params
|
* @param int $package_index WC doesn't pass the package index to callbacks on the 'woocommerce_shipping_chosen_method' filter (yet) so we set a default value of 0 for it in the function params
|
||||||
*
|
*
|
||||||
* @return $default_method
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function set_chosen_shipping_method( $default_method, $available_methods, $package_index = 0 ) {
|
public static function set_chosen_shipping_method( $default_method, $available_methods, $package_index = 0 ) {
|
||||||
$chosen_methods = WC()->session->get( 'chosen_shipping_methods', array() );
|
$chosen_methods = WC()->session->get( 'chosen_shipping_methods', array() );
|
||||||
@@ -1409,8 +1408,8 @@ class WC_Subscriptions_Cart {
|
|||||||
return $url;
|
return $url;
|
||||||
}
|
}
|
||||||
|
|
||||||
$quantity = isset( $_REQUEST['quantity'] ) ? $_REQUEST['quantity'] : 1;
|
$quantity = isset( $_REQUEST['quantity'] ) ? wc_clean( wp_unslash( $_REQUEST['quantity'] ) ) : 1;
|
||||||
$product_id = $_REQUEST['add-to-cart'];
|
$product_id = wc_clean( wp_unslash( $_REQUEST['add-to-cart'] ) );
|
||||||
|
|
||||||
$add_to_cart_notice = wc_add_to_cart_message( array( $product_id => $quantity ), true, true );
|
$add_to_cart_notice = wc_add_to_cart_message( array( $product_id => $quantity ), true, true );
|
||||||
|
|
||||||
@@ -1497,12 +1496,15 @@ class WC_Subscriptions_Cart {
|
|||||||
*
|
*
|
||||||
* Returns the cart_item containing the product renewal, else false.
|
* Returns the cart_item containing the product renewal, else false.
|
||||||
*
|
*
|
||||||
|
* @param string $role The role of the cart item to check for.
|
||||||
|
* @return array|false The cart item containing the renewal, else false.
|
||||||
|
*
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.3
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.3
|
||||||
*/
|
*/
|
||||||
public static function cart_contains_subscription_renewal( $role = '' ) {
|
public static function cart_contains_subscription_renewal( $role = '' ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'wcs_cart_contains_renewal( $role )' );
|
_deprecated_function( __METHOD__, '2.0', 'wcs_cart_contains_renewal( $role )' );
|
||||||
return wcs_cart_contains_renewal( $role );
|
return wcs_cart_contains_renewal();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1590,8 +1592,8 @@ class WC_Subscriptions_Cart {
|
|||||||
/**
|
/**
|
||||||
* Returns individual coupon's formatted discount amount for WooCommerce 2.1+
|
* Returns individual coupon's formatted discount amount for WooCommerce 2.1+
|
||||||
*
|
*
|
||||||
* @param string $discount_html String of the coupon's discount amount
|
* @param string $cart_totals_fee_html String of the coupon's discount amount
|
||||||
* @param string $coupon WC_Coupon object for the coupon to which this line item relates
|
* @param string $fee WC_Coupon object for the coupon to which this line item relates
|
||||||
* @return string formatted subscription price string if the cart includes a coupon being applied to recurring amount
|
* @return string formatted subscription price string if the cart includes a coupon being applied to recurring amount
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.4.6
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.4.6
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
@@ -1695,6 +1697,8 @@ class WC_Subscriptions_Cart {
|
|||||||
public static function get_cart_subscription_period() {
|
public static function get_cart_subscription_period() {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'values from WC()->cart->recurring_carts' );
|
_deprecated_function( __METHOD__, '2.0', 'values from WC()->cart->recurring_carts' );
|
||||||
|
|
||||||
|
$period = '';
|
||||||
|
|
||||||
if ( self::cart_contains_subscription() ) {
|
if ( self::cart_contains_subscription() ) {
|
||||||
foreach ( WC()->cart->cart_contents as $cart_item ) {
|
foreach ( WC()->cart->cart_contents as $cart_item ) {
|
||||||
if ( WC_Subscriptions_Product::is_subscription( $cart_item['data'] ) ) {
|
if ( WC_Subscriptions_Product::is_subscription( $cart_item['data'] ) ) {
|
||||||
@@ -1718,6 +1722,8 @@ class WC_Subscriptions_Cart {
|
|||||||
public static function get_cart_subscription_interval() {
|
public static function get_cart_subscription_interval() {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'values from WC()->cart->recurring_carts' );
|
_deprecated_function( __METHOD__, '2.0', 'values from WC()->cart->recurring_carts' );
|
||||||
|
|
||||||
|
$interval = 0;
|
||||||
|
|
||||||
foreach ( WC()->cart->cart_contents as $cart_item ) {
|
foreach ( WC()->cart->cart_contents as $cart_item ) {
|
||||||
if ( WC_Subscriptions_Product::is_subscription( $cart_item['data'] ) ) {
|
if ( WC_Subscriptions_Product::is_subscription( $cart_item['data'] ) ) {
|
||||||
$interval = WC_Subscriptions_Product::get_interval( $cart_item['data'] );
|
$interval = WC_Subscriptions_Product::get_interval( $cart_item['data'] );
|
||||||
@@ -2110,6 +2116,8 @@ class WC_Subscriptions_Cart {
|
|||||||
public static function calculate_recurring_shipping() {
|
public static function calculate_recurring_shipping() {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'values from WC()->cart->recurring_carts' );
|
_deprecated_function( __METHOD__, '2.0', 'values from WC()->cart->recurring_carts' );
|
||||||
|
|
||||||
|
$recurring_total = 0;
|
||||||
|
|
||||||
foreach ( WC()->cart->recurring_carts as $cart ) {
|
foreach ( WC()->cart->recurring_carts as $cart ) {
|
||||||
$recurring_total = $cart->shipping_total;
|
$recurring_total = $cart->shipping_total;
|
||||||
}
|
}
|
||||||
@@ -2302,8 +2310,8 @@ class WC_Subscriptions_Cart {
|
|||||||
/**
|
/**
|
||||||
* Return a localized free trial period string.
|
* Return a localized free trial period string.
|
||||||
*
|
*
|
||||||
* @param int An interval in the range 1-6
|
* @param int $number An interval in the range 1-6
|
||||||
* @param string One of day, week, month or year.
|
* @param string $period One of day, week, month or year.
|
||||||
*/
|
*/
|
||||||
public static function format_free_trial_period( $number, $period ) {
|
public static function format_free_trial_period( $number, $period ) {
|
||||||
if ( 'day' === $period ) {
|
if ( 'day' === $period ) {
|
||||||
@@ -2399,6 +2407,8 @@ class WC_Subscriptions_Cart {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Adds meta data so it can be displayed in the Cart.
|
* Adds meta data so it can be displayed in the Cart.
|
||||||
@@ -2456,7 +2466,7 @@ class WC_Subscriptions_Cart {
|
|||||||
* sends the shipping methods with a numerical index.
|
* sends the shipping methods with a numerical index.
|
||||||
*
|
*
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v3.1.0
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v3.1.0
|
||||||
* @return null
|
* @return void
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0.12
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0.12
|
||||||
*/
|
*/
|
||||||
public static function add_shipping_method_post_data() {
|
public static function add_shipping_method_post_data() {
|
||||||
@@ -2467,7 +2477,7 @@ class WC_Subscriptions_Cart {
|
|||||||
|
|
||||||
check_ajax_referer( 'update-order-review', 'security' );
|
check_ajax_referer( 'update-order-review', 'security' );
|
||||||
|
|
||||||
parse_str( $_POST['post_data'], $form_data );
|
parse_str( wc_clean( wp_unslash( $_POST['post_data'] ) ), $form_data );
|
||||||
|
|
||||||
// In case we have only free trials/sync'd products in the cart and shipping methods aren't being displayed
|
// In case we have only free trials/sync'd products in the cart and shipping methods aren't being displayed
|
||||||
if ( ! isset( $_POST['shipping_method'] ) ) {
|
if ( ! isset( $_POST['shipping_method'] ) ) {
|
||||||
|
@@ -218,10 +218,10 @@ class WC_Subscriptions_Change_Payment_Gateway {
|
|||||||
* @param WC_Subscription $subscription
|
* @param WC_Subscription $subscription
|
||||||
* @return bool Whether the request is valid or not.
|
* @return bool Whether the request is valid or not.
|
||||||
*/
|
*/
|
||||||
private static function validate_change_payment_request( $subscription ) {
|
private static function validate_change_payment_request( $subscription = null ) {
|
||||||
$is_valid = true;
|
$is_valid = true;
|
||||||
|
|
||||||
if ( wp_verify_nonce( $_GET['_wpnonce'] ) === false ) {
|
if ( wp_verify_nonce( wc_clean( wp_unslash( $_GET['_wpnonce'] ) ) ) === false ) {
|
||||||
$is_valid = false;
|
$is_valid = false;
|
||||||
wc_add_notice( __( 'There was an error with your request. Please try again.', 'woocommerce-subscriptions' ), 'error' );
|
wc_add_notice( __( 'There was an error with your request. Please try again.', 'woocommerce-subscriptions' ), 'error' );
|
||||||
} elseif ( empty( $subscription ) ) {
|
} elseif ( empty( $subscription ) ) {
|
||||||
@@ -244,8 +244,8 @@ class WC_Subscriptions_Change_Payment_Gateway {
|
|||||||
/**
|
/**
|
||||||
* Add a "Change Payment Method" button to the "My Subscriptions" table.
|
* Add a "Change Payment Method" button to the "My Subscriptions" table.
|
||||||
*
|
*
|
||||||
* @param array $all_actions The $subscription_key => $actions array with all actions that will be displayed for a subscription on the "My Subscriptions" table
|
* @param array $actions The $subscription_key => $actions array with all actions that will be displayed for a subscription on the "My Subscriptions" table
|
||||||
* @param array $subscriptions All of a given users subscriptions that will be displayed on the "My Subscriptions" table
|
* @param WC_Subscription $subscription The subscription.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.4
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.4
|
||||||
*/
|
*/
|
||||||
public static function change_payment_method_button( $actions, $subscription ) {
|
public static function change_payment_method_button( $actions, $subscription ) {
|
||||||
@@ -272,24 +272,23 @@ class WC_Subscriptions_Change_Payment_Gateway {
|
|||||||
*
|
*
|
||||||
* Based on the @see woocommerce_pay_action() function.
|
* Based on the @see woocommerce_pay_action() function.
|
||||||
*
|
*
|
||||||
* @access public
|
|
||||||
* @return void
|
* @return void
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.4
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.4
|
||||||
*/
|
*/
|
||||||
public static function change_payment_method_via_pay_shortcode() {
|
public static function change_payment_method_via_pay_shortcode() {
|
||||||
|
|
||||||
if ( ! isset( $_POST['_wcsnonce'] ) || ! wp_verify_nonce( $_POST['_wcsnonce'], 'wcs_change_payment_method' ) ) {
|
if ( ! isset( $_POST['_wcsnonce'] ) || ! wp_verify_nonce( wc_clean( wp_unslash( $_POST['_wcsnonce'] ) ), 'wcs_change_payment_method' ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$subscription_id = absint( $_POST['woocommerce_change_payment'] );
|
$subscription_id = absint( wc_clean( wp_unslash( $_POST['woocommerce_change_payment'] ) ) );
|
||||||
$subscription = wcs_get_subscription( $subscription_id );
|
$subscription = wcs_get_subscription( $subscription_id );
|
||||||
|
|
||||||
do_action( 'woocommerce_subscription_change_payment_method_via_pay_shortcode', $subscription );
|
do_action( 'woocommerce_subscription_change_payment_method_via_pay_shortcode', $subscription );
|
||||||
|
|
||||||
ob_start();
|
ob_start();
|
||||||
|
|
||||||
if ( $subscription->get_order_key() == $_GET['key'] ) {
|
if ( $subscription->get_order_key() == wc_clean( wp_unslash( $_GET['key'] ) ) ) {
|
||||||
|
|
||||||
$subscription_billing_country = $subscription->get_billing_country();
|
$subscription_billing_country = $subscription->get_billing_country();
|
||||||
$subscription_billing_state = $subscription->get_billing_state();
|
$subscription_billing_state = $subscription->get_billing_state();
|
||||||
@@ -366,7 +365,7 @@ class WC_Subscriptions_Change_Payment_Gateway {
|
|||||||
// Does the customer want all current subscriptions to be updated to this payment method?
|
// Does the customer want all current subscriptions to be updated to this payment method?
|
||||||
if (
|
if (
|
||||||
isset( $_POST['update_all_subscriptions_payment_method'] )
|
isset( $_POST['update_all_subscriptions_payment_method'] )
|
||||||
&& $_POST['update_all_subscriptions_payment_method']
|
&& wc_clean( wp_unslash( $_POST['update_all_subscriptions_payment_method'] ) )
|
||||||
&& WC_Subscriptions_Change_Payment_Gateway::can_update_all_subscription_payment_methods( $available_gateways[ $new_payment_method ], $subscription )
|
&& WC_Subscriptions_Change_Payment_Gateway::can_update_all_subscription_payment_methods( $available_gateways[ $new_payment_method ], $subscription )
|
||||||
) {
|
) {
|
||||||
// Allow some payment gateways which can't process the payment immediately, like PayPal, to do it later after the payment/sign-up is confirmed
|
// Allow some payment gateways which can't process the payment immediately, like PayPal, to do it later after the payment/sign-up is confirmed
|
||||||
@@ -409,7 +408,7 @@ class WC_Subscriptions_Change_Payment_Gateway {
|
|||||||
$subscription->save_meta_data();
|
$subscription->save_meta_data();
|
||||||
}
|
}
|
||||||
|
|
||||||
$payment_meta_table = WCS_Payment_tokens::get_subscription_payment_meta( $subscription, $new_payment_method );
|
$payment_meta_table = WCS_Payment_Tokens::get_subscription_payment_meta( $subscription, $new_payment_method );
|
||||||
if ( ! is_array( $payment_meta_table ) ) {
|
if ( ! is_array( $payment_meta_table ) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -498,7 +497,7 @@ class WC_Subscriptions_Change_Payment_Gateway {
|
|||||||
* @param array $new_payment_method_meta The meta for the new payment method. Optional. Default false.
|
* @param array $new_payment_method_meta The meta for the new payment method. Optional. Default false.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.4
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.4
|
||||||
*/
|
*/
|
||||||
public static function update_payment_method( $subscription, $new_payment_method, $new_payment_method_meta = false ) {
|
public static function update_payment_method( $subscription, $new_payment_method, $new_payment_method_meta = [] ) {
|
||||||
|
|
||||||
$old_payment_method = $subscription->get_payment_method();
|
$old_payment_method = $subscription->get_payment_method();
|
||||||
$old_payment_method_title = $subscription->get_payment_method_title();
|
$old_payment_method_title = $subscription->get_payment_method_title();
|
||||||
@@ -618,7 +617,7 @@ class WC_Subscriptions_Change_Payment_Gateway {
|
|||||||
public static function maybe_zero_total( $total, $subscription ) {
|
public static function maybe_zero_total( $total, $subscription ) {
|
||||||
global $wp;
|
global $wp;
|
||||||
|
|
||||||
if ( ! empty( $_POST['_wcsnonce'] ) && wp_verify_nonce( $_POST['_wcsnonce'], 'wcs_change_payment_method' ) && isset( $_POST['woocommerce_change_payment'] ) && wcs_is_subscription( $subscription ) && $subscription->get_order_key() == $_GET['key'] && $subscription->get_id() == absint( $_POST['woocommerce_change_payment'] ) ) {
|
if ( ! empty( $_POST['_wcsnonce'] ) && wp_verify_nonce( wc_clean( wp_unslash( $_POST['_wcsnonce'] ) ), 'wcs_change_payment_method' ) && isset( $_POST['woocommerce_change_payment'] ) && wcs_is_subscription( $subscription ) && $subscription->get_order_key() == $_GET['key'] && $subscription->get_id() == absint( $_POST['woocommerce_change_payment'] ) ) {
|
||||||
$total = 0;
|
$total = 0;
|
||||||
} elseif ( ! self::$is_request_to_change_payment && isset( $wp->query_vars['order-pay'] ) && wcs_is_subscription( absint( $wp->query_vars['order-pay'] ) ) ) {
|
} elseif ( ! self::$is_request_to_change_payment && isset( $wp->query_vars['order-pay'] ) && wcs_is_subscription( absint( $wp->query_vars['order-pay'] ) ) ) {
|
||||||
// if the request to pay for the order belongs to a subscription but there's no GET params for changing payment method, the receipt page is being used to collect credit card details so we still need to $0 the total
|
// if the request to pay for the order belongs to a subscription but there's no GET params for changing payment method, the receipt page is being used to collect credit card details so we still need to $0 the total
|
||||||
@@ -635,7 +634,7 @@ class WC_Subscriptions_Change_Payment_Gateway {
|
|||||||
*/
|
*/
|
||||||
public static function get_return_url( $return_url ) {
|
public static function get_return_url( $return_url ) {
|
||||||
|
|
||||||
if ( ! empty( $_POST['_wcsnonce'] ) && wp_verify_nonce( $_POST['_wcsnonce'], 'wcs_change_payment_method' ) && isset( $_POST['woocommerce_change_payment'] ) ) {
|
if ( ! empty( $_POST['_wcsnonce'] ) && wp_verify_nonce( wc_clean( wp_unslash( $_POST['_wcsnonce'] ) ), 'wcs_change_payment_method' ) && isset( $_POST['woocommerce_change_payment'] ) ) {
|
||||||
$return_url = get_permalink( wc_get_page_id( 'myaccount' ) );
|
$return_url = get_permalink( wc_get_page_id( 'myaccount' ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -649,15 +648,15 @@ class WC_Subscriptions_Change_Payment_Gateway {
|
|||||||
* Also trigger a hook for payment gateways to update any meta on the original order for a subscription.
|
* Also trigger a hook for payment gateways to update any meta on the original order for a subscription.
|
||||||
*
|
*
|
||||||
* @param WC_Order $renewal_order The order which recorded the successful payment (to make up for the failed automatic payment).
|
* @param WC_Order $renewal_order The order which recorded the successful payment (to make up for the failed automatic payment).
|
||||||
* @param WC_Order $original_order The original order in which the subscription was purchased.
|
* @param WC_Subscription $subscription The subscription.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.4
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.4
|
||||||
*/
|
*/
|
||||||
public static function change_failing_payment_method( $renewal_order, $subscription ) {
|
public static function change_failing_payment_method( $renewal_order, $subscription ) {
|
||||||
|
|
||||||
if ( ! $subscription->is_manual() ) {
|
if ( ! $subscription->is_manual() ) {
|
||||||
|
|
||||||
if ( ! empty( $_POST['_wcsnonce'] ) && wp_verify_nonce( $_POST['_wcsnonce'], 'wcs_change_payment_method' ) && isset( $_POST['payment_method'] ) ) {
|
if ( ! empty( $_POST['_wcsnonce'] ) && wp_verify_nonce( wc_clean( wp_unslash( $_POST['_wcsnonce'] ) ), 'wcs_change_payment_method' ) && isset( $_POST['payment_method'] ) ) {
|
||||||
$new_payment_method = wc_clean( $_POST['payment_method'] );
|
$new_payment_method = wc_clean( wp_unslash( $_POST['payment_method'] ) );
|
||||||
} else {
|
} else {
|
||||||
$new_payment_method = wcs_get_objects_property( $renewal_order, 'payment_method' );
|
$new_payment_method = wcs_get_objects_property( $renewal_order, 'payment_method' );
|
||||||
}
|
}
|
||||||
@@ -796,7 +795,6 @@ class WC_Subscriptions_Change_Payment_Gateway {
|
|||||||
* This is causing `$gateway->payment_fields()` to be called multiple times.
|
* This is causing `$gateway->payment_fields()` to be called multiple times.
|
||||||
*
|
*
|
||||||
* @param bool $needs_payment
|
* @param bool $needs_payment
|
||||||
* @param WC_Subscription $subscription
|
|
||||||
* @return bool
|
* @return bool
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0.7
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0.7
|
||||||
*/
|
*/
|
||||||
@@ -845,7 +843,9 @@ class WC_Subscriptions_Change_Payment_Gateway {
|
|||||||
/**
|
/**
|
||||||
* Update the recurring payment method on a subscription order.
|
* Update the recurring payment method on a subscription order.
|
||||||
*
|
*
|
||||||
* @param array $available_gateways The payment gateways which are currently being allowed.
|
* @param string $subscription_key The subscription key.
|
||||||
|
* @param WC_Order $order The order.
|
||||||
|
* @param string $new_payment_method The new payment method.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.4
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.4
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
|
@@ -116,7 +116,7 @@ class WC_Subscriptions_Checkout {
|
|||||||
* The function doesn't validate whether the cart item is a subscription product, meaning it can be used for any cart item,
|
* The function doesn't validate whether the cart item is a subscription product, meaning it can be used for any cart item,
|
||||||
* but the item will need a `subscription_period` and `subscription_period_interval` value set on it, at a minimum.
|
* but the item will need a `subscription_period` and `subscription_period_interval` value set on it, at a minimum.
|
||||||
*
|
*
|
||||||
* @param WC_Order $order
|
* @param WC_Subscription $order
|
||||||
* @param WC_Cart $cart
|
* @param WC_Cart $cart
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
@@ -152,6 +152,7 @@ class WC_Subscriptions_Checkout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set the subscription's billing and shipping address
|
// Set the subscription's billing and shipping address
|
||||||
|
/** @var WC_Subscription $subscription */
|
||||||
$subscription = wcs_copy_order_address( $order, $subscription );
|
$subscription = wcs_copy_order_address( $order, $subscription );
|
||||||
|
|
||||||
$subscription->update_dates(
|
$subscription->update_dates(
|
||||||
@@ -336,7 +337,7 @@ class WC_Subscriptions_Checkout {
|
|||||||
/**
|
/**
|
||||||
* Remove the Backordered meta data from subscription line items added on the checkout.
|
* Remove the Backordered meta data from subscription line items added on the checkout.
|
||||||
*
|
*
|
||||||
* @param WC_Order_Item_Product $order_item
|
* @param WC_Order_Item_Product $item
|
||||||
* @param string $cart_item_key The hash used to identify the item in the cart
|
* @param string $cart_item_key The hash used to identify the item in the cart
|
||||||
* @param array $cart_item The cart item's data.
|
* @param array $cart_item The cart item's data.
|
||||||
* @param WC_Order|WC_Subscription $subscription The order or subscription object to which the line item relates
|
* @param WC_Order|WC_Subscription $subscription The order or subscription object to which the line item relates
|
||||||
@@ -451,9 +452,9 @@ class WC_Subscriptions_Checkout {
|
|||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v3.0.10
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v3.0.10
|
||||||
*
|
*
|
||||||
* @param WC_Line_Item_Product $line_item The line item added to the order/subscription.
|
* @param WC_Order_Item_Product $line_item The line item added to the order/subscription.
|
||||||
* @param string $cart_item_key The key of the cart item being added to the cart.
|
* @param string $cart_item_key The key of the cart item being added to the cart.
|
||||||
* @param array $cart_item The cart item data.
|
* @param array $cart_item The cart item data.
|
||||||
*/
|
*/
|
||||||
public static function store_line_item_base_location_taxes( $line_item, $cart_item_key, $cart_item ) {
|
public static function store_line_item_base_location_taxes( $line_item, $cart_item_key, $cart_item ) {
|
||||||
if ( isset( $cart_item['_subtracted_base_location_taxes'] ) ) {
|
if ( isset( $cart_item['_subtracted_base_location_taxes'] ) ) {
|
||||||
@@ -671,6 +672,7 @@ class WC_Subscriptions_Checkout {
|
|||||||
$switch_items = wcs_cart_contains_switches();
|
$switch_items = wcs_cart_contains_switches();
|
||||||
$renewal_item = wcs_cart_contains_renewal();
|
$renewal_item = wcs_cart_contains_renewal();
|
||||||
$resubscribe_item = wcs_cart_contains_resubscribe();
|
$resubscribe_item = wcs_cart_contains_resubscribe();
|
||||||
|
$subscription_id = null;
|
||||||
|
|
||||||
if ( ! $switch_items && ! $renewal_item && ! $resubscribe_item ) {
|
if ( ! $switch_items && ! $renewal_item && ! $resubscribe_item ) {
|
||||||
return $ship_to_different_address;
|
return $ship_to_different_address;
|
||||||
|
@@ -161,10 +161,13 @@ class WC_Subscriptions_Core_Plugin {
|
|||||||
add_action( 'plugins_loaded', array( $this, 'init_version_dependant_classes' ) );
|
add_action( 'plugins_loaded', array( $this, 'init_version_dependant_classes' ) );
|
||||||
|
|
||||||
// Initialised the related order and customter data store instances.
|
// Initialised the related order and customter data store instances.
|
||||||
|
// @phpstan-ignore return.void
|
||||||
add_action( 'plugins_loaded', 'WCS_Related_Order_Store::instance' );
|
add_action( 'plugins_loaded', 'WCS_Related_Order_Store::instance' );
|
||||||
|
// @phpstan-ignore return.void
|
||||||
add_action( 'plugins_loaded', 'WCS_Customer_Store::instance' );
|
add_action( 'plugins_loaded', 'WCS_Customer_Store::instance' );
|
||||||
|
|
||||||
// Initialise the batch processing controller.
|
// Initialise the batch processing controller.
|
||||||
|
// @phpstan-ignore return.void
|
||||||
add_action( 'init', 'WCS_Batch_Processing_Controller::instance' );
|
add_action( 'init', 'WCS_Batch_Processing_Controller::instance' );
|
||||||
|
|
||||||
// Initialise the scheduler.
|
// Initialise the scheduler.
|
||||||
@@ -213,7 +216,7 @@ class WC_Subscriptions_Core_Plugin {
|
|||||||
/**
|
/**
|
||||||
* Allow third-party code to enable running v2.0 hook deprecation handling for stores that might want to check for deprecated code.
|
* Allow third-party code to enable running v2.0 hook deprecation handling for stores that might want to check for deprecated code.
|
||||||
*
|
*
|
||||||
* @param bool Whether the hook deprecation handlers should be loaded. False by default.
|
* @param bool $value Whether the hook deprecation handlers should be loaded. False by default.
|
||||||
*/
|
*/
|
||||||
if ( apply_filters( 'woocommerce_subscriptions_load_deprecation_handlers', false ) ) {
|
if ( apply_filters( 'woocommerce_subscriptions_load_deprecation_handlers', false ) ) {
|
||||||
new WCS_Action_Deprecator();
|
new WCS_Action_Deprecator();
|
||||||
@@ -527,11 +530,11 @@ class WC_Subscriptions_Core_Plugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if this is the first time activating WooCommerce Subscription we want to enable PayPal debugging by default.
|
// if this is the first time activating WooCommerce Subscription we want to enable PayPal debugging by default.
|
||||||
if ( '0' == get_option( WC_Subscriptions_Admin::$option_prefix . '_previous_version', '0' ) && false == get_option( WC_Subscriptions_admin::$option_prefix . '_paypal_debugging_default_set', false ) ) {
|
if ( '0' == get_option( WC_Subscriptions_Admin::$option_prefix . '_previous_version', '0' ) && false == get_option( WC_Subscriptions_Admin::$option_prefix . '_paypal_debugging_default_set', false ) ) {
|
||||||
$paypal_settings = get_option( 'woocommerce_paypal_settings' );
|
$paypal_settings = get_option( 'woocommerce_paypal_settings' );
|
||||||
$paypal_settings['debug'] = 'yes';
|
$paypal_settings['debug'] = 'yes';
|
||||||
update_option( 'woocommerce_paypal_settings', $paypal_settings );
|
update_option( 'woocommerce_paypal_settings', $paypal_settings );
|
||||||
update_option( WC_Subscriptions_admin::$option_prefix . '_paypal_debugging_default_set', 'true' );
|
update_option( WC_Subscriptions_Admin::$option_prefix . '_paypal_debugging_default_set', 'true' );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable customer notifications by default for new stores.
|
// Enable customer notifications by default for new stores.
|
||||||
|
@@ -90,7 +90,7 @@ class WC_Subscriptions_Coupon {
|
|||||||
|
|
||||||
add_filter( 'woocommerce_cart_totals_coupon_label', __CLASS__ . '::get_pseudo_coupon_label', 10, 2 );
|
add_filter( 'woocommerce_cart_totals_coupon_label', __CLASS__ . '::get_pseudo_coupon_label', 10, 2 );
|
||||||
|
|
||||||
add_filter( 'woocommerce_cart_totals_coupon_html', __CLASS__ . '::mark_recurring_coupon_in_initial_cart_for_hiding', 10, 3 );
|
add_filter( 'woocommerce_cart_totals_coupon_html', __CLASS__ . '::mark_recurring_coupon_in_initial_cart_for_hiding', 10, 2 );
|
||||||
|
|
||||||
add_filter( 'woocommerce_coupon_is_valid_for_product', array( __CLASS__, 'validate_subscription_coupon_for_product' ), 10, 3 );
|
add_filter( 'woocommerce_coupon_is_valid_for_product', array( __CLASS__, 'validate_subscription_coupon_for_product' ), 10, 3 );
|
||||||
add_filter( 'woocommerce_coupon_get_apply_quantity', array( __CLASS__, 'override_applied_quantity_for_recurring_carts' ), 10, 3 );
|
add_filter( 'woocommerce_coupon_get_apply_quantity', array( __CLASS__, 'override_applied_quantity_for_recurring_carts' ), 10, 3 );
|
||||||
@@ -101,7 +101,7 @@ class WC_Subscriptions_Coupon {
|
|||||||
* Mark such recurring coupons with a dummy span with class wcs-hidden-coupon so that it can be hidden.
|
* Mark such recurring coupons with a dummy span with class wcs-hidden-coupon so that it can be hidden.
|
||||||
*
|
*
|
||||||
* @param string $coupon_html Html string of the recurring coupon's cell in the Cart totals table
|
* @param string $coupon_html Html string of the recurring coupon's cell in the Cart totals table
|
||||||
* @param WC_coupon $coupon WC_Coupon object of the recurring coupon
|
* @param WC_Coupon $coupon WC_Coupon object of the recurring coupon
|
||||||
* @return string $coupon_html Modified html string of the coupon containing the marking
|
* @return string $coupon_html Modified html string of the coupon containing the marking
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.3
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.3
|
||||||
*/
|
*/
|
||||||
@@ -300,6 +300,8 @@ class WC_Subscriptions_Coupon {
|
|||||||
* This is so rows with different tax rates get a fair discount, and so rows with no price (free) don't get discounted.
|
* This is so rows with different tax rates get a fair discount, and so rows with no price (free) don't get discounted.
|
||||||
*
|
*
|
||||||
* BUT... we also need the subtotal to exclude non renewal products, so user the renewal subtotal
|
* BUT... we also need the subtotal to exclude non renewal products, so user the renewal subtotal
|
||||||
|
*
|
||||||
|
* @phpstan-ignore binaryOp.invalid
|
||||||
*/
|
*/
|
||||||
$discount_percent = ( $discounting_amount * $cart_item['quantity'] ) / self::get_renewal_subtotal( wcs_get_coupon_property( $coupon, 'code' ) );
|
$discount_percent = ( $discounting_amount * $cart_item['quantity'] ) / self::get_renewal_subtotal( wcs_get_coupon_property( $coupon, 'code' ) );
|
||||||
|
|
||||||
@@ -562,6 +564,7 @@ class WC_Subscriptions_Coupon {
|
|||||||
* @param WC_Coupon $coupon The coupon object.
|
* @param WC_Coupon $coupon The coupon object.
|
||||||
* @param string $coupon_type The coupon's discount_type property.
|
* @param string $coupon_type The coupon's discount_type property.
|
||||||
* @param string $calculation_type The current calculation type.
|
* @param string $calculation_type The current calculation type.
|
||||||
|
* @param WC_Cart $cart The cart object.
|
||||||
*/
|
*/
|
||||||
if ( apply_filters( 'wcs_bypass_coupon_removal', false, $coupon, $coupon_type, $calculation_type, $cart ) ) {
|
if ( apply_filters( 'wcs_bypass_coupon_removal', false, $coupon, $coupon_type, $calculation_type, $cart ) ) {
|
||||||
continue;
|
continue;
|
||||||
@@ -926,6 +929,8 @@ class WC_Subscriptions_Coupon {
|
|||||||
/**
|
/**
|
||||||
* Restores discount coupons which had been removed for special subscription calculations.
|
* Restores discount coupons which had been removed for special subscription calculations.
|
||||||
*
|
*
|
||||||
|
* @param WC_Cart $cart The cart object.
|
||||||
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.3.5
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.3.5
|
||||||
*/
|
*/
|
||||||
public static function restore_coupons( $cart ) {
|
public static function restore_coupons( $cart ) {
|
||||||
|
@@ -157,6 +157,7 @@ class WC_Subscriptions_Data_Copier {
|
|||||||
* }
|
* }
|
||||||
* @param WC_Order $from_object The object to copy data from.
|
* @param WC_Order $from_object The object to copy data from.
|
||||||
* @param WC_Order $to_object The object to copy data to.
|
* @param WC_Order $to_object The object to copy data to.
|
||||||
|
* @param string $copy_type The type of copy. Can be 'subscription', 'parent', 'renewal_order' or 'resubscribe_order'.
|
||||||
*/
|
*/
|
||||||
$data = apply_filters( 'wc_subscriptions_object_data', $data, $this->to_object, $this->from_object, $this->copy_type );
|
$data = apply_filters( 'wc_subscriptions_object_data', $data, $this->to_object, $this->from_object, $this->copy_type );
|
||||||
|
|
||||||
@@ -376,6 +377,9 @@ class WC_Subscriptions_Data_Copier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( $this->has_filter_on_meta_query_hook() ) {
|
if ( $this->has_filter_on_meta_query_hook() ) {
|
||||||
|
$data_copier_to_object = $this->to_object;
|
||||||
|
$data_copier_from_object = $this->from_object;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filters the data to be copied from one object to another.
|
* Filters the data to be copied from one object to another.
|
||||||
*
|
*
|
||||||
@@ -388,10 +392,10 @@ class WC_Subscriptions_Data_Copier {
|
|||||||
* @deprecated subscriptions-core 2.5.0
|
* @deprecated subscriptions-core 2.5.0
|
||||||
*
|
*
|
||||||
* @param string $meta_query The SQL query to fetch the meta data to be copied.
|
* @param string $meta_query The SQL query to fetch the meta data to be copied.
|
||||||
* @param WC_Order $this->to_object The object to copy data to.
|
* @param WC_Order $data_copier_to_object The object to copy data to.
|
||||||
* @param WC_Order $this->from_object The object to copy data from.
|
* @param WC_Order $data_copier_from_object The object to copy data from.
|
||||||
*/
|
*/
|
||||||
$meta_query = apply_filters( "wcs_{$this->copy_type}_meta_query", $meta_query, $this->to_object, $this->from_object );
|
$meta_query = apply_filters( "wcs_{$this->copy_type}_meta_query", $meta_query, $data_copier_to_object, $data_copier_from_object );
|
||||||
wcs_deprecated_hook( "wcs_{$this->copy_type}_meta_query", 'subscriptions-core 2.5.0', "wc_subscriptions_{$this->copy_type}_data" );
|
wcs_deprecated_hook( "wcs_{$this->copy_type}_meta_query", 'subscriptions-core 2.5.0', "wc_subscriptions_{$this->copy_type}_data" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -424,6 +428,9 @@ class WC_Subscriptions_Data_Copier {
|
|||||||
|
|
||||||
wcs_deprecated_hook( "wcs_{$this->copy_type}_meta", 'wcs-core 2.5.0', "wc_subscriptions_{$this->copy_type}_data" );
|
wcs_deprecated_hook( "wcs_{$this->copy_type}_meta", 'wcs-core 2.5.0', "wc_subscriptions_{$this->copy_type}_data" );
|
||||||
|
|
||||||
|
$data_copier_to_object = $this->to_object;
|
||||||
|
$data_copier_from_object = $this->from_object;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filters the data to be copied from one object to another.
|
* Filters the data to be copied from one object to another.
|
||||||
*
|
*
|
||||||
@@ -445,10 +452,10 @@ class WC_Subscriptions_Data_Copier {
|
|||||||
* @type mixed $meta_value The meta value to be copied.
|
* @type mixed $meta_value The meta value to be copied.
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* @param WC_Order $this->to_object The object to copy data to.
|
* @param WC_Order $data_copier_to_object The object to copy data to.
|
||||||
* @param WC_Order $this->from_object The object to copy data from.
|
* @param WC_Order $data_copier_from_object The object to copy data from.
|
||||||
*/
|
*/
|
||||||
$data_array = apply_filters( "wcs_{$this->copy_type}_meta", $data_array, $this->to_object, $this->from_object );
|
$data_array = apply_filters( "wcs_{$this->copy_type}_meta", $data_array, $data_copier_to_object, $data_copier_from_object );
|
||||||
|
|
||||||
// Return the data to a key => value format.
|
// Return the data to a key => value format.
|
||||||
return wp_list_pluck( $data_array, 'meta_value', 'meta_key' );
|
return wp_list_pluck( $data_array, 'meta_value', 'meta_key' );
|
||||||
|
@@ -54,10 +54,10 @@ class WC_Subscriptions_Email_Notifications {
|
|||||||
add_filter( 'woocommerce_subscription_settings', [ __CLASS__, 'add_settings' ], 20 );
|
add_filter( 'woocommerce_subscription_settings', [ __CLASS__, 'add_settings' ], 20 );
|
||||||
|
|
||||||
// Bump settings update time whenever related options change.
|
// Bump settings update time whenever related options change.
|
||||||
add_action( 'update_option_' . WC_Subscriptions_Admin::$option_prefix . self::$offset_setting_string, [ __CLASS__, 'set_notification_settings_update_time' ], 10, 3 );
|
add_action( 'update_option_' . WC_Subscriptions_Admin::$option_prefix . self::$offset_setting_string, [ __CLASS__, 'set_notification_settings_update_time' ], 10 );
|
||||||
add_action( 'update_option_' . WC_Subscriptions_Admin::$option_prefix . self::$switch_setting_string, [ __CLASS__, 'set_notification_settings_update_time' ], 10, 3 );
|
add_action( 'update_option_' . WC_Subscriptions_Admin::$option_prefix . self::$switch_setting_string, [ __CLASS__, 'set_notification_settings_update_time' ], 10 );
|
||||||
add_action( 'add_option_' . WC_Subscriptions_Admin::$option_prefix . self::$offset_setting_string, [ __CLASS__, 'set_notification_settings_update_time' ], 10, 2 );
|
add_action( 'add_option_' . WC_Subscriptions_Admin::$option_prefix . self::$offset_setting_string, [ __CLASS__, 'set_notification_settings_update_time' ], 10 );
|
||||||
add_action( 'add_option_' . WC_Subscriptions_Admin::$option_prefix . self::$switch_setting_string, [ __CLASS__, 'set_notification_settings_update_time' ], 10, 2 );
|
add_action( 'add_option_' . WC_Subscriptions_Admin::$option_prefix . self::$switch_setting_string, [ __CLASS__, 'set_notification_settings_update_time' ], 10 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -45,7 +45,7 @@ class WC_Subscriptions_Email {
|
|||||||
add_action( 'woocommerce_subscriptions_email_order_details', __CLASS__ . '::order_download_details', 10, 4 );
|
add_action( 'woocommerce_subscriptions_email_order_details', __CLASS__ . '::order_download_details', 10, 4 );
|
||||||
add_action( 'woocommerce_subscriptions_email_order_details', __CLASS__ . '::order_details', 10, 4 );
|
add_action( 'woocommerce_subscriptions_email_order_details', __CLASS__ . '::order_details', 10, 4 );
|
||||||
|
|
||||||
add_action( 'woocommerce_subscription_status_pending-cancel_to_active', __CLASS__ . '::maybe_clear_cancelled_email_flag', 10, 4 );
|
add_action( 'woocommerce_subscription_status_pending-cancel_to_active', __CLASS__ . '::maybe_clear_cancelled_email_flag', 10 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -102,9 +102,9 @@ class WC_Subscriptions_Email {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_action( 'woocommerce_subscription_status_updated', __CLASS__ . '::send_cancelled_email', 10, 2 );
|
add_action( 'woocommerce_subscription_status_updated', __CLASS__ . '::send_cancelled_email', 10 );
|
||||||
add_action( 'woocommerce_subscription_status_expired', __CLASS__ . '::send_expired_email', 10, 2 );
|
add_action( 'woocommerce_subscription_status_expired', __CLASS__ . '::send_expired_email', 10 );
|
||||||
add_action( 'woocommerce_customer_changed_subscription_to_on-hold', __CLASS__ . '::send_on_hold_email', 10, 2 );
|
add_action( 'woocommerce_customer_changed_subscription_to_on-hold', __CLASS__ . '::send_on_hold_email', 10 );
|
||||||
add_action( 'woocommerce_subscriptions_switch_completed', __CLASS__ . '::send_switch_order_email', 10 );
|
add_action( 'woocommerce_subscriptions_switch_completed', __CLASS__ . '::send_switch_order_email', 10 );
|
||||||
|
|
||||||
foreach ( $order_email_actions as $action ) {
|
foreach ( $order_email_actions as $action ) {
|
||||||
@@ -268,7 +268,7 @@ class WC_Subscriptions_Email {
|
|||||||
* @param WC_Order $order
|
* @param WC_Order $order
|
||||||
* @param bool $sent_to_admin Whether the email is sent to admin - defaults to false
|
* @param bool $sent_to_admin Whether the email is sent to admin - defaults to false
|
||||||
* @param bool $plain_text Whether the email should use plain text templates - defaults to false
|
* @param bool $plain_text Whether the email should use plain text templates - defaults to false
|
||||||
* @param WC_Email $email
|
* @param string $email
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.1
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.1
|
||||||
*/
|
*/
|
||||||
public static function order_details( $order, $sent_to_admin = false, $plain_text = false, $email = '' ) {
|
public static function order_details( $order, $sent_to_admin = false, $plain_text = false, $email = '' ) {
|
||||||
@@ -336,8 +336,8 @@ class WC_Subscriptions_Email {
|
|||||||
/**
|
/**
|
||||||
* Detach WC transactional emails from a specific hook.
|
* Detach WC transactional emails from a specific hook.
|
||||||
*
|
*
|
||||||
* @param string Optional. The action hook or filter to detach WC core's transactional emails from. Defaults to the current filter.
|
* @param string $hook Optional. The action hook or filter to detach WC core's transactional emails from. Defaults to the current filter.
|
||||||
* @param int Optional. The priority the function runs on. Default 10.
|
* @param int $priority Optional. The priority the function runs on. Default 10.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.3
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.3
|
||||||
*/
|
*/
|
||||||
public static function detach_woocommerce_transactional_email( $hook = '', $priority = 10 ) {
|
public static function detach_woocommerce_transactional_email( $hook = '', $priority = 10 ) {
|
||||||
@@ -354,9 +354,9 @@ class WC_Subscriptions_Email {
|
|||||||
/**
|
/**
|
||||||
* Attach WC transactional emails to a specific hook.
|
* Attach WC transactional emails to a specific hook.
|
||||||
*
|
*
|
||||||
* @param string Optional. The action hook or filter to attach WC core's transactional emails to. Defaults to the current filter.
|
* @param string $hook Optional. The action hook or filter to attach WC core's transactional emails to. Defaults to the current filter.
|
||||||
* @param int Optional. The priority the function should run on. Default 10.
|
* @param int $priority Optional. The priority the function should run on. Default 10.
|
||||||
* @param int Optional. The number of arguments the function accepts. Default 10.
|
* @param int $accepted_args Optional. The number of arguments the function accepts. Default 10.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.3
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.3
|
||||||
*/
|
*/
|
||||||
public static function attach_woocommerce_transactional_email( $hook = '', $priority = 10, $accepted_args = 10 ) {
|
public static function attach_woocommerce_transactional_email( $hook = '', $priority = 10, $accepted_args = 10 ) {
|
||||||
@@ -378,7 +378,7 @@ class WC_Subscriptions_Email {
|
|||||||
* @param WC_Order $order
|
* @param WC_Order $order
|
||||||
* @param bool $sent_to_admin Whether the email is sent to admin - defaults to false
|
* @param bool $sent_to_admin Whether the email is sent to admin - defaults to false
|
||||||
* @param bool $plain_text Whether the email should use plain text templates - defaults to false
|
* @param bool $plain_text Whether the email should use plain text templates - defaults to false
|
||||||
* @param WC_Email $email
|
* @param string $email
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.17
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.17
|
||||||
*/
|
*/
|
||||||
public static function order_download_details( $order, $sent_to_admin = false, $plain_text = false, $email = '' ) {
|
public static function order_download_details( $order, $sent_to_admin = false, $plain_text = false, $email = '' ) {
|
||||||
|
@@ -53,8 +53,11 @@ class WC_Subscriptions_Extend_Store_Endpoint {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @phpstan-ignore class.notFound
|
||||||
self::$schema = class_exists( 'Automattic\WooCommerce\StoreApi\StoreApi' ) ? Automattic\WooCommerce\StoreApi\StoreApi::container()->get( Automattic\WooCommerce\StoreApi\SchemaController::class ) : Package::container()->get( Automattic\WooCommerce\Blocks\StoreApi\SchemaController::class );
|
self::$schema = class_exists( 'Automattic\WooCommerce\StoreApi\StoreApi' ) ? Automattic\WooCommerce\StoreApi\StoreApi::container()->get( Automattic\WooCommerce\StoreApi\SchemaController::class ) : Package::container()->get( Automattic\WooCommerce\Blocks\StoreApi\SchemaController::class );
|
||||||
|
// @phpstan-ignore class.notFound
|
||||||
self::$money_formatter = function_exists( 'woocommerce_store_api_get_formatter' ) ? woocommerce_store_api_get_formatter( 'money' ) : Package::container()->get( ExtendRestApi::class )->get_formatter( 'money' );
|
self::$money_formatter = function_exists( 'woocommerce_store_api_get_formatter' ) ? woocommerce_store_api_get_formatter( 'money' ) : Package::container()->get( ExtendRestApi::class )->get_formatter( 'money' );
|
||||||
|
// @phpstan-ignore class.notFound
|
||||||
self::$currency_formatter = function_exists( 'woocommerce_store_api_get_formatter' ) ? woocommerce_store_api_get_formatter( 'currency' ) : Package::container()->get( ExtendRestApi::class )->get_formatter( 'currency' );
|
self::$currency_formatter = function_exists( 'woocommerce_store_api_get_formatter' ) ? woocommerce_store_api_get_formatter( 'currency' ) : Package::container()->get( ExtendRestApi::class )->get_formatter( 'currency' );
|
||||||
self::extend_store();
|
self::extend_store();
|
||||||
}
|
}
|
||||||
@@ -68,6 +71,7 @@ class WC_Subscriptions_Extend_Store_Endpoint {
|
|||||||
if ( function_exists( 'woocommerce_store_api_register_endpoint_data' ) ) {
|
if ( function_exists( 'woocommerce_store_api_register_endpoint_data' ) ) {
|
||||||
woocommerce_store_api_register_endpoint_data( $args );
|
woocommerce_store_api_register_endpoint_data( $args );
|
||||||
} else {
|
} else {
|
||||||
|
// @phpstan-ignore class.notFound
|
||||||
Package::container()->get( ExtendRestApi::class )->register_endpoint_data( $args );
|
Package::container()->get( ExtendRestApi::class )->register_endpoint_data( $args );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -81,6 +85,7 @@ class WC_Subscriptions_Extend_Store_Endpoint {
|
|||||||
if ( function_exists( 'woocommerce_store_api_register_payment_requirements' ) ) {
|
if ( function_exists( 'woocommerce_store_api_register_payment_requirements' ) ) {
|
||||||
woocommerce_store_api_register_payment_requirements( $args );
|
woocommerce_store_api_register_payment_requirements( $args );
|
||||||
} else {
|
} else {
|
||||||
|
// @phpstan-ignore class.notFound
|
||||||
Package::container()->get( ExtendRestApi::class )->register_payment_requirements( $args );
|
Package::container()->get( ExtendRestApi::class )->register_payment_requirements( $args );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -92,6 +97,7 @@ class WC_Subscriptions_Extend_Store_Endpoint {
|
|||||||
// Register into `cart/items`
|
// Register into `cart/items`
|
||||||
self::register_endpoint_data(
|
self::register_endpoint_data(
|
||||||
array(
|
array(
|
||||||
|
// @phpstan-ignore class.notFound
|
||||||
'endpoint' => CartItemSchema::IDENTIFIER,
|
'endpoint' => CartItemSchema::IDENTIFIER,
|
||||||
'namespace' => self::IDENTIFIER,
|
'namespace' => self::IDENTIFIER,
|
||||||
'data_callback' => array( 'WC_Subscriptions_Extend_Store_Endpoint', 'extend_cart_item_data' ),
|
'data_callback' => array( 'WC_Subscriptions_Extend_Store_Endpoint', 'extend_cart_item_data' ),
|
||||||
@@ -103,6 +109,7 @@ class WC_Subscriptions_Extend_Store_Endpoint {
|
|||||||
// Register into `cart`
|
// Register into `cart`
|
||||||
self::register_endpoint_data(
|
self::register_endpoint_data(
|
||||||
array(
|
array(
|
||||||
|
// @phpstan-ignore class.notFound
|
||||||
'endpoint' => CartSchema::IDENTIFIER,
|
'endpoint' => CartSchema::IDENTIFIER,
|
||||||
'namespace' => self::IDENTIFIER,
|
'namespace' => self::IDENTIFIER,
|
||||||
'data_callback' => array( 'WC_Subscriptions_Extend_Store_Endpoint', 'extend_cart_data' ),
|
'data_callback' => array( 'WC_Subscriptions_Extend_Store_Endpoint', 'extend_cart_data' ),
|
||||||
@@ -266,7 +273,7 @@ class WC_Subscriptions_Extend_Store_Endpoint {
|
|||||||
// Add extra package data to array.
|
// Add extra package data to array.
|
||||||
if ( count( $packages ) ) {
|
if ( count( $packages ) ) {
|
||||||
$packages = array_map(
|
$packages = array_map(
|
||||||
function( $key, $package, $index ) use ( $cart, $cart_key ) {
|
function( $key, $package, $index ) use ( $cart ) {
|
||||||
$package['package_id'] = isset( $package['package_id'] ) ? $package['package_id'] : $key;
|
$package['package_id'] = isset( $package['package_id'] ) ? $package['package_id'] : $key;
|
||||||
$package['package_name'] = isset( $package['package_name'] ) ? $package['package_name'] : self::get_shipping_package_name( $package, $cart );
|
$package['package_name'] = isset( $package['package_name'] ) ? $package['package_name'] : self::get_shipping_package_name( $package, $cart );
|
||||||
return $package;
|
return $package;
|
||||||
|
@@ -284,9 +284,10 @@ class WC_Subscriptions_Manager {
|
|||||||
* function directly, do not call this function also.
|
* function directly, do not call this function also.
|
||||||
*
|
*
|
||||||
* @param WC_Order|int $order The order or ID of the order for which subscription payments should be marked against.
|
* @param WC_Order|int $order The order or ID of the order for which subscription payments should be marked against.
|
||||||
|
* @param int $product_id The ID of the product.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
||||||
*/
|
*/
|
||||||
public static function process_subscription_payments_on_order( $order, $product_id = '' ) {
|
public static function process_subscription_payments_on_order( $order, $product_id = 0 ) {
|
||||||
wcs_deprecated_function( __METHOD__, '2.6.0' );
|
wcs_deprecated_function( __METHOD__, '2.6.0' );
|
||||||
$subscriptions = wcs_get_subscriptions_for_order( $order );
|
$subscriptions = wcs_get_subscriptions_for_order( $order );
|
||||||
|
|
||||||
@@ -307,9 +308,10 @@ class WC_Subscriptions_Manager {
|
|||||||
* function directly, do not call this function also.
|
* function directly, do not call this function also.
|
||||||
*
|
*
|
||||||
* @param int|WC_Order $order The order or ID of the order for which subscription payments should be marked against.
|
* @param int|WC_Order $order The order or ID of the order for which subscription payments should be marked against.
|
||||||
|
* @param int $product_id The ID of the product.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
||||||
*/
|
*/
|
||||||
public static function process_subscription_payment_failure_on_order( $order, $product_id = '' ) {
|
public static function process_subscription_payment_failure_on_order( $order, $product_id = 0 ) {
|
||||||
wcs_deprecated_function( __METHOD__, '2.6.0' );
|
wcs_deprecated_function( __METHOD__, '2.6.0' );
|
||||||
$subscriptions = wcs_get_subscriptions_for_order( $order );
|
$subscriptions = wcs_get_subscriptions_for_order( $order );
|
||||||
|
|
||||||
@@ -364,7 +366,7 @@ class WC_Subscriptions_Manager {
|
|||||||
foreach ( $subscriptions as $subscription ) {
|
foreach ( $subscriptions as $subscription ) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ( ! $subscription->has_status( wcs_get_subscription_ended_statuses() ) ) {
|
if ( $subscription->can_be_updated_to( 'on-hold' ) ) {
|
||||||
$subscription->update_status( 'on-hold' );
|
$subscription->update_status( 'on-hold' );
|
||||||
}
|
}
|
||||||
} catch ( Exception $e ) {
|
} catch ( Exception $e ) {
|
||||||
@@ -443,30 +445,39 @@ class WC_Subscriptions_Manager {
|
|||||||
|
|
||||||
$subscriptions = wcs_get_subscriptions_for_order( $order, array( 'order_type' => 'parent' ) );
|
$subscriptions = wcs_get_subscriptions_for_order( $order, array( 'order_type' => 'parent' ) );
|
||||||
|
|
||||||
if ( ! empty( $subscriptions ) ) {
|
if ( empty( $subscriptions ) ) {
|
||||||
|
return;
|
||||||
if ( ! is_object( $order ) ) {
|
|
||||||
$order = wc_get_order( $order );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set subscription status to failed and log failure
|
|
||||||
if ( $order->has_status( 'failed' ) ) {
|
|
||||||
$order->update_status( 'failed', __( 'Subscription sign up failed.', 'woocommerce-subscriptions' ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ( $subscriptions as $subscription ) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
$subscription->payment_failed();
|
|
||||||
|
|
||||||
} catch ( Exception $e ) {
|
|
||||||
// translators: $1: order number, $2: error message
|
|
||||||
$subscription->add_order_note( sprintf( __( 'Failed to process failed payment on subscription for order #%1$s: %2$s', 'woocommerce-subscriptions' ), is_object( $order ) ? $order->get_order_number() : $order, $e->getMessage() ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
do_action( 'failed_subscription_sign_ups_for_order', $order );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( ! is_object( $order ) ) {
|
||||||
|
$order = wc_get_order( $order );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set subscription status to failed and log failure
|
||||||
|
if ( $order->has_status( 'failed' ) ) {
|
||||||
|
$order->update_status( 'failed', __( 'Subscription sign up failed.', 'woocommerce-subscriptions' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ( $subscriptions as $subscription ) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
$new_status = $subscription->has_status( 'pending' ) && $subscription->get_parent_id() === $order->get_id() ? 'pending' : 'on-hold';
|
||||||
|
$subscription->payment_failed( $new_status );
|
||||||
|
|
||||||
|
} catch ( Exception $e ) {
|
||||||
|
// translators: $1: order number, $2: error message
|
||||||
|
$subscription->add_order_note( sprintf( __( 'Failed to process failed payment on subscription for order #%1$s: %2$s', 'woocommerce-subscriptions' ), is_object( $order ) ? $order->get_order_number() : $order, $e->getMessage() ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fires after an order is marked as failed.
|
||||||
|
*
|
||||||
|
* @param WC_Order $order Failed order object.
|
||||||
|
*
|
||||||
|
* @since 1.5.0
|
||||||
|
*/
|
||||||
|
do_action( 'failed_subscription_sign_ups_for_order', $order );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -633,7 +644,7 @@ class WC_Subscriptions_Manager {
|
|||||||
public static function process_subscriptions_on_checkout( $order ) {
|
public static function process_subscriptions_on_checkout( $order ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'WC_Subscriptions_Checkout::process_checkout()' );
|
_deprecated_function( __METHOD__, '2.0', 'WC_Subscriptions_Checkout::process_checkout()' );
|
||||||
|
|
||||||
if ( ! empty( $_POST['_wpnonce'] ) && wp_verify_nonce( $_POST['_wpnonce'], 'woocommerce-process_checkout' ) ) {
|
if ( ! empty( $_POST['_wpnonce'] ) && wp_verify_nonce( wc_clean( wp_unslash( $_POST['_wpnonce'] ) ), 'woocommerce-process_checkout' ) ) {
|
||||||
WC_Subscriptions_Checkout::process_checkout( $order, $_POST );
|
WC_Subscriptions_Checkout::process_checkout( $order, $_POST );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -675,6 +686,7 @@ class WC_Subscriptions_Manager {
|
|||||||
case 'pending':
|
case 'pending':
|
||||||
_deprecated_argument( __METHOD__, '2.0', 'The "pending" status value is deprecated.' );
|
_deprecated_argument( __METHOD__, '2.0', 'The "pending" status value is deprecated.' );
|
||||||
default:
|
default:
|
||||||
|
// @phpstan-ignore arguments.count
|
||||||
self::create_pending_subscription_for_order( $order );
|
self::create_pending_subscription_for_order( $order );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1083,7 +1095,7 @@ class WC_Subscriptions_Manager {
|
|||||||
* @param int $user_id The ID of the user who owns the subscriptions. Although this parameter is optional, if you have the User ID you should pass it to improve performance.
|
* @param int $user_id The ID of the user who owns the subscriptions. Although this parameter is optional, if you have the User ID you should pass it to improve performance.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
||||||
*/
|
*/
|
||||||
public static function can_subscription_be_changed_to( $new_status_or_meta, $subscription_key, $user_id = '' ) {
|
public static function can_subscription_be_changed_to( $new_status_or_meta, $subscription_key, $user_id = 0 ) {
|
||||||
|
|
||||||
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::can_be_updated_to( $new_status_or_meta )' );
|
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::can_be_updated_to( $new_status_or_meta )' );
|
||||||
|
|
||||||
@@ -1127,7 +1139,7 @@ class WC_Subscriptions_Manager {
|
|||||||
* Return an associative array of a given subscriptions details (if it exists).
|
* Return an associative array of a given subscriptions details (if it exists).
|
||||||
*
|
*
|
||||||
* @param string $subscription_key A subscription key of the form created by @see self::get_subscription_key()
|
* @param string $subscription_key A subscription key of the form created by @see self::get_subscription_key()
|
||||||
* @param deprecated don't use
|
* @param mixed $deprecated Don't use
|
||||||
* @return array Subscription details
|
* @return array Subscription details
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.1
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.1
|
||||||
*/
|
*/
|
||||||
@@ -1217,7 +1229,7 @@ class WC_Subscriptions_Manager {
|
|||||||
* M – for months; allowable range is 1 to 24
|
* M – for months; allowable range is 1 to 24
|
||||||
* Y – for years; allowable range is 1 to 5
|
* Y – for years; allowable range is 1 to 5
|
||||||
*
|
*
|
||||||
* @param subscription_period string (optional) One of day, week, month or year. If empty, all subscription ranges are returned.
|
* @param string $subscription_period string (optional) One of day, week, month or year. If empty, all subscription ranges are returned.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
@@ -1230,7 +1242,7 @@ class WC_Subscriptions_Manager {
|
|||||||
* Returns an array of allowable trial periods.
|
* Returns an array of allowable trial periods.
|
||||||
*
|
*
|
||||||
* @see self::get_subscription_ranges()
|
* @see self::get_subscription_ranges()
|
||||||
* @param subscription_period string (optional) One of day, week, month or year. If empty, all subscription ranges are returned.
|
* @param string $subscription_period string (optional) One of day, week, month or year. If empty, all subscription ranges are returned.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.1
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.1
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
@@ -1265,12 +1277,12 @@ class WC_Subscriptions_Manager {
|
|||||||
/**
|
/**
|
||||||
* Returns the string key for a subscription purchased in an order specified by $order_id
|
* Returns the string key for a subscription purchased in an order specified by $order_id
|
||||||
*
|
*
|
||||||
* @param order_id int The ID of the order in which the subscription was purchased.
|
* @param int $order_id The ID of the order in which the subscription was purchased.
|
||||||
* @param product_id int The ID of the subscription product.
|
* @param int $product_id The ID of the subscription product.
|
||||||
* @return string The key representing the given subscription.
|
* @return string The key representing the given subscription.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
||||||
*/
|
*/
|
||||||
public static function get_subscription_key( $order_id, $product_id = '' ) {
|
public static function get_subscription_key( $order_id, $product_id = 0 ) {
|
||||||
|
|
||||||
_deprecated_function( __METHOD__, '2.0', 'wcs_get_old_subscription_key( WC_Subscription $subscription )' );
|
_deprecated_function( __METHOD__, '2.0', 'wcs_get_old_subscription_key( WC_Subscription $subscription )' );
|
||||||
|
|
||||||
@@ -1313,7 +1325,7 @@ class WC_Subscriptions_Manager {
|
|||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
public static function get_subscriptions_failed_payment_count( $subscription_key, $user_id = '' ) {
|
public static function get_subscriptions_failed_payment_count( $subscription_key, $user_id = 0 ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::get_failed_payment_count()' );
|
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::get_failed_payment_count()' );
|
||||||
return apply_filters( 'woocommerce_subscription_failed_payment_count', wcs_get_subscription_from_key( $subscription_key )->get_failed_payment_count(), $user_id, $subscription_key );
|
return apply_filters( 'woocommerce_subscription_failed_payment_count', wcs_get_subscription_from_key( $subscription_key )->get_failed_payment_count(), $user_id, $subscription_key );
|
||||||
}
|
}
|
||||||
@@ -1322,7 +1334,6 @@ class WC_Subscriptions_Manager {
|
|||||||
* Returns the number of completed payments for a given subscription (including the initial payment).
|
* Returns the number of completed payments for a given subscription (including the initial payment).
|
||||||
*
|
*
|
||||||
* @param string $subscription_key A subscription key of the form created by @see self::get_subscription_key()
|
* @param string $subscription_key A subscription key of the form created by @see self::get_subscription_key()
|
||||||
* @param int $user_id The ID of the user who owns the subscriptions. Although this parameter is optional, if you have the User ID you should pass it to improve performance.
|
|
||||||
* @return int The number of outstanding failed payments on the subscription, if any.
|
* @return int The number of outstanding failed payments on the subscription, if any.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.4
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.4
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
@@ -1342,7 +1353,7 @@ class WC_Subscriptions_Manager {
|
|||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.1
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.1
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
public static function get_subscription_expiration_date( $subscription_key, $user_id = '', $type = 'mysql' ) {
|
public static function get_subscription_expiration_date( $subscription_key, $user_id = 0, $type = 'mysql' ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::get_date( "end" )' );
|
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::get_date( "end" )' );
|
||||||
$subscription = wcs_get_subscription_from_key( $subscription_key );
|
$subscription = wcs_get_subscription_from_key( $subscription_key );
|
||||||
$expiration_date = ( 'mysql' == $type ) ? $subscription->get_date( 'end' ) : $subscription->get_time( 'end' );
|
$expiration_date = ( 'mysql' == $type ) ? $subscription->get_date( 'end' ) : $subscription->get_time( 'end' );
|
||||||
@@ -1354,12 +1365,12 @@ class WC_Subscriptions_Manager {
|
|||||||
*
|
*
|
||||||
* @param string $subscription_key A subscription key of the form created by @see self::get_subscription_key()
|
* @param string $subscription_key A subscription key of the form created by @see self::get_subscription_key()
|
||||||
* @param int $user_id (optional) The ID of the user who owns the subscriptions. Although this parameter is optional, if you have the User ID you should pass it to improve performance.
|
* @param int $user_id (optional) The ID of the user who owns the subscriptions. Although this parameter is optional, if you have the User ID you should pass it to improve performance.
|
||||||
* @param (optional) $next_payment string | int The date and time the next payment is due, either as MySQL formatted datetime string or a Unix timestamp. If empty, @see self::calculate_subscription_expiration_date() will be called.
|
* @param string|int $expiration_date (optional)The date and time the subscription will expire, either as MySQL formatted datetime string or a Unix timestamp. If empty, @see self::calculate_subscription_expiration_date() will be called.
|
||||||
* @return mixed If the expiration does not get set, returns false, otherwise it will return a MySQL datetime formatted string for the new date when the subscription will expire
|
* @return mixed If the expiration does not get set, returns false, otherwise it will return a MySQL datetime formatted string for the new date when the subscription will expire
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2.4
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2.4
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
public static function set_expiration_date( $subscription_key, $user_id = '', $expiration_date = '' ) {
|
public static function set_expiration_date( $subscription_key, $user_id = 0, $expiration_date = '' ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::update_dates( array( "end" => $expiration_date ) )' );
|
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::update_dates( array( "end" => $expiration_date ) )' );
|
||||||
if ( is_int( $expiration_date ) ) {
|
if ( is_int( $expiration_date ) ) {
|
||||||
$expiration_date = gmdate( 'Y-m-d H:i:s', $expiration_date );
|
$expiration_date = gmdate( 'Y-m-d H:i:s', $expiration_date );
|
||||||
@@ -1382,7 +1393,7 @@ class WC_Subscriptions_Manager {
|
|||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.1
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.1
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
public static function calculate_subscription_expiration_date( $subscription_key, $user_id = '', $type = 'mysql' ) {
|
public static function calculate_subscription_expiration_date( $subscription_key, $user_id = 0, $type = 'mysql' ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::get_date( "end" )' );
|
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::get_date( "end" )' );
|
||||||
$subscription = wcs_get_subscription_from_key( $subscription_key );
|
$subscription = wcs_get_subscription_from_key( $subscription_key );
|
||||||
$expiration_date = ( 'mysql' == $type ) ? $subscription->get_date( 'end' ) : $subscription->get_time( 'end' );
|
$expiration_date = ( 'mysql' == $type ) ? $subscription->get_date( 'end' ) : $subscription->get_time( 'end' );
|
||||||
@@ -1399,7 +1410,7 @@ class WC_Subscriptions_Manager {
|
|||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
public static function get_next_payment_date( $subscription_key, $user_id = '', $type = 'mysql' ) {
|
public static function get_next_payment_date( $subscription_key, $user_id = 0, $type = 'mysql' ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::get_date( "next_payment" )' );
|
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::get_date( "next_payment" )' );
|
||||||
$subscription = wcs_get_subscription_from_key( $subscription_key );
|
$subscription = wcs_get_subscription_from_key( $subscription_key );
|
||||||
$next_payment = ( 'mysql' == $type ) ? $subscription->get_date( 'next_payment' ) : $subscription->get_time( 'next_payment' );
|
$next_payment = ( 'mysql' == $type ) ? $subscription->get_date( 'next_payment' ) : $subscription->get_time( 'next_payment' );
|
||||||
@@ -1414,12 +1425,12 @@ class WC_Subscriptions_Manager {
|
|||||||
*
|
*
|
||||||
* @param string $subscription_key A subscription key of the form created by @see self::get_subscription_key()
|
* @param string $subscription_key A subscription key of the form created by @see self::get_subscription_key()
|
||||||
* @param int $user_id (optional) The ID of the user who owns the subscriptions. Although this parameter is optional, if you have the User ID you should pass it to improve performance.
|
* @param int $user_id (optional) The ID of the user who owns the subscriptions. Although this parameter is optional, if you have the User ID you should pass it to improve performance.
|
||||||
* @param (optional) $next_payment string | int The date and time the next payment is due, either as MySQL formatted datetime string or a Unix timestamp. If empty, @see self::calculate_next_payment_date() will be called.
|
* @param string|int $next_payment (optional) The date and time the next payment is due, either as MySQL formatted datetime string or a Unix timestamp. If empty, @see self::calculate_next_payment_date() will be called.
|
||||||
* @return mixed If there is no future payment set, returns 0, otherwise it will return a MySQL datetime formatted string for the date of the next payment
|
* @return mixed If there is no future payment set, returns 0, otherwise it will return a MySQL datetime formatted string for the date of the next payment
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
public static function set_next_payment_date( $subscription_key, $user_id = '', $next_payment = '' ) {
|
public static function set_next_payment_date( $subscription_key, $user_id = 0, $next_payment = '' ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::update_dates( array( "next_payment" => $next_payment ) )' );
|
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::update_dates( array( "next_payment" => $next_payment ) )' );
|
||||||
|
|
||||||
if ( is_int( $next_payment ) ) {
|
if ( is_int( $next_payment ) ) {
|
||||||
@@ -1441,7 +1452,7 @@ class WC_Subscriptions_Manager {
|
|||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
public static function get_last_payment_date( $subscription_key, $user_id = '', $type = 'mysql' ) {
|
public static function get_last_payment_date( $subscription_key, $user_id = 0, $type = 'mysql' ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::get_date( "last_payment" )' );
|
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::get_date( "last_payment" )' );
|
||||||
$subscription = wcs_get_subscription_from_key( $subscription_key );
|
$subscription = wcs_get_subscription_from_key( $subscription_key );
|
||||||
$last_payment_date = ( 'mysql' == $type ) ? $subscription->get_date( 'last_order_date_created' ) : $subscription->get_time( 'last_order_date_created' );
|
$last_payment_date = ( 'mysql' == $type ) ? $subscription->get_date( 'last_order_date_created' ) : $subscription->get_time( 'last_order_date_created' );
|
||||||
@@ -1457,7 +1468,7 @@ class WC_Subscriptions_Manager {
|
|||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
public static function update_wp_cron_lock( $subscription_key, $lock_time, $user_id = '' ) {
|
public static function update_wp_cron_lock( $subscription_key, $lock_time, $user_id = 0 ) {
|
||||||
_deprecated_function( __METHOD__, '2.0' );
|
_deprecated_function( __METHOD__, '2.0' );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1471,7 +1482,7 @@ class WC_Subscriptions_Manager {
|
|||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
public static function calculate_next_payment_date( $subscription_key, $user_id = '', $type = 'mysql', $from_date = '' ) {
|
public static function calculate_next_payment_date( $subscription_key, $user_id = 0, $type = 'mysql', $from_date = '' ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::calculate_date( "next_payment" )' );
|
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::calculate_date( "next_payment" )' );
|
||||||
$subscription = wcs_get_subscription_from_key( $subscription_key );
|
$subscription = wcs_get_subscription_from_key( $subscription_key );
|
||||||
$next_payment = $subscription->calculate_date( 'next_payment' );
|
$next_payment = $subscription->calculate_date( 'next_payment' );
|
||||||
@@ -1486,7 +1497,7 @@ class WC_Subscriptions_Manager {
|
|||||||
* @return mixed If the subscription has no trial period, returns 0, otherwise it will return the date the trial period ends or ended in the form specified by $type
|
* @return mixed If the subscription has no trial period, returns 0, otherwise it will return the date the trial period ends or ended in the form specified by $type
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
*/
|
*/
|
||||||
public static function get_trial_expiration_date( $subscription_key, $user_id = '', $type = 'mysql' ) {
|
public static function get_trial_expiration_date( $subscription_key, $user_id = 0, $type = 'mysql' ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::get_date( "trial_end" )' );
|
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::get_date( "trial_end" )' );
|
||||||
$subscription = wcs_get_subscription_from_key( $subscription_key );
|
$subscription = wcs_get_subscription_from_key( $subscription_key );
|
||||||
$trial_end_date = ( 'mysql' == $type ) ? $subscription->get_date( 'trial_end' ) : $subscription->get_time( 'trial_end' );
|
$trial_end_date = ( 'mysql' == $type ) ? $subscription->get_date( 'trial_end' ) : $subscription->get_time( 'trial_end' );
|
||||||
@@ -1498,11 +1509,11 @@ class WC_Subscriptions_Manager {
|
|||||||
*
|
*
|
||||||
* @param string $subscription_key A subscription key of the form created by @see self::get_subscription_key()
|
* @param string $subscription_key A subscription key of the form created by @see self::get_subscription_key()
|
||||||
* @param int $user_id (optional) The ID of the user who owns the subscription. Although this parameter is optional, if you have the User ID you should pass it to improve performance.
|
* @param int $user_id (optional) The ID of the user who owns the subscription. Although this parameter is optional, if you have the User ID you should pass it to improve performance.
|
||||||
* @param (optional) $next_payment string | int The date and time the next payment is due, either as MySQL formatted datetime string or a Unix timestamp. If empty, @see self::calculate_next_payment_date() will be called.
|
* @param string|int $trial_expiration_date (optional) The date and time the trial will expire, either as MySQL formatted datetime string or a Unix timestamp. If empty, @see self::calculate_next_payment_date() will be called.
|
||||||
* @return mixed If the trial expiration does not get set, returns false, otherwise it will return a MySQL datetime formatted string for the new date when the trial will expire
|
* @return mixed If the trial expiration does not get set, returns false, otherwise it will return a MySQL datetime formatted string for the new date when the trial will expire
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2.4
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2.4
|
||||||
*/
|
*/
|
||||||
public static function set_trial_expiration_date( $subscription_key, $user_id = '', $trial_expiration_date = '' ) {
|
public static function set_trial_expiration_date( $subscription_key, $user_id = 0, $trial_expiration_date = '' ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::update_dates( array( "trial_end" => $expiration_date ) )' );
|
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::update_dates( array( "trial_end" => $expiration_date ) )' );
|
||||||
if ( is_int( $trial_expiration_date ) ) {
|
if ( is_int( $trial_expiration_date ) ) {
|
||||||
$trial_expiration_date = gmdate( 'Y-m-d H:i:s', $trial_expiration_date );
|
$trial_expiration_date = gmdate( 'Y-m-d H:i:s', $trial_expiration_date );
|
||||||
@@ -1520,7 +1531,7 @@ class WC_Subscriptions_Manager {
|
|||||||
* @param string $type (optional) The format for the Either 'mysql' or 'timestamp'.
|
* @param string $type (optional) The format for the Either 'mysql' or 'timestamp'.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.1
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.1
|
||||||
*/
|
*/
|
||||||
public static function calculate_trial_expiration_date( $subscription_key, $user_id = '', $type = 'mysql' ) {
|
public static function calculate_trial_expiration_date( $subscription_key, $user_id = 0, $type = 'mysql' ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::calculate_date( "trial_end" )' );
|
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::calculate_date( "trial_end" )' );
|
||||||
$subscription = wcs_get_subscription_from_key( $subscription_key );
|
$subscription = wcs_get_subscription_from_key( $subscription_key );
|
||||||
$trial_end = $subscription->calculate_date( 'trial_end' );
|
$trial_end = $subscription->calculate_date( 'trial_end' );
|
||||||
@@ -1551,7 +1562,7 @@ class WC_Subscriptions_Manager {
|
|||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
public static function requires_manual_renewal( $subscription_key, $user_id = '' ) {
|
public static function requires_manual_renewal( $subscription_key, $user_id = 0 ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::is_manual()' );
|
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::is_manual()' );
|
||||||
return wcs_get_subscription_from_key( $subscription_key )->is_manual();
|
return wcs_get_subscription_from_key( $subscription_key )->is_manual();
|
||||||
}
|
}
|
||||||
@@ -1588,7 +1599,7 @@ class WC_Subscriptions_Manager {
|
|||||||
public static function user_owns_subscription( $subscription_key, $user_id = 0 ) {
|
public static function user_owns_subscription( $subscription_key, $user_id = 0 ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'WC_Subscriptions::get_user_id()' );
|
_deprecated_function( __METHOD__, '2.0', 'WC_Subscriptions::get_user_id()' );
|
||||||
|
|
||||||
if ( 0 === $user_id || empty( $user_id ) ) {
|
if ( 0 === $user_id ) {
|
||||||
$user_id = get_current_user_id();
|
$user_id = get_current_user_id();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1607,12 +1618,12 @@ class WC_Subscriptions_Manager {
|
|||||||
* Check if a user has a subscription, optionally specified with $product_id.
|
* Check if a user has a subscription, optionally specified with $product_id.
|
||||||
*
|
*
|
||||||
* @param int $user_id (optional) The id of the user whose subscriptions you want. Defaults to the currently logged in user.
|
* @param int $user_id (optional) The id of the user whose subscriptions you want. Defaults to the currently logged in user.
|
||||||
* @param product_id int (optional) The ID of a subscription product.
|
* @param int $product_id (optional) The ID of a subscription product.
|
||||||
* @param status string (optional) A subscription status to check against. For example, for a $status of 'active', a subscriber must have an active subscription for a return value of true.
|
* @param string $status (optional) A subscription status to check against. For example, for a $status of 'active', a subscriber must have an active subscription for a return value of true.
|
||||||
* @return bool True if the user has the subscription (or any subscription if no subscription specified), otherwise false.
|
* @return bool True if the user has the subscription (or any subscription if no subscription specified), otherwise false.
|
||||||
* @version 1.0.0 - Migrated from WooCommerce Subscriptions v1.3.5
|
* @version 1.0.0 - Migrated from WooCommerce Subscriptions v1.3.5
|
||||||
*/
|
*/
|
||||||
public static function user_has_subscription( $user_id = 0, $product_id = '', $status = 'any' ) {
|
public static function user_has_subscription( $user_id = 0, $product_id = 0, $status = 'any' ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'wcs_user_has_subscription()' );
|
_deprecated_function( __METHOD__, '2.0', 'wcs_user_has_subscription()' );
|
||||||
return wcs_user_has_subscription( $user_id, $product_id, $status );
|
return wcs_user_has_subscription( $user_id, $product_id, $status );
|
||||||
}
|
}
|
||||||
@@ -1625,6 +1636,7 @@ class WC_Subscriptions_Manager {
|
|||||||
*/
|
*/
|
||||||
public static function get_all_users_subscriptions() {
|
public static function get_all_users_subscriptions() {
|
||||||
_deprecated_function( __METHOD__, '2.0' );
|
_deprecated_function( __METHOD__, '2.0' );
|
||||||
|
$subscriptions_in_old_format = array();
|
||||||
|
|
||||||
foreach ( get_users() as $user ) {
|
foreach ( get_users() as $user ) {
|
||||||
foreach ( wcs_get_users_subscriptions( $user->ID ) as $subscription ) {
|
foreach ( wcs_get_users_subscriptions( $user->ID ) as $subscription ) {
|
||||||
@@ -1660,7 +1672,7 @@ class WC_Subscriptions_Manager {
|
|||||||
* @param int $user_id (optional) The id of the user whose subscriptions you want. Defaults to the currently logged in user.
|
* @param int $user_id (optional) The id of the user whose subscriptions you want. Defaults to the currently logged in user.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
||||||
*/
|
*/
|
||||||
public static function get_users_trashed_subscriptions( $user_id = '' ) {
|
public static function get_users_trashed_subscriptions( $user_id = 0 ) {
|
||||||
|
|
||||||
$subscriptions = self::get_users_subscriptions( $user_id );
|
$subscriptions = self::get_users_subscriptions( $user_id );
|
||||||
|
|
||||||
@@ -1717,7 +1729,7 @@ class WC_Subscriptions_Manager {
|
|||||||
*
|
*
|
||||||
* A wrapper for the @see woocommerce_paying_customer() function.
|
* A wrapper for the @see woocommerce_paying_customer() function.
|
||||||
*
|
*
|
||||||
* @param int $order_id The id of the order for which customers should be pulled from and marked as paying.
|
* @param int $order The order for which customers should be pulled from and marked as paying.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
@@ -1789,7 +1801,7 @@ class WC_Subscriptions_Manager {
|
|||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
public static function update_next_payment_date( $new_payment_date, $subscription_key, $user_id = '', $timezone = 'server' ) {
|
public static function update_next_payment_date( $new_payment_date, $subscription_key, $user_id = 0, $timezone = 'server' ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::update_dates( array( "next_payment" => $new_payment_date ) )' );
|
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::update_dates( array( "next_payment" => $new_payment_date ) )' );
|
||||||
|
|
||||||
$new_payment_timestamp = ( is_numeric( $new_payment_date ) ) ? $new_payment_date : wcs_date_to_time( $new_payment_date );
|
$new_payment_timestamp = ( is_numeric( $new_payment_date ) ) ? $new_payment_date : wcs_date_to_time( $new_payment_date );
|
||||||
@@ -2317,7 +2329,7 @@ class WC_Subscriptions_Manager {
|
|||||||
$subscription->update_status( 'cancelled' );
|
$subscription->update_status( 'cancelled' );
|
||||||
}
|
}
|
||||||
|
|
||||||
wp_trash_post( $subscription->get_id(), true );
|
wp_trash_post( $subscription->get_id() );
|
||||||
|
|
||||||
do_action( 'subscription_trashed', $user_id, $subscription_key );
|
do_action( 'subscription_trashed', $user_id, $subscription_key );
|
||||||
}
|
}
|
||||||
@@ -2352,7 +2364,7 @@ class WC_Subscriptions_Manager {
|
|||||||
|
|
||||||
wp_delete_post( $subscription->get_id(), true );
|
wp_delete_post( $subscription->get_id(), true );
|
||||||
|
|
||||||
do_action( 'subscription_deleted', $user_id, $subscription_key, $subscription, $item );
|
do_action( 'subscription_deleted', $user_id, $subscription_key, $subscription, null );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2370,7 +2382,7 @@ class WC_Subscriptions_Manager {
|
|||||||
|
|
||||||
$response = array( 'status' => 'error' );
|
$response = array( 'status' => 'error' );
|
||||||
|
|
||||||
if ( ! wp_verify_nonce( $_POST['wcs_nonce'], 'woocommerce-subscriptions' ) ) {
|
if ( ! wp_verify_nonce( wc_clean( wp_unslash( $_POST['wcs_nonce'] ) ), 'woocommerce-subscriptions' ) ) {
|
||||||
|
|
||||||
$response['message'] = '<div class="error">' . __( 'Invalid security token, please reload the page and try again.', 'woocommerce-subscriptions' ) . '</div>';
|
$response['message'] = '<div class="error">' . __( 'Invalid security token, please reload the page and try again.', 'woocommerce-subscriptions' ) . '</div>';
|
||||||
|
|
||||||
@@ -2385,7 +2397,7 @@ class WC_Subscriptions_Manager {
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
$new_payment_date = sprintf( '%s-%s-%s %s', (int) $_POST['wcs_year'], zeroise( (int) $_POST['wcs_month'], 2 ), zeroise( (int) $_POST['wcs_day'], 2 ), gmdate( 'H:i:s', current_time( 'timestamp' ) ) );
|
$new_payment_date = sprintf( '%s-%s-%s %s', (int) $_POST['wcs_year'], zeroise( (int) $_POST['wcs_month'], 2 ), zeroise( (int) $_POST['wcs_day'], 2 ), gmdate( 'H:i:s', current_time( 'timestamp' ) ) );
|
||||||
$new_payment_timestamp = self::update_next_payment_date( $new_payment_date, $_POST['wcs_subscription_key'], self::get_user_id_from_subscription_key( $_POST['wcs_subscription_key'] ), 'user' );
|
$new_payment_timestamp = self::update_next_payment_date( $new_payment_date, wc_clean( wp_unslash( $_POST['wcs_subscription_key'] ) ), self::get_user_id_from_subscription_key( wc_clean( wp_unslash( $_POST['wcs_subscription_key'] ) ) ), 'user' );
|
||||||
|
|
||||||
if ( is_wp_error( $new_payment_timestamp ) ) {
|
if ( is_wp_error( $new_payment_timestamp ) ) {
|
||||||
|
|
||||||
@@ -2412,6 +2424,7 @@ class WC_Subscriptions_Manager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
echo wcs_json_encode( $response );
|
echo wcs_json_encode( $response );
|
||||||
|
|
||||||
exit();
|
exit();
|
||||||
@@ -2462,7 +2475,7 @@ class WC_Subscriptions_Manager {
|
|||||||
$subscription = wcs_get_subscription_from_key( $subscription_key );
|
$subscription = wcs_get_subscription_from_key( $subscription_key );
|
||||||
|
|
||||||
// Don't reschedule for cancelled, suspended or expired subscriptions
|
// Don't reschedule for cancelled, suspended or expired subscriptions
|
||||||
if ( ! $subscription->has_status( 'expired', 'cancelled', 'on-hold' ) ) {
|
if ( ! $subscription->has_status( [ 'expired', 'cancelled', 'on-hold' ] ) ) {
|
||||||
|
|
||||||
// Reschedule the 'scheduled_subscription_payment' hook
|
// Reschedule the 'scheduled_subscription_payment' hook
|
||||||
if ( $subscription->can_date_be_updated( 'next_payment' ) ) {
|
if ( $subscription->can_date_be_updated( 'next_payment' ) ) {
|
||||||
|
@@ -106,7 +106,7 @@ class WC_Subscriptions_Order {
|
|||||||
* This may return 0 if there no non-subscription products in the cart, or otherwise it will be the sum of the
|
* This may return 0 if there no non-subscription products in the cart, or otherwise it will be the sum of the
|
||||||
* line totals for each non-subscription product.
|
* line totals for each non-subscription product.
|
||||||
*
|
*
|
||||||
* @param mixed $order A WC_Order object or the ID of the order which the subscription was purchased in.
|
* @param WC_Order|int $order A WC_Order object or the ID of the order which the subscription was purchased in.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.5.3
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.5.3
|
||||||
*/
|
*/
|
||||||
public static function get_non_subscription_total( $order ) {
|
public static function get_non_subscription_total( $order ) {
|
||||||
@@ -136,7 +136,7 @@ class WC_Subscriptions_Order {
|
|||||||
* @return float The initial sign-up fee charged when the subscription product in the order was first purchased, if any.
|
* @return float The initial sign-up fee charged when the subscription product in the order was first purchased, if any.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
||||||
*/
|
*/
|
||||||
public static function get_sign_up_fee( $order, $product_id = '' ) {
|
public static function get_sign_up_fee( $order, $product_id = 0 ) {
|
||||||
|
|
||||||
$sign_up_fee = 0;
|
$sign_up_fee = 0;
|
||||||
|
|
||||||
@@ -182,7 +182,7 @@ class WC_Subscriptions_Order {
|
|||||||
* @param int $product_id The product/post ID of a subscription product.
|
* @param int $product_id The product/post ID of a subscription product.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2.5
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2.5
|
||||||
*/
|
*/
|
||||||
public static function get_item_by_product_id( $order, $product_id = '' ) {
|
public static function get_item_by_product_id( $order, $product_id = 0 ) {
|
||||||
|
|
||||||
if ( ! is_object( $order ) ) {
|
if ( ! is_object( $order ) ) {
|
||||||
$order = wc_get_order( $order );
|
$order = wc_get_order( $order );
|
||||||
@@ -200,8 +200,7 @@ class WC_Subscriptions_Order {
|
|||||||
/**
|
/**
|
||||||
* Gets an item by a subscription key of the form created by @see WC_Subscriptions_Manager::get_subscription_key().
|
* Gets an item by a subscription key of the form created by @see WC_Subscriptions_Manager::get_subscription_key().
|
||||||
*
|
*
|
||||||
* @param WC_Order|int $order The WC_Order object or ID of the order for which the meta should be sought.
|
* @param string $subscription_key The subscription key.
|
||||||
* @param int $product_id The product/post ID of a subscription product.
|
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2.5
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2.5
|
||||||
*/
|
*/
|
||||||
public static function get_item_by_subscription_key( $subscription_key ) {
|
public static function get_item_by_subscription_key( $subscription_key ) {
|
||||||
@@ -217,8 +216,7 @@ class WC_Subscriptions_Order {
|
|||||||
* Gets the ID of a subscription item which belongs to a subscription key of the form created
|
* Gets the ID of a subscription item which belongs to a subscription key of the form created
|
||||||
* by @see WC_Subscriptions_Manager::get_subscription_key().
|
* by @see WC_Subscriptions_Manager::get_subscription_key().
|
||||||
*
|
*
|
||||||
* @param WC_Order|int $order The WC_Order object or ID of the order for which the meta should be sought.
|
* @param string $subscription_key The subscription key.
|
||||||
* @param int $product_id The product/post ID of a subscription product.
|
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.4
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.4
|
||||||
*/
|
*/
|
||||||
public static function get_item_id_by_subscription_key( $subscription_key ) {
|
public static function get_item_id_by_subscription_key( $subscription_key ) {
|
||||||
@@ -242,9 +240,7 @@ class WC_Subscriptions_Order {
|
|||||||
/**
|
/**
|
||||||
* Gets an individual order item by ID without requiring the order ID associated with it.
|
* Gets an individual order item by ID without requiring the order ID associated with it.
|
||||||
*
|
*
|
||||||
* @param WC_Order|int $order The WC_Order object or ID of the order for which the meta should be sought.
|
* @param int $order_item_id The product/post ID of a subscription. Option - if no product id is provided, the first item's meta will be returned
|
||||||
* @param int $item_id The product/post ID of a subscription. Option - if no product id is provided, the first item's meta will be returned
|
|
||||||
* @return array $item An array containing the order_item_id, order_item_name, order_item_type, order_id and any item_meta. Array structure matches that returned by WC_Order::get_items()
|
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2.5
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2.5
|
||||||
*/
|
*/
|
||||||
public static function get_item_by_id( $order_item_id ) {
|
public static function get_item_by_id( $order_item_id ) {
|
||||||
@@ -282,7 +278,7 @@ class WC_Subscriptions_Order {
|
|||||||
* @param mixed $default (optional) The default value to return if the meta key does not exist. Default 0.
|
* @param mixed $default (optional) The default value to return if the meta key does not exist. Default 0.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
*/
|
*/
|
||||||
public static function get_item_meta( $order, $meta_key, $product_id = '', $default = 0 ) {
|
public static function get_item_meta( $order, $meta_key, $product_id = 0, $default = 0 ) {
|
||||||
|
|
||||||
$meta_value = $default;
|
$meta_value = $default;
|
||||||
|
|
||||||
@@ -332,7 +328,7 @@ class WC_Subscriptions_Order {
|
|||||||
* @param int $product_id The product/post ID of a subscription. Option - if no product id is provided, it is expected that only one item exists and the last item's meta will be returned
|
* @param int $product_id The product/post ID of a subscription. Option - if no product id is provided, it is expected that only one item exists and the last item's meta will be returned
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
*/
|
*/
|
||||||
public static function get_item_name( $order, $product_id = '' ) {
|
public static function get_item_name( $order, $product_id = 0 ) {
|
||||||
|
|
||||||
$item = self::get_item_by_product_id( $order, $product_id );
|
$item = self::get_item_by_product_id( $order, $product_id );
|
||||||
|
|
||||||
@@ -412,7 +408,7 @@ class WC_Subscriptions_Order {
|
|||||||
* Output a hidden element on the Edit Order screen to provide information about whether the order displayed
|
* Output a hidden element on the Edit Order screen to provide information about whether the order displayed
|
||||||
* in that row contains a subscription or not.
|
* in that row contains a subscription or not.
|
||||||
*
|
*
|
||||||
* @param string $column The string of the current column.
|
* @param string $order_id The ID of the order.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.1
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.1
|
||||||
*/
|
*/
|
||||||
public static function contains_subscription_hidden_field( $order_id ) {
|
public static function contains_subscription_hidden_field( $order_id ) {
|
||||||
@@ -581,8 +577,10 @@ class WC_Subscriptions_Order {
|
|||||||
$subscription->payment_complete_for_order( $order );
|
$subscription->payment_complete_for_order( $order );
|
||||||
$was_activated = true;
|
$was_activated = true;
|
||||||
|
|
||||||
} elseif ( 'failed' == $new_order_status ) {
|
} elseif ( 'failed' === $new_order_status ) {
|
||||||
$subscription->payment_failed();
|
// When parent order fails, we want to keep the subscription status as pending unless it had another status before.
|
||||||
|
$new_status = $subscription->has_status( 'pending' ) && $subscription->get_parent_id() === $order->get_id() ? 'pending' : 'on-hold';
|
||||||
|
$subscription->payment_failed( $new_status );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -597,7 +595,7 @@ class WC_Subscriptions_Order {
|
|||||||
* Checks if a given order item matches a line item from a subscription purchased in the order.
|
* Checks if a given order item matches a line item from a subscription purchased in the order.
|
||||||
*
|
*
|
||||||
* @param WC_Order|int $order A WC_Order object or ID of a WC_Order order.
|
* @param WC_Order|int $order A WC_Order object or ID of a WC_Order order.
|
||||||
* @param array $item | int An array representing an order item or a product ID of an item in an order (not an order item ID)
|
* @param array $order_item An array representing an order item or a product ID of an item in an order (not an order item ID)
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
*/
|
*/
|
||||||
public static function is_item_subscription( $order, $order_item ) {
|
public static function is_item_subscription( $order, $order_item ) {
|
||||||
@@ -1041,7 +1039,7 @@ class WC_Subscriptions_Order {
|
|||||||
* @return null|object A subscription from the order, either with an item to the product ID (if any) or just the first subscription purchase in the order.
|
* @return null|object A subscription from the order, either with an item to the product ID (if any) or just the first subscription purchase in the order.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
private static function get_matching_subscription( $order, $product_id = '' ) {
|
private static function get_matching_subscription( $order, $product_id = 0 ) {
|
||||||
|
|
||||||
$subscriptions = wcs_get_subscriptions_for_order( $order, array( 'order_type' => 'parent' ) );
|
$subscriptions = wcs_get_subscriptions_for_order( $order, array( 'order_type' => 'parent' ) );
|
||||||
$matching_subscription = null;
|
$matching_subscription = null;
|
||||||
@@ -1079,7 +1077,7 @@ class WC_Subscriptions_Order {
|
|||||||
* @return array The line item for this product on the subscription object
|
* @return array The line item for this product on the subscription object
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
private static function get_matching_subscription_item( $order, $product_id = '' ) {
|
private static function get_matching_subscription_item( $order, $product_id = 0 ) {
|
||||||
|
|
||||||
$matching_item = array();
|
$matching_item = array();
|
||||||
$subscription = self::get_matching_subscription( $order, $product_id );
|
$subscription = self::get_matching_subscription( $order, $product_id );
|
||||||
@@ -1149,7 +1147,7 @@ class WC_Subscriptions_Order {
|
|||||||
/**
|
/**
|
||||||
* If the subscription is pending cancellation and a latest order is refunded, cancel the subscription.
|
* If the subscription is pending cancellation and a latest order is refunded, cancel the subscription.
|
||||||
*
|
*
|
||||||
* @param $order_id
|
* @param WC_Order $order The order object.
|
||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
@@ -1423,7 +1421,7 @@ class WC_Subscriptions_Order {
|
|||||||
* @param array $query_clauses The query clauses.
|
* @param array $query_clauses The query clauses.
|
||||||
* @param OrdersTableQuery $order_query The order query object.
|
* @param OrdersTableQuery $order_query The order query object.
|
||||||
*
|
*
|
||||||
* @return $query_clauses The modified query clauses to include/exclude parent orders.
|
* @return array The modified query clauses to include/exclude parent orders.
|
||||||
*/
|
*/
|
||||||
public static function filter_orders_query_by_parent_orders( $query_clauses, $order_query ) {
|
public static function filter_orders_query_by_parent_orders( $query_clauses, $order_query ) {
|
||||||
$include_parent_orders = $order_query->get( 'subscription_parent' );
|
$include_parent_orders = $order_query->get( 'subscription_parent' );
|
||||||
@@ -1491,7 +1489,8 @@ class WC_Subscriptions_Order {
|
|||||||
* Deprecated because editing a subscription's values is now done from the Edit Subscription screen and those values
|
* Deprecated because editing a subscription's values is now done from the Edit Subscription screen and those values
|
||||||
* are stored against a 'shop_subscription' post, not the 'shop_order' used to purchase the subscription.
|
* are stored against a 'shop_subscription' post, not the 'shop_order' used to purchase the subscription.
|
||||||
*
|
*
|
||||||
* @param item_id int An order_item_id as returned by the insert statement of @see woocommerce_add_order_item()
|
* @param WC_Order_Item $item
|
||||||
|
* @param int $item_id An order_item_id as returned by the insert statement of @see woocommerce_add_order_item()
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2.5
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2.5
|
||||||
* @version 1.0.0 - Migrated from WooCommerce Subscriptions v1.4
|
* @version 1.0.0 - Migrated from WooCommerce Subscriptions v1.4
|
||||||
* @return void
|
* @return void
|
||||||
@@ -1620,10 +1619,11 @@ class WC_Subscriptions_Order {
|
|||||||
* fee and price per period. This function should be used by payment gateways for the initial payment.
|
* fee and price per period. This function should be used by payment gateways for the initial payment.
|
||||||
*
|
*
|
||||||
* @param mixed $order A WC_Order object or the ID of the order which the subscription was purchased in.
|
* @param mixed $order A WC_Order object or the ID of the order which the subscription was purchased in.
|
||||||
|
* @param int $product_id The ID of the product.
|
||||||
* @return float The total initial amount charged when the subscription product in the order was first purchased, if any.
|
* @return float The total initial amount charged when the subscription product in the order was first purchased, if any.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.1
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.1
|
||||||
*/
|
*/
|
||||||
public static function get_total_initial_payment( $order, $product_id = '' ) {
|
public static function get_total_initial_payment( $order, $product_id = 0 ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'WC_Order::get_total()' );
|
_deprecated_function( __METHOD__, '2.0', 'WC_Order::get_total()' );
|
||||||
|
|
||||||
if ( ! is_object( $order ) ) {
|
if ( ! is_object( $order ) ) {
|
||||||
@@ -1659,9 +1659,10 @@ class WC_Subscriptions_Order {
|
|||||||
* Returns the proportion of cart discount that is recurring for the product specified with $product_id
|
* Returns the proportion of cart discount that is recurring for the product specified with $product_id
|
||||||
*
|
*
|
||||||
* @param WC_Order|int $order A WC_Order object or ID of a WC_Order order.
|
* @param WC_Order|int $order A WC_Order object or ID of a WC_Order order.
|
||||||
|
* @param int $product_id The ID of the product.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
*/
|
*/
|
||||||
public static function get_recurring_discount_cart( $order, $product_id = '' ) {
|
public static function get_recurring_discount_cart( $order, $product_id = 0 ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'the value for the subscription object rather than the value on the original order. The value is stored against the subscription since Subscriptions v2.0 as an order can be used to create multiple different subscriptions with different discounts, so use the subscription object' );
|
_deprecated_function( __METHOD__, '2.0', 'the value for the subscription object rather than the value on the original order. The value is stored against the subscription since Subscriptions v2.0 as an order can be used to create multiple different subscriptions with different discounts, so use the subscription object' );
|
||||||
|
|
||||||
$recurring_discount_cart = 0;
|
$recurring_discount_cart = 0;
|
||||||
@@ -1689,9 +1690,10 @@ class WC_Subscriptions_Order {
|
|||||||
* Returns the proportion of cart discount tax that is recurring for the product specified with $product_id
|
* Returns the proportion of cart discount tax that is recurring for the product specified with $product_id
|
||||||
*
|
*
|
||||||
* @param WC_Order|int $order A WC_Order object or ID of a WC_Order order.
|
* @param WC_Order|int $order A WC_Order object or ID of a WC_Order order.
|
||||||
|
* @param int $product_id The ID of the product.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
*/
|
*/
|
||||||
public static function get_recurring_discount_cart_tax( $order, $product_id = '' ) {
|
public static function get_recurring_discount_cart_tax( $order, $product_id = 0 ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'the value for the subscription object rather than the value on the original order. The value is stored against the subscription since Subscriptions v2.0 as an order can be used to create multiple different subscriptions with different discounts, so use the subscription object' );
|
_deprecated_function( __METHOD__, '2.0', 'the value for the subscription object rather than the value on the original order. The value is stored against the subscription since Subscriptions v2.0 as an order can be used to create multiple different subscriptions with different discounts, so use the subscription object' );
|
||||||
|
|
||||||
$recurring_discount_cart_tax = 0;
|
$recurring_discount_cart_tax = 0;
|
||||||
@@ -1719,9 +1721,10 @@ class WC_Subscriptions_Order {
|
|||||||
* Returns the proportion of total discount that is recurring for the product specified with $product_id
|
* Returns the proportion of total discount that is recurring for the product specified with $product_id
|
||||||
*
|
*
|
||||||
* @param WC_Order|int $order A WC_Order object or ID of a WC_Order order.
|
* @param WC_Order|int $order A WC_Order object or ID of a WC_Order order.
|
||||||
|
* @param int $product_id The ID of the product.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
*/
|
*/
|
||||||
public static function get_recurring_discount_total( $order, $product_id = '' ) {
|
public static function get_recurring_discount_total( $order, $product_id = 0 ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'the value for the subscription object rather than the value on the original order. The value is stored against the subscription since Subscriptions v2.0 as an order can be used to create multiple different subscriptions with different discounts, so use the subscription object' );
|
_deprecated_function( __METHOD__, '2.0', 'the value for the subscription object rather than the value on the original order. The value is stored against the subscription since Subscriptions v2.0 as an order can be used to create multiple different subscriptions with different discounts, so use the subscription object' );
|
||||||
|
|
||||||
$ex_tax = ( 'excl' === get_option( 'woocommerce_tax_display_cart' ) && wcs_get_objects_property( $order, 'display_totals_ex_tax' ) );
|
$ex_tax = ( 'excl' === get_option( 'woocommerce_tax_display_cart' ) && wcs_get_objects_property( $order, 'display_totals_ex_tax' ) );
|
||||||
@@ -1765,9 +1768,10 @@ class WC_Subscriptions_Order {
|
|||||||
* this is equal to @see WC_Order::get_total_tax()
|
* this is equal to @see WC_Order::get_total_tax()
|
||||||
*
|
*
|
||||||
* @param WC_Order|int $order A WC_Order object or ID of a WC_Order order.
|
* @param WC_Order|int $order A WC_Order object or ID of a WC_Order order.
|
||||||
|
* @param int $product_id The ID of the product.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
*/
|
*/
|
||||||
public static function get_recurring_shipping_tax_total( $order, $product_id = '' ) {
|
public static function get_recurring_shipping_tax_total( $order, $product_id = 0 ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'the value for the subscription object rather than the value on the original order. The value is stored against the subscription since Subscriptions v2.0 as an order can be used to create multiple different subscriptions with different amounts, so use the subscription object' );
|
_deprecated_function( __METHOD__, '2.0', 'the value for the subscription object rather than the value on the original order. The value is stored against the subscription since Subscriptions v2.0 as an order can be used to create multiple different subscriptions with different amounts, so use the subscription object' );
|
||||||
|
|
||||||
$recurring_shipping_tax_total = 0;
|
$recurring_shipping_tax_total = 0;
|
||||||
@@ -1797,9 +1801,10 @@ class WC_Subscriptions_Order {
|
|||||||
* equal to @see WC_Order::get_total_shipping()
|
* equal to @see WC_Order::get_total_shipping()
|
||||||
*
|
*
|
||||||
* @param WC_Order|int $order A WC_Order object or ID of a WC_Order order.
|
* @param WC_Order|int $order A WC_Order object or ID of a WC_Order order.
|
||||||
|
* @param int $product_id The ID of the product.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
*/
|
*/
|
||||||
public static function get_recurring_shipping_total( $order, $product_id = '' ) {
|
public static function get_recurring_shipping_total( $order, $product_id = 0 ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'the value for the subscription object rather than the value on the original order. The value is stored against the subscription since Subscriptions v2.0 as an order can be used to create multiple different subscriptions with different amounts, so use the subscription object' );
|
_deprecated_function( __METHOD__, '2.0', 'the value for the subscription object rather than the value on the original order. The value is stored against the subscription since Subscriptions v2.0 as an order can be used to create multiple different subscriptions with different amounts, so use the subscription object' );
|
||||||
|
|
||||||
$recurring_shipping_total = 0;
|
$recurring_shipping_total = 0;
|
||||||
@@ -1862,9 +1867,10 @@ class WC_Subscriptions_Order {
|
|||||||
* Returns the proportion of total tax on an order that is recurring for the product specified with $product_id
|
* Returns the proportion of total tax on an order that is recurring for the product specified with $product_id
|
||||||
*
|
*
|
||||||
* @param WC_Order|int $order A WC_Order object or ID of a WC_Order order.
|
* @param WC_Order|int $order A WC_Order object or ID of a WC_Order order.
|
||||||
|
* @param int $product_id The ID of the product.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
*/
|
*/
|
||||||
public static function get_recurring_total_tax( $order, $product_id = '' ) {
|
public static function get_recurring_total_tax( $order, $product_id = 0 ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'the value for the subscription object rather than the value on the original order. The value is stored against the subscription since Subscriptions v2.0 as an order can be used to create multiple different subscriptions with different amounts, so use the subscription object' );
|
_deprecated_function( __METHOD__, '2.0', 'the value for the subscription object rather than the value on the original order. The value is stored against the subscription since Subscriptions v2.0 as an order can be used to create multiple different subscriptions with different amounts, so use the subscription object' );
|
||||||
|
|
||||||
$recurring_total_tax = 0;
|
$recurring_total_tax = 0;
|
||||||
@@ -1892,9 +1898,10 @@ class WC_Subscriptions_Order {
|
|||||||
* Returns the proportion of total before tax on an order that is recurring for the product specified with $product_id
|
* Returns the proportion of total before tax on an order that is recurring for the product specified with $product_id
|
||||||
*
|
*
|
||||||
* @param WC_Order|int $order A WC_Order object or ID of a WC_Order order.
|
* @param WC_Order|int $order A WC_Order object or ID of a WC_Order order.
|
||||||
|
* @param int $product_id The ID of the product.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
*/
|
*/
|
||||||
public static function get_recurring_total_ex_tax( $order, $product_id = '' ) {
|
public static function get_recurring_total_ex_tax( $order, $product_id = 0 ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'the value for the subscription object rather than the value on the original order. The value is stored against the subscription since Subscriptions v2.0 as an order can be used to create multiple different subscriptions with different amounts, so use the subscription object' );
|
_deprecated_function( __METHOD__, '2.0', 'the value for the subscription object rather than the value on the original order. The value is stored against the subscription since Subscriptions v2.0 as an order can be used to create multiple different subscriptions with different amounts, so use the subscription object' );
|
||||||
return self::get_recurring_total( $order, $product_id ) - self::get_recurring_total_tax( $order, $product_id );
|
return self::get_recurring_total( $order, $product_id ) - self::get_recurring_total_tax( $order, $product_id );
|
||||||
}
|
}
|
||||||
@@ -1903,10 +1910,10 @@ class WC_Subscriptions_Order {
|
|||||||
* Returns the price per period for a subscription in an order.
|
* Returns the price per period for a subscription in an order.
|
||||||
*
|
*
|
||||||
* @param mixed $order A WC_Order object or the ID of the order which the subscription was purchased in.
|
* @param mixed $order A WC_Order object or the ID of the order which the subscription was purchased in.
|
||||||
* @param int $product_id (optional) The post ID of the subscription WC_Product object purchased in the order. Defaults to the ID of the first product purchased in the order.
|
* @param int $product_id The ID of the product.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
*/
|
*/
|
||||||
public static function get_recurring_total( $order ) {
|
public static function get_recurring_total( $order, $product_id = 0 ) {
|
||||||
$recurring_total = 0;
|
$recurring_total = 0;
|
||||||
|
|
||||||
foreach ( wcs_get_subscriptions_for_order( $order, array( 'order_type' => 'parent' ) ) as $subscription ) {
|
foreach ( wcs_get_subscriptions_for_order( $order, array( 'order_type' => 'parent' ) ) as $subscription ) {
|
||||||
@@ -1932,8 +1939,8 @@ class WC_Subscriptions_Order {
|
|||||||
* Creates a string representation of the subscription period/term for each item in the cart
|
* Creates a string representation of the subscription period/term for each item in the cart
|
||||||
*
|
*
|
||||||
* @param WC_Order $order A WC_Order object.
|
* @param WC_Order $order A WC_Order object.
|
||||||
* @param mixed $deprecated Never used.
|
* @param mixed $deprecated_price Never used.
|
||||||
* @param mixed $deprecated Never used.
|
* @param mixed $deprecated_sign_up_fee Never used.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
||||||
*/
|
*/
|
||||||
public static function get_order_subscription_string( $order, $deprecated_price = '', $deprecated_sign_up_fee = '' ) {
|
public static function get_order_subscription_string( $order, $deprecated_price = '', $deprecated_sign_up_fee = '' ) {
|
||||||
@@ -1996,7 +2003,7 @@ class WC_Subscriptions_Order {
|
|||||||
* @return string A string representation of the period for the subscription, i.e. day, week, month or year.
|
* @return string A string representation of the period for the subscription, i.e. day, week, month or year.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
||||||
*/
|
*/
|
||||||
public static function get_subscription_period( $order, $product_id = '' ) {
|
public static function get_subscription_period( $order, $product_id = 0 ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'the billing period for each individual subscription object. Since Subscriptions v2.0, an order can be used to create multiple different subscriptions with different billing schedules, so use the subscription object' );
|
_deprecated_function( __METHOD__, '2.0', 'the billing period for each individual subscription object. Since Subscriptions v2.0, an order can be used to create multiple different subscriptions with different billing schedules, so use the subscription object' );
|
||||||
|
|
||||||
$billing_period = '';
|
$billing_period = '';
|
||||||
@@ -2031,7 +2038,7 @@ class WC_Subscriptions_Order {
|
|||||||
* @return int The billing interval for a each subscription product in an order.
|
* @return int The billing interval for a each subscription product in an order.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
||||||
*/
|
*/
|
||||||
public static function get_subscription_interval( $order, $product_id = '' ) {
|
public static function get_subscription_interval( $order, $product_id = 0 ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'the billing interval for each individual subscription object. Since Subscriptions v2.0, an order can be used to create multiple different subscriptions with different billing schedules, so use the subscription object' );
|
_deprecated_function( __METHOD__, '2.0', 'the billing interval for each individual subscription object. Since Subscriptions v2.0, an order can be used to create multiple different subscriptions with different billing schedules, so use the subscription object' );
|
||||||
|
|
||||||
$billing_interval = '';
|
$billing_interval = '';
|
||||||
@@ -2066,7 +2073,7 @@ class WC_Subscriptions_Order {
|
|||||||
* @return int The number of periods for which the subscription will recur. For example, a $5/month subscription for one year would return 12. A $10 every 3 month subscription for one year would also return 12.
|
* @return int The number of periods for which the subscription will recur. For example, a $5/month subscription for one year would return 12. A $10 every 3 month subscription for one year would also return 12.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
||||||
*/
|
*/
|
||||||
public static function get_subscription_length( $order, $product_id = '' ) {
|
public static function get_subscription_length( $order, $product_id = 0 ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'the end date each individual subscription object. Since Subscriptions v2.0, an order can be used to create multiple different subscriptions with different billing schedules. The length of a subscription is also no longer stored against the subscription and instead, it is used simply to calculate the end date for the subscription when it is purchased. Therefore, you must use the end date of a subscription object' );
|
_deprecated_function( __METHOD__, '2.0', 'the end date each individual subscription object. Since Subscriptions v2.0, an order can be used to create multiple different subscriptions with different billing schedules. The length of a subscription is also no longer stored against the subscription and instead, it is used simply to calculate the end date for the subscription when it is purchased. Therefore, you must use the end date of a subscription object' );
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -2083,7 +2090,7 @@ class WC_Subscriptions_Order {
|
|||||||
* @return int The number of periods the trial period lasts for. For no trial, this will return 0, for a 3 period trial, it will return 3.
|
* @return int The number of periods the trial period lasts for. For no trial, this will return 0, for a 3 period trial, it will return 3.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.1
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.1
|
||||||
*/
|
*/
|
||||||
public static function get_subscription_trial_length( $order, $product_id = '' ) {
|
public static function get_subscription_trial_length( $order, $product_id = 0 ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'the first payment date for each individual subscription object. Since Subscriptions v2.0, an order can be used to create multiple different subscriptions with different billing schedules. The trial length of a subscription is also no longer stored against the subscription and instead, it is used simply to calculate the first payment date for the subscription when it is purchased. Therefore, you must use the first payment date of a subscription object' );
|
_deprecated_function( __METHOD__, '2.0', 'the first payment date for each individual subscription object. Since Subscriptions v2.0, an order can be used to create multiple different subscriptions with different billing schedules. The trial length of a subscription is also no longer stored against the subscription and instead, it is used simply to calculate the first payment date for the subscription when it is purchased. Therefore, you must use the first payment date of a subscription object' );
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -2100,7 +2107,7 @@ class WC_Subscriptions_Order {
|
|||||||
* @return string A string representation of the period for the subscription, i.e. day, week, month or year.
|
* @return string A string representation of the period for the subscription, i.e. day, week, month or year.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
*/
|
*/
|
||||||
public static function get_subscription_trial_period( $order, $product_id = '' ) {
|
public static function get_subscription_trial_period( $order, $product_id = 0 ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'the billing period for each individual subscription object. Since Subscriptions v2.0, an order can be used to create multiple different subscriptions with different billing schedules. The trial period of a subscription is also no longer stored against the subscription and instead, it is used simply to calculate the first payment date for the subscription when it is purchased. Therefore, you must use the billing period of a subscription object' );
|
_deprecated_function( __METHOD__, '2.0', 'the billing period for each individual subscription object. Since Subscriptions v2.0, an order can be used to create multiple different subscriptions with different billing schedules. The trial period of a subscription is also no longer stored against the subscription and instead, it is used simply to calculate the first payment date for the subscription when it is purchased. Therefore, you must use the billing period of a subscription object' );
|
||||||
return self::get_subscription_period( $order, $product_id );
|
return self::get_subscription_period( $order, $product_id );
|
||||||
}
|
}
|
||||||
@@ -2162,10 +2169,9 @@ class WC_Subscriptions_Order {
|
|||||||
*
|
*
|
||||||
* A convenience wrapper for @see WC_Subscriptions_Manager::get_last_payment_date() to get the next
|
* A convenience wrapper for @see WC_Subscriptions_Manager::get_last_payment_date() to get the next
|
||||||
* payment date for a subscription when all you have is the order and product.
|
* payment date for a subscription when all you have is the order and product.
|
||||||
*
|
f *
|
||||||
* @param mixed $order A WC_Order object or the ID of the order which the subscription was purchased in.
|
* @param mixed $order A WC_Order object or the ID of the order which the subscription was purchased in.
|
||||||
* @param int $product_id The product/post ID of the subscription
|
* @param int $product_id The product/post ID of the subscription
|
||||||
* @param mixed $deprecated Never used.
|
|
||||||
* @return mixed If no more payments are due, returns 0, otherwise it returns the MySQL formatted date/time string for the next payment date.
|
* @return mixed If no more payments are due, returns 0, otherwise it returns the MySQL formatted date/time string for the next payment date.
|
||||||
* @version 1.0.0 - Migrated from WooCommerce Subscriptions v1.2.1
|
* @version 1.0.0 - Migrated from WooCommerce Subscriptions v1.2.1
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
||||||
@@ -2224,7 +2230,7 @@ class WC_Subscriptions_Order {
|
|||||||
* Returns the number of failed payments for a given subscription.
|
* Returns the number of failed payments for a given subscription.
|
||||||
*
|
*
|
||||||
* @param WC_Order $order The WC_Order object of the order for which you want to determine the number of failed payments.
|
* @param WC_Order $order The WC_Order object of the order for which you want to determine the number of failed payments.
|
||||||
* @param product_id int The ID of the subscription product.
|
* @param int $product_id The ID of the subscription product.
|
||||||
* @return string The key representing the given subscription.
|
* @return string The key representing the given subscription.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
||||||
*/
|
*/
|
||||||
@@ -2247,7 +2253,7 @@ class WC_Subscriptions_Order {
|
|||||||
* than one subscription.
|
* than one subscription.
|
||||||
*
|
*
|
||||||
* @param WC_Order $order The WC_Order object of the order for which you want to determine the number of failed payments.
|
* @param WC_Order $order The WC_Order object of the order for which you want to determine the number of failed payments.
|
||||||
* @param product_id int The ID of the subscription product.
|
* @param int $product_id The ID of the subscription product.
|
||||||
* @return string The key representing the given subscription.
|
* @return string The key representing the given subscription.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.0
|
||||||
*/
|
*/
|
||||||
@@ -2264,8 +2270,7 @@ class WC_Subscriptions_Order {
|
|||||||
/**
|
/**
|
||||||
* Once payment is completed on an order, set a lock on payments until the next subscription payment period.
|
* Once payment is completed on an order, set a lock on payments until the next subscription payment period.
|
||||||
*
|
*
|
||||||
* @param int $user_id The id of the user who purchased the subscription
|
* @param int $order_id The id of the order.
|
||||||
* @param string $subscription_key A subscription key of the form created by @see WC_Subscriptions_Manager::get_subscription_key()
|
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.1.2
|
||||||
*/
|
*/
|
||||||
public static function safeguard_scheduled_payments( $order_id ) {
|
public static function safeguard_scheduled_payments( $order_id ) {
|
||||||
@@ -2370,7 +2375,7 @@ class WC_Subscriptions_Order {
|
|||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
public static function get_item_sign_up_fee( $order, $product_id = '' ) {
|
public static function get_item_sign_up_fee( $order, $product_id = 0 ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::get_items_sign_up_fee() or WC_Subscriptions_Order::get_sign_up_fee()' );
|
_deprecated_function( __METHOD__, '2.0', 'WC_Subscription::get_items_sign_up_fee() or WC_Subscriptions_Order::get_sign_up_fee()' );
|
||||||
return self::get_sign_up_fee( $order, $product_id );
|
return self::get_sign_up_fee( $order, $product_id );
|
||||||
}
|
}
|
||||||
@@ -2446,6 +2451,7 @@ class WC_Subscriptions_Order {
|
|||||||
|
|
||||||
if ( isset( $order->$meta_key ) ) { // WC 2.1+ magic __isset() & __get() methods
|
if ( isset( $order->$meta_key ) ) { // WC 2.1+ magic __isset() & __get() methods
|
||||||
$meta_value = $order->$meta_key;
|
$meta_value = $order->$meta_key;
|
||||||
|
// @phpstan-ignore-next-line
|
||||||
} elseif ( is_array( $order->order_custom_fields ) && isset( $order->order_custom_fields[ '_' . $meta_key ][0] ) && $order->order_custom_fields[ '_' . $meta_key ][0] ) { // < WC 2.1+
|
} elseif ( is_array( $order->order_custom_fields ) && isset( $order->order_custom_fields[ '_' . $meta_key ][0] ) && $order->order_custom_fields[ '_' . $meta_key ][0] ) { // < WC 2.1+
|
||||||
$meta_value = maybe_unserialize( $order->order_custom_fields[ '_' . $meta_key ][0] );
|
$meta_value = maybe_unserialize( $order->order_custom_fields[ '_' . $meta_key ][0] );
|
||||||
} else {
|
} else {
|
||||||
@@ -2504,9 +2510,6 @@ class WC_Subscriptions_Order {
|
|||||||
|
|
||||||
foreach ( $subscription_ids as $subscription_id ) {
|
foreach ( $subscription_ids as $subscription_id ) {
|
||||||
$subscription = wcs_get_subscription( $subscription_id );
|
$subscription = wcs_get_subscription( $subscription_id );
|
||||||
if ( ! $subscription ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
self::update_subscription_last_order_date_created( $subscription, $exclude_statuses );
|
self::update_subscription_last_order_date_created( $subscription, $exclude_statuses );
|
||||||
}
|
}
|
||||||
@@ -2527,9 +2530,6 @@ class WC_Subscriptions_Order {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$subscription = wcs_get_subscription( $object_id );
|
$subscription = wcs_get_subscription( $object_id );
|
||||||
if ( ! $subscription ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
self::update_subscription_last_order_date_created( $subscription );
|
self::update_subscription_last_order_date_created( $subscription );
|
||||||
}
|
}
|
||||||
@@ -2541,8 +2541,17 @@ class WC_Subscriptions_Order {
|
|||||||
* @param array $exclude_statuses The order statuses to exclude.
|
* @param array $exclude_statuses The order statuses to exclude.
|
||||||
*/
|
*/
|
||||||
private static function update_subscription_last_order_date_created( $subscription, $exclude_statuses = [] ) {
|
private static function update_subscription_last_order_date_created( $subscription, $exclude_statuses = [] ) {
|
||||||
|
if ( ! $subscription ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$last_order_date_created = $subscription->get_time( 'last_order_date_created', 'gmt', $exclude_statuses );
|
$last_order_date_created = $subscription->get_time( 'last_order_date_created', 'gmt', $exclude_statuses );
|
||||||
|
|
||||||
|
// If the last order date created hasn't changed, no need to update and save.
|
||||||
|
if ( $last_order_date_created === (int) $subscription->get_last_order_date_created() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$subscription->set_last_order_date_created( $last_order_date_created );
|
$subscription->set_last_order_date_created( $last_order_date_created );
|
||||||
$subscription->save();
|
$subscription->save();
|
||||||
}
|
}
|
||||||
|
@@ -61,8 +61,8 @@ class WC_Subscriptions_Product {
|
|||||||
add_action( 'wp_scheduled_delete', __CLASS__ . '::prevent_scheduled_deletion', 9 );
|
add_action( 'wp_scheduled_delete', __CLASS__ . '::prevent_scheduled_deletion', 9 );
|
||||||
|
|
||||||
// Trash variations instead of deleting them to prevent headaches from deleted products
|
// Trash variations instead of deleting them to prevent headaches from deleted products
|
||||||
add_action( 'wp_ajax_woocommerce_remove_variation', __CLASS__ . '::remove_variations', 9, 2 );
|
add_action( 'wp_ajax_woocommerce_remove_variation', __CLASS__ . '::remove_variations', 9 );
|
||||||
add_action( 'wp_ajax_woocommerce_remove_variations', __CLASS__ . '::remove_variations', 9, 2 );
|
add_action( 'wp_ajax_woocommerce_remove_variations', __CLASS__ . '::remove_variations', 9 );
|
||||||
|
|
||||||
// Handle bulk edits to subscription data in WC 2.4
|
// Handle bulk edits to subscription data in WC 2.4
|
||||||
add_action( 'woocommerce_bulk_edit_variations', __CLASS__ . '::bulk_edit_variations', 10, 4 );
|
add_action( 'woocommerce_bulk_edit_variations', __CLASS__ . '::bulk_edit_variations', 10, 4 );
|
||||||
@@ -202,7 +202,7 @@ class WC_Subscriptions_Product {
|
|||||||
* For example "$20 per Month for 3 Months with a $10 sign-up fee".
|
* For example "$20 per Month for 3 Months with a $10 sign-up fee".
|
||||||
*
|
*
|
||||||
* @param WC_Product|int $product A WC_Product object or ID of a WC_Product.
|
* @param WC_Product|int $product A WC_Product object or ID of a WC_Product.
|
||||||
* @param array $inclusions An associative array of flags to indicate how to calculate the price and what to include, values:
|
* @param array $include An associative array of flags to indicate how to calculate the price and what to include, values:
|
||||||
* 'tax_calculation' => false to ignore tax, 'include_tax' or 'exclude_tax' To indicate that tax should be added or excluded respectively
|
* 'tax_calculation' => false to ignore tax, 'include_tax' or 'exclude_tax' To indicate that tax should be added or excluded respectively
|
||||||
* 'subscription_length' => true to include subscription's length (default) or false to exclude it
|
* 'subscription_length' => true to include subscription's length (default) or false to exclude it
|
||||||
* 'sign_up_fee' => true to include subscription's sign up fee (default) or false to exclude it
|
* 'sign_up_fee' => true to include subscription's sign up fee (default) or false to exclude it
|
||||||
@@ -537,7 +537,6 @@ class WC_Subscriptions_Product {
|
|||||||
*
|
*
|
||||||
* @param int|WC_Product $product The product instance or product/post ID of a subscription product.
|
* @param int|WC_Product $product The product instance or product/post ID of a subscription product.
|
||||||
* @param mixed $from_date A MySQL formatted date/time string from which to calculate the expiration date, or empty (default), which will use today's date/time.
|
* @param mixed $from_date A MySQL formatted date/time string from which to calculate the expiration date, or empty (default), which will use today's date/time.
|
||||||
* @param string $type The return format for the date, either 'mysql', or 'timezone'. Default 'mysql'.
|
|
||||||
* @param string $timezone The timezone for the returned date, either 'site' for the site's timezone, or 'gmt'. Default, 'site'.
|
* @param string $timezone The timezone for the returned date, either 'site' for the site's timezone, or 'gmt'. Default, 'site'.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
@@ -560,7 +559,6 @@ class WC_Subscriptions_Product {
|
|||||||
*
|
*
|
||||||
* @param int|WC_Product $product The product instance or product/post ID of a subscription product.
|
* @param int|WC_Product $product The product instance or product/post ID of a subscription product.
|
||||||
* @param mixed $from_date A MySQL formatted date/time string from which to calculate the expiration date, or empty (default), which will use today's date/time.
|
* @param mixed $from_date A MySQL formatted date/time string from which to calculate the expiration date, or empty (default), which will use today's date/time.
|
||||||
* @param string $type The return format for the date, either 'mysql', or 'timezone'. Default 'mysql'.
|
|
||||||
* @param string $timezone The timezone for the returned date, either 'site' for the site's timezone, or 'gmt'. Default, 'site'.
|
* @param string $timezone The timezone for the returned date, either 'site' for the site's timezone, or 'gmt'. Default, 'site'.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
@@ -816,14 +814,14 @@ class WC_Subscriptions_Product {
|
|||||||
public static function prevent_scheduled_deletion() {
|
public static function prevent_scheduled_deletion() {
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
|
|
||||||
$query = "UPDATE $wpdb->postmeta
|
$wpdb->query(
|
||||||
INNER JOIN $wpdb->posts ON $wpdb->postmeta.post_id = $wpdb->posts.ID
|
"UPDATE $wpdb->postmeta
|
||||||
SET $wpdb->postmeta.meta_key = '_wc_trash_meta_time'
|
INNER JOIN $wpdb->posts ON $wpdb->postmeta.post_id = $wpdb->posts.ID
|
||||||
WHERE $wpdb->postmeta.meta_key = '_wp_trash_meta_time'
|
SET $wpdb->postmeta.meta_key = '_wc_trash_meta_time'
|
||||||
AND $wpdb->posts.post_type IN ( 'product', 'product_variation')
|
WHERE $wpdb->postmeta.meta_key = '_wp_trash_meta_time'
|
||||||
AND $wpdb->posts.post_status = 'trash'";
|
AND $wpdb->posts.post_type IN ( 'product', 'product_variation')
|
||||||
|
AND $wpdb->posts.post_status = 'trash'"
|
||||||
$wpdb->query( $query );
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -842,12 +840,12 @@ class WC_Subscriptions_Product {
|
|||||||
if ( isset( $_POST['variation_id'] ) ) { // removing single variation
|
if ( isset( $_POST['variation_id'] ) ) { // removing single variation
|
||||||
|
|
||||||
check_ajax_referer( 'delete-variation', 'security' );
|
check_ajax_referer( 'delete-variation', 'security' );
|
||||||
$variation_ids = array( $_POST['variation_id'] );
|
$variation_ids = array( wc_clean( wp_unslash( $_POST['variation_id'] ) ) );
|
||||||
|
|
||||||
} else { // removing multiple variations
|
} else { // removing multiple variations
|
||||||
|
|
||||||
check_ajax_referer( 'delete-variations', 'security' );
|
check_ajax_referer( 'delete-variations', 'security' );
|
||||||
$variation_ids = (array) $_POST['variation_ids'];
|
$variation_ids = (array) wc_clean( wp_unslash( $_POST['variation_ids'] ) );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -910,7 +908,7 @@ class WC_Subscriptions_Product {
|
|||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// Since 2.5 we have the product type information available so we don't have to wait for the product to be saved to check if it is a subscription
|
// Since 2.5 we have the product type information available so we don't have to wait for the product to be saved to check if it is a subscription
|
||||||
if ( empty( $_POST['security'] ) || ! wp_verify_nonce( $_POST['security'], 'bulk-edit-variations' ) || 'variable-subscription' !== $_POST['product_type'] ) {
|
if ( empty( $_POST['security'] ) || ! wp_verify_nonce( wc_clean( wp_unslash( $_POST['security'] ) ), 'bulk-edit-variations' ) || 'variable-subscription' !== $_POST['product_type'] ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -936,8 +934,10 @@ class WC_Subscriptions_Product {
|
|||||||
|
|
||||||
if ( '%' === substr( $value, -1 ) ) {
|
if ( '%' === substr( $value, -1 ) ) {
|
||||||
$percent = wc_format_decimal( substr( $value, 0, -1 ) );
|
$percent = wc_format_decimal( substr( $value, 0, -1 ) );
|
||||||
|
// @phpstan-ignore binaryOp.invalid
|
||||||
$subscription_price += ( ( $subscription_price / 100 ) * $percent ) * "{$operator}1";
|
$subscription_price += ( ( $subscription_price / 100 ) * $percent ) * "{$operator}1";
|
||||||
} else {
|
} else {
|
||||||
|
// @phpstan-ignore binaryOp.invalid
|
||||||
$subscription_price += $value * "{$operator}1";
|
$subscription_price += $value * "{$operator}1";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -987,7 +987,7 @@ class WC_Subscriptions_Product {
|
|||||||
|
|
||||||
check_admin_referer( 'one_time_shipping', 'nonce' );
|
check_admin_referer( 'one_time_shipping', 'nonce' );
|
||||||
|
|
||||||
$product = wc_get_product( $_POST['product_id'] );
|
$product = wc_get_product( wc_clean( wp_unslash( $_POST['product_id'] ) ) );
|
||||||
$is_synced_or_has_trial = false;
|
$is_synced_or_has_trial = false;
|
||||||
|
|
||||||
if ( WC_Subscriptions_Product::is_subscription( $product ) ) {
|
if ( WC_Subscriptions_Product::is_subscription( $product ) ) {
|
||||||
@@ -1028,15 +1028,15 @@ class WC_Subscriptions_Product {
|
|||||||
|
|
||||||
check_admin_referer( 'one_time_shipping', 'nonce' );
|
check_admin_referer( 'one_time_shipping', 'nonce' );
|
||||||
|
|
||||||
$one_time_shipping_enabled = $_POST['one_time_shipping_enabled'];
|
$one_time_shipping_enabled = wc_clean( wp_unslash( $_POST['one_time_shipping_enabled'] ) );
|
||||||
$one_time_shipping_selected = $_POST['one_time_shipping_selected'];
|
$one_time_shipping_selected = wc_clean( wp_unslash( $_POST['one_time_shipping_selected'] ) );
|
||||||
$subscription_one_time_shipping = 'no';
|
$subscription_one_time_shipping = 'no';
|
||||||
|
|
||||||
if ( 'false' !== $one_time_shipping_enabled && 'true' === $one_time_shipping_selected ) {
|
if ( 'false' !== $one_time_shipping_enabled && 'true' === $one_time_shipping_selected ) {
|
||||||
$subscription_one_time_shipping = 'yes';
|
$subscription_one_time_shipping = 'yes';
|
||||||
}
|
}
|
||||||
|
|
||||||
update_post_meta( $_POST['product_id'], '_subscription_one_time_shipping', $subscription_one_time_shipping );
|
update_post_meta( wc_clean( wp_unslash( $_POST['product_id'] ) ), '_subscription_one_time_shipping', $subscription_one_time_shipping );
|
||||||
|
|
||||||
wp_send_json( array( 'one_time_shipping' => $subscription_one_time_shipping ) );
|
wp_send_json( array( 'one_time_shipping' => $subscription_one_time_shipping ) );
|
||||||
}
|
}
|
||||||
@@ -1148,7 +1148,7 @@ class WC_Subscriptions_Product {
|
|||||||
/**
|
/**
|
||||||
* Get an array of parent IDs from a potential child product, used to determine if a product belongs to a group.
|
* Get an array of parent IDs from a potential child product, used to determine if a product belongs to a group.
|
||||||
*
|
*
|
||||||
* @param WC_Product The product object to get parents from.
|
* @param WC_Product $product The product object to get parents from.
|
||||||
* @return array Parent IDs
|
* @return array Parent IDs
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.4
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.4
|
||||||
*/
|
*/
|
||||||
@@ -1159,12 +1159,13 @@ class WC_Subscriptions_Product {
|
|||||||
if ( wcs_is_woocommerce_pre( '3.0' ) && isset( $product->post->post_parent ) ) {
|
if ( wcs_is_woocommerce_pre( '3.0' ) && isset( $product->post->post_parent ) ) {
|
||||||
$parent_product_ids[] = $product->get_parent();
|
$parent_product_ids[] = $product->get_parent();
|
||||||
} else {
|
} else {
|
||||||
$parent_product_ids = $wpdb->get_col( $wpdb->prepare(
|
$parent_product_ids = $wpdb->get_col(
|
||||||
"SELECT post_id
|
$wpdb->prepare(
|
||||||
FROM {$wpdb->prefix}postmeta
|
// phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.LikeWildcardsInQuery
|
||||||
WHERE meta_key = '_children' AND meta_value LIKE '%%i:%d;%%'",
|
"SELECT post_id FROM {$wpdb->prefix}postmeta WHERE meta_key = '_children' AND meta_value LIKE '%%i:%d;%%'",
|
||||||
$product->get_id()
|
$product->get_id()
|
||||||
) );
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $parent_product_ids;
|
return $parent_product_ids;
|
||||||
@@ -1175,7 +1176,7 @@ class WC_Subscriptions_Product {
|
|||||||
*
|
*
|
||||||
* Unlike @see WC_Subscriptions_Product::get_parent_ids(), this function will return parent products which still exist, are visible and are a grouped product.
|
* Unlike @see WC_Subscriptions_Product::get_parent_ids(), this function will return parent products which still exist, are visible and are a grouped product.
|
||||||
*
|
*
|
||||||
* @param WC_Product The product object to get parents from.
|
* @param WC_Product $product The product object to get parents from.
|
||||||
* @return array The product's grouped parent IDs.
|
* @return array The product's grouped parent IDs.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.3.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.3.0
|
||||||
*/
|
*/
|
||||||
@@ -1254,7 +1255,6 @@ class WC_Subscriptions_Product {
|
|||||||
/**
|
/**
|
||||||
* Check if the current session has an order awaiting payment for a subscription to a specific product line item.
|
* Check if the current session has an order awaiting payment for a subscription to a specific product line item.
|
||||||
*
|
*
|
||||||
* @return 2.0.13
|
|
||||||
* @return bool
|
* @return bool
|
||||||
**/
|
**/
|
||||||
protected static function order_awaiting_payment_for_product( $product_id ) {
|
protected static function order_awaiting_payment_for_product( $product_id ) {
|
||||||
|
@@ -28,7 +28,7 @@ class WC_Subscriptions_Renewal_Order {
|
|||||||
add_filter( 'wcs_renewal_order_created', array( __CLASS__, 'add_order_note' ), 10, 2 );
|
add_filter( 'wcs_renewal_order_created', array( __CLASS__, 'add_order_note' ), 10, 2 );
|
||||||
|
|
||||||
// Prevent customers from cancelling renewal orders. Needs to be hooked before WC_Form_Handler::cancel_order() (20)
|
// Prevent customers from cancelling renewal orders. Needs to be hooked before WC_Form_Handler::cancel_order() (20)
|
||||||
add_action( 'wp_loaded', array( __CLASS__, 'prevent_cancelling_renewal_orders' ), 19, 3 );
|
add_action( 'wp_loaded', array( __CLASS__, 'prevent_cancelling_renewal_orders' ), 19 );
|
||||||
|
|
||||||
// Don't copy switch order item meta to renewal order items
|
// Don't copy switch order item meta to renewal order items
|
||||||
add_filter( 'wcs_new_order_items', array( __CLASS__, 'remove_switch_item_meta_keys' ), 10, 1 );
|
add_filter( 'wcs_new_order_items', array( __CLASS__, 'remove_switch_item_meta_keys' ), 10, 1 );
|
||||||
@@ -51,7 +51,7 @@ class WC_Subscriptions_Renewal_Order {
|
|||||||
* Check if a given renewal order was created to replace a failed renewal order.
|
* Check if a given renewal order was created to replace a failed renewal order.
|
||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.5.12
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.5.12
|
||||||
* @param int ID of the renewal order you want to check against
|
* @param int $renewal_order_id ID of the renewal order you want to check against
|
||||||
* @return mixed If the renewal order did replace a failed order, the ID of the fail order, else false
|
* @return mixed If the renewal order did replace a failed order, the ID of the fail order, else false
|
||||||
*/
|
*/
|
||||||
public static function get_failed_order_replaced_by( $renewal_order_id ) {
|
public static function get_failed_order_replaced_by( $renewal_order_id ) {
|
||||||
@@ -170,7 +170,7 @@ class WC_Subscriptions_Renewal_Order {
|
|||||||
|
|
||||||
$order_id = absint( $_GET['order_id'] );
|
$order_id = absint( $_GET['order_id'] );
|
||||||
$order = wc_get_order( $order_id );
|
$order = wc_get_order( $order_id );
|
||||||
$redirect = $_GET['redirect'];
|
$redirect = wc_clean( wp_unslash( $_GET['redirect'] ) );
|
||||||
|
|
||||||
if ( wcs_order_contains_renewal( $order ) ) {
|
if ( wcs_order_contains_renewal( $order ) ) {
|
||||||
remove_action( 'wp_loaded', 'WC_Form_Handler::cancel_order', 20 );
|
remove_action( 'wp_loaded', 'WC_Form_Handler::cancel_order', 20 );
|
||||||
@@ -268,6 +268,7 @@ class WC_Subscriptions_Renewal_Order {
|
|||||||
*/
|
*/
|
||||||
public static function maybe_generate_manual_renewal_order( $user_id, $subscription_key ) {
|
public static function maybe_generate_manual_renewal_order( $user_id, $subscription_key ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', __CLASS__ . '::maybe_create_manual_renewal_order( WC_Subscription $subscription )' );
|
_deprecated_function( __METHOD__, '2.0', __CLASS__ . '::maybe_create_manual_renewal_order( WC_Subscription $subscription )' );
|
||||||
|
// @phpstan-ignore staticMethod.notFound
|
||||||
self::maybe_create_manual_renewal_order( wcs_get_subscription_from_key( $subscription_key ) );
|
self::maybe_create_manual_renewal_order( wcs_get_subscription_from_key( $subscription_key ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,7 +278,7 @@ class WC_Subscriptions_Renewal_Order {
|
|||||||
* Deprecated because a subscription's details are now stored in a WC_Subscription object, not the
|
* Deprecated because a subscription's details are now stored in a WC_Subscription object, not the
|
||||||
* parent order.
|
* parent order.
|
||||||
*
|
*
|
||||||
* @param WC_Order|int $order The WC_Order object or ID of a WC_Order order.
|
* @param WC_Order|int $renewal_order The WC_Order object or ID of a WC_Order order.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
@@ -295,7 +296,7 @@ class WC_Subscriptions_Renewal_Order {
|
|||||||
* Deprecated because a subscription's details are now stored in a WC_Subscription object, not the
|
* Deprecated because a subscription's details are now stored in a WC_Subscription object, not the
|
||||||
* parent order.
|
* parent order.
|
||||||
*
|
*
|
||||||
* @param WC_Order|int $order The WC_Order object or ID of a WC_Order order.
|
* @param WC_Order|int $renewal_order The WC_Order object or ID of a WC_Order order.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0, self::get_parent_subscription() is the better function to use now as a renewal order
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0, self::get_parent_subscription() is the better function to use now as a renewal order
|
||||||
*/
|
*/
|
||||||
@@ -367,7 +368,7 @@ class WC_Subscriptions_Renewal_Order {
|
|||||||
*
|
*
|
||||||
* Deprecated because the use of a $subscription_key is deprecated.
|
* Deprecated because the use of a $subscription_key is deprecated.
|
||||||
*
|
*
|
||||||
* @param string $subscription_key A subscription key of the form created by @see WC_Subscriptions_Manager::get_subscription_key()
|
* @param string $product_id The ID of the product to renew.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
@@ -386,7 +387,7 @@ class WC_Subscriptions_Renewal_Order {
|
|||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
public static function can_subscription_be_renewed( $subscription_key, $user_id = '' ) {
|
public static function can_subscription_be_renewed( $subscription_key, $user_id = 0 ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'wcs_can_user_resubscribe_to( $subscription, $user_id )' );
|
_deprecated_function( __METHOD__, '2.0', 'wcs_can_user_resubscribe_to( $subscription, $user_id )' );
|
||||||
return wcs_can_user_resubscribe_to( wcs_get_subscription_from_key( $subscription_key ), $user_id );
|
return wcs_can_user_resubscribe_to( wcs_get_subscription_from_key( $subscription_key ), $user_id );
|
||||||
}
|
}
|
||||||
@@ -417,7 +418,7 @@ class WC_Subscriptions_Renewal_Order {
|
|||||||
/**
|
/**
|
||||||
* Created a new order for renewing a subscription product based on the details of a previous order.
|
* Created a new order for renewing a subscription product based on the details of a previous order.
|
||||||
*
|
*
|
||||||
* @param WC_Order|int $order The WC_Order object or ID of the order for which the a new order should be created.
|
* @param WC_Order|int $original_order The WC_Order object or ID of the order for which the a new order should be created.
|
||||||
* @param string $product_id The ID of the subscription product in the order which needs to be added to the new order.
|
* @param string $product_id The ID of the subscription product in the order which needs to be added to the new order.
|
||||||
* @param array $args (optional) An array of name => value flags:
|
* @param array $args (optional) An array of name => value flags:
|
||||||
* 'new_order_role' string A flag to indicate whether the new order should become the master order for the subscription. Accepts either 'parent' or 'child'. Defaults to 'parent' - replace the existing order.
|
* 'new_order_role' string A flag to indicate whether the new order should become the master order for the subscription. Accepts either 'parent' or 'child'. Defaults to 'parent' - replace the existing order.
|
||||||
@@ -531,6 +532,9 @@ class WC_Subscriptions_Renewal_Order {
|
|||||||
*
|
*
|
||||||
* This is particularly important to ensure renewals of limited subscriptions can be completed.
|
* This is particularly important to ensure renewals of limited subscriptions can be completed.
|
||||||
*
|
*
|
||||||
|
* @param string $pay_url The URL to the payment page.
|
||||||
|
* @param WC_Order|int $order The WC_Order object or ID of a WC_Order order.
|
||||||
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.5.5
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.5.5
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
@@ -554,7 +558,7 @@ class WC_Subscriptions_Renewal_Order {
|
|||||||
* @see WC_Subscriptions_Manager::process_subscription_payments_on_order() function would
|
* @see WC_Subscriptions_Manager::process_subscription_payments_on_order() function would
|
||||||
* never be called. This function makes sure it is called.
|
* never be called. This function makes sure it is called.
|
||||||
*
|
*
|
||||||
* @param WC_Order|int $order A WC_Order object or ID of a WC_Order order.
|
* @param int $order_id The ID of a WC_Order object.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
@@ -574,7 +578,7 @@ class WC_Subscriptions_Renewal_Order {
|
|||||||
/**
|
/**
|
||||||
* Records manual payment of a renewal order against a subscription.
|
* Records manual payment of a renewal order against a subscription.
|
||||||
*
|
*
|
||||||
* @param WC_Order|int $order A WC_Order object or ID of a WC_Order order.
|
* @param int $order_id The ID of a WC_Order object.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
@@ -594,7 +598,7 @@ class WC_Subscriptions_Renewal_Order {
|
|||||||
/**
|
/**
|
||||||
* Records manual payment of a renewal order against a subscription.
|
* Records manual payment of a renewal order against a subscription.
|
||||||
*
|
*
|
||||||
* @param WC_Order|int $order A WC_Order object or ID of a WC_Order order.
|
* @param WC_Order|int $order_id A WC_Order object or ID of a WC_Order order.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
@@ -615,8 +619,9 @@ class WC_Subscriptions_Renewal_Order {
|
|||||||
* If the payment for a renewal order has previously failed and is then paid, we need to make sure the
|
* If the payment for a renewal order has previously failed and is then paid, we need to make sure the
|
||||||
* subscription payment function is called.
|
* subscription payment function is called.
|
||||||
*
|
*
|
||||||
* @param int $user_id The id of the user who purchased the subscription
|
* @param int $order_id The ID of a WC_Order object.
|
||||||
* @param string $subscription_key A subscription key of the form created by @see WC_Subscriptions_Manager::get_subscription_key()
|
* @param string $payment_status The status of the payment.
|
||||||
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
|
@@ -321,7 +321,10 @@ class WC_Subscriptions_Synchroniser {
|
|||||||
?>
|
?>
|
||||||
</select>
|
</select>
|
||||||
</span>
|
</span>
|
||||||
<?php echo wcs_help_tip( self::$sync_description_year ); ?>
|
<?php
|
||||||
|
// @phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
|
echo wcs_help_tip( self::$sync_description_year );
|
||||||
|
?>
|
||||||
</p><?php
|
</p><?php
|
||||||
|
|
||||||
echo '</div>';
|
echo '</div>';
|
||||||
@@ -370,7 +373,7 @@ class WC_Subscriptions_Synchroniser {
|
|||||||
*/
|
*/
|
||||||
public static function save_subscription_meta( $post_id ) {
|
public static function save_subscription_meta( $post_id ) {
|
||||||
|
|
||||||
if ( empty( $_POST['_wcsnonce'] ) || ! wp_verify_nonce( $_POST['_wcsnonce'], 'wcs_subscription_meta' ) ) {
|
if ( empty( $_POST['_wcsnonce'] ) || ! wp_verify_nonce( wc_clean( wp_unslash( $_POST['_wcsnonce'] ) ), 'wcs_subscription_meta' ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,8 +385,8 @@ class WC_Subscriptions_Synchroniser {
|
|||||||
if ( 'year' == $_POST['_subscription_period'] ) { // save the day & month for the date rather than just the day
|
if ( 'year' == $_POST['_subscription_period'] ) { // save the day & month for the date rather than just the day
|
||||||
|
|
||||||
$_POST[ self::$post_meta_key ] = array(
|
$_POST[ self::$post_meta_key ] = array(
|
||||||
'day' => isset( $_POST[ self::$post_meta_key_day ] ) ? $_POST[ self::$post_meta_key_day ] : 0,
|
'day' => isset( $_POST[ self::$post_meta_key_day ] ) ? wc_clean( wp_unslash( $_POST[ self::$post_meta_key_day ] ) ) : 0,
|
||||||
'month' => isset( $_POST[ self::$post_meta_key_month ] ) ? $_POST[ self::$post_meta_key_month ] : '01',
|
'month' => isset( $_POST[ self::$post_meta_key_month ] ) ? wc_clean( wp_unslash( $_POST[ self::$post_meta_key_month ] ) ) : '01',
|
||||||
);
|
);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -393,7 +396,7 @@ class WC_Subscriptions_Synchroniser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
update_post_meta( $post_id, self::$post_meta_key, $_POST[ self::$post_meta_key ] );
|
update_post_meta( $post_id, self::$post_meta_key, wc_clean( wp_unslash( $_POST[ self::$post_meta_key ] ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -403,7 +406,7 @@ class WC_Subscriptions_Synchroniser {
|
|||||||
*/
|
*/
|
||||||
public static function process_product_meta_variable_subscription( $post_id ) {
|
public static function process_product_meta_variable_subscription( $post_id ) {
|
||||||
|
|
||||||
if ( empty( $_POST['_wcsnonce_save_variations'] ) || ! wp_verify_nonce( $_POST['_wcsnonce_save_variations'], 'wcs_subscription_variations' ) || ! isset( $_POST['variable_post_id'] ) || ! is_array( $_POST['variable_post_id'] ) ) {
|
if ( empty( $_POST['_wcsnonce_save_variations'] ) || ! wp_verify_nonce( wc_clean( wp_unslash( $_POST['_wcsnonce_save_variations'] ) ), 'wcs_subscription_variations' ) || ! isset( $_POST['variable_post_id'] ) || ! is_array( $_POST['variable_post_id'] ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -418,7 +421,7 @@ class WC_Subscriptions_Synchroniser {
|
|||||||
*/
|
*/
|
||||||
public static function save_product_variation( $variation_id, $index ) {
|
public static function save_product_variation( $variation_id, $index ) {
|
||||||
|
|
||||||
if ( empty( $_POST['_wcsnonce_save_variations'] ) || ! wp_verify_nonce( $_POST['_wcsnonce_save_variations'], 'wcs_subscription_variations' ) || ! isset( $_POST['variable_post_id'] ) || ! is_array( $_POST['variable_post_id'] ) ) {
|
if ( empty( $_POST['_wcsnonce_save_variations'] ) || ! wp_verify_nonce( wc_clean( wp_unslash( $_POST['_wcsnonce_save_variations'] ) ), 'wcs_subscription_variations' ) || ! isset( $_POST['variable_post_id'] ) || ! is_array( $_POST['variable_post_id'] ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -428,15 +431,15 @@ class WC_Subscriptions_Synchroniser {
|
|||||||
if ( 'year' == $_POST['variable_subscription_period'][ $index ] ) { // save the day & month for the date rather than just the day
|
if ( 'year' == $_POST['variable_subscription_period'][ $index ] ) { // save the day & month for the date rather than just the day
|
||||||
|
|
||||||
$_POST[ 'variable' . self::$post_meta_key ][ $index ] = array(
|
$_POST[ 'variable' . self::$post_meta_key ][ $index ] = array(
|
||||||
'day' => isset( $_POST[ $day_field ][ $index ] ) ? $_POST[ $day_field ][ $index ] : 0,
|
'day' => isset( $_POST[ $day_field ][ $index ] ) ? wc_clean( wp_unslash( $_POST[ $day_field ][ $index ] ) ) : 0,
|
||||||
'month' => isset( $_POST[ $month_field ][ $index ] ) ? $_POST[ $month_field ][ $index ] : 0,
|
'month' => isset( $_POST[ $month_field ][ $index ] ) ? wc_clean( wp_unslash( $_POST[ $month_field ][ $index ] ) ) : 0,
|
||||||
);
|
);
|
||||||
|
|
||||||
} elseif ( ! isset( $_POST[ 'variable' . self::$post_meta_key ][ $index ] ) ) {
|
} elseif ( ! isset( $_POST[ 'variable' . self::$post_meta_key ][ $index ] ) ) {
|
||||||
$_POST[ 'variable' . self::$post_meta_key ][ $index ] = 0;
|
$_POST[ 'variable' . self::$post_meta_key ][ $index ] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
update_post_meta( $variation_id, self::$post_meta_key, $_POST[ 'variable' . self::$post_meta_key ][ $index ] );
|
update_post_meta( $variation_id, self::$post_meta_key, wc_clean( wp_unslash( $_POST[ 'variable' . self::$post_meta_key ][ $index ] ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -608,6 +611,7 @@ class WC_Subscriptions_Synchroniser {
|
|||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.5
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.5
|
||||||
*/
|
*/
|
||||||
public static function calculate_first_payment_date( $product, $type = 'mysql', $from_date = '' ) {
|
public static function calculate_first_payment_date( $product, $type = 'mysql', $from_date = '' ) {
|
||||||
|
$first_payment_timestamp = 0;
|
||||||
|
|
||||||
if ( ! is_object( $product ) ) {
|
if ( ! is_object( $product ) ) {
|
||||||
$product = wc_get_product( $product );
|
$product = wc_get_product( $product );
|
||||||
@@ -645,7 +649,7 @@ class WC_Subscriptions_Synchroniser {
|
|||||||
if ( 'week' == $period ) {
|
if ( 'week' == $period ) {
|
||||||
|
|
||||||
// Get the day of the week for the from date
|
// Get the day of the week for the from date
|
||||||
$from_day = gmdate( 'N', $from_timestamp );
|
$from_day = (int) gmdate( 'N', $from_timestamp );
|
||||||
|
|
||||||
// To account for rollover of the weekdays. For example, if from day is Saturday and the payment date is Monday,
|
// To account for rollover of the weekdays. For example, if from day is Saturday and the payment date is Monday,
|
||||||
// and the grace period is 2, Saturday is day 6 and Monday is day 1.
|
// and the grace period is 2, Saturday is day 6 and Monday is day 1.
|
||||||
@@ -665,7 +669,7 @@ class WC_Subscriptions_Synchroniser {
|
|||||||
$payment_day = gmdate( 't', $from_timestamp ); // the number of days in the month
|
$payment_day = gmdate( 't', $from_timestamp ); // the number of days in the month
|
||||||
}
|
}
|
||||||
|
|
||||||
$from_day = gmdate( 'j', $from_timestamp );
|
$from_day = (int) gmdate( 'j', $from_timestamp );
|
||||||
|
|
||||||
// If 'from day' is before 'sync day' in the month
|
// If 'from day' is before 'sync day' in the month
|
||||||
if ( $from_day <= $payment_day ) {
|
if ( $from_day <= $payment_day ) {
|
||||||
@@ -677,7 +681,7 @@ class WC_Subscriptions_Synchroniser {
|
|||||||
$month_number = gmdate( 'm', wcs_add_months( $from_timestamp, $interval - 1 ) );
|
$month_number = gmdate( 'm', wcs_add_months( $from_timestamp, $interval - 1 ) );
|
||||||
}
|
}
|
||||||
} else { // If 'from day' is after 'sync day' in the month
|
} else { // If 'from day' is after 'sync day' in the month
|
||||||
$days_in_month = gmdate( 't', $from_timestamp );
|
$days_in_month = (int) gmdate( 't', $from_timestamp );
|
||||||
// Use 'days in month' to account for end of month dates
|
// Use 'days in month' to account for end of month dates
|
||||||
if ( $from_day + $no_fee_days - $days_in_month >= $payment_day ) { // In grace period
|
if ( $from_day + $no_fee_days - $days_in_month >= $payment_day ) { // In grace period
|
||||||
$month = gmdate( 'F', wcs_add_months( $from_timestamp, 1 ) );
|
$month = gmdate( 'F', wcs_add_months( $from_timestamp, 1 ) );
|
||||||
@@ -723,6 +727,8 @@ class WC_Subscriptions_Synchroniser {
|
|||||||
$year++;
|
$year++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$first_payment_timestamp = 0;
|
||||||
|
|
||||||
if ( $from_timestamp + ( $no_fee_days * DAY_IN_SECONDS ) >=
|
if ( $from_timestamp + ( $no_fee_days * DAY_IN_SECONDS ) >=
|
||||||
wcs_strtotime_dark_knight( "{$payment_day['day']} {$month} {$year}" ) ) { // In grace period
|
wcs_strtotime_dark_knight( "{$payment_day['day']} {$month} {$year}" ) ) { // In grace period
|
||||||
$first_payment_timestamp = wcs_strtotime_dark_knight( "{$payment_day['day']} {$month} {$year}", $from_timestamp );
|
$first_payment_timestamp = wcs_strtotime_dark_knight( "{$payment_day['day']} {$month} {$year}", $from_timestamp );
|
||||||
@@ -1037,10 +1043,9 @@ class WC_Subscriptions_Synchroniser {
|
|||||||
* Filters WC_Subscriptions_Order::get_sign_up_fee() to make sure the sign-up fee for a subscription product
|
* Filters WC_Subscriptions_Order::get_sign_up_fee() to make sure the sign-up fee for a subscription product
|
||||||
* that is synchronised is returned correctly.
|
* that is synchronised is returned correctly.
|
||||||
*
|
*
|
||||||
* @param float The initial sign-up fee charged when the subscription product in the order was first purchased, if any.
|
* @param float $sign_up_fee The initial sign-up fee charged when the subscription product in the order was first purchased, if any.
|
||||||
* @param mixed $order A WC_Order object or the ID of the order which the subscription was purchased in.
|
* @param WC_Subscription $subscription The subscription object.
|
||||||
* @param int $product_id The post ID of the subscription WC_Product object purchased in the order. Defaults to the ID of the first product purchased in the order.
|
* @param int $product_id The post ID of the subscription WC_Product object purchased in the order. Defaults to the ID of the first product purchased in the order.
|
||||||
* @return float The initial sign-up fee charged when the subscription product in the order was first purchased, if any.
|
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
public static function get_synced_sign_up_fee( $sign_up_fee, $subscription, $product_id ) {
|
public static function get_synced_sign_up_fee( $sign_up_fee, $subscription, $product_id ) {
|
||||||
@@ -1072,15 +1077,17 @@ class WC_Subscriptions_Synchroniser {
|
|||||||
return $price;
|
return $price;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$days_in_cycle = 0;
|
||||||
|
|
||||||
switch ( WC_Subscriptions_Product::get_period( $product ) ) {
|
switch ( WC_Subscriptions_Product::get_period( $product ) ) {
|
||||||
case 'week':
|
case 'week':
|
||||||
$days_in_cycle = 7 * WC_Subscriptions_Product::get_interval( $product );
|
$days_in_cycle = 7 * WC_Subscriptions_Product::get_interval( $product );
|
||||||
break;
|
break;
|
||||||
case 'month':
|
case 'month':
|
||||||
$days_in_cycle = gmdate( 't' ) * WC_Subscriptions_Product::get_interval( $product );
|
$days_in_cycle = (int) gmdate( 't' ) * WC_Subscriptions_Product::get_interval( $product );
|
||||||
break;
|
break;
|
||||||
case 'year':
|
case 'year':
|
||||||
$days_in_cycle = ( 365 + gmdate( 'L' ) ) * WC_Subscriptions_Product::get_interval( $product );
|
$days_in_cycle = ( 365 + (int) gmdate( 'L' ) ) * WC_Subscriptions_Product::get_interval( $product );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1132,7 +1139,7 @@ class WC_Subscriptions_Synchroniser {
|
|||||||
*
|
*
|
||||||
* @param integer $qty the original quantity that would be taken out of the stock level
|
* @param integer $qty the original quantity that would be taken out of the stock level
|
||||||
* @param array $order order data
|
* @param array $order order data
|
||||||
* @param array $item item data for each item in the order
|
* @param array $order_item item data for each item in the order
|
||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
@@ -1159,7 +1166,7 @@ class WC_Subscriptions_Synchroniser {
|
|||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*
|
*
|
||||||
* @param WC_Subscription|int Subscription object or ID.
|
* @param WC_Subscription|int $subscription Subscription object or ID.
|
||||||
*/
|
*/
|
||||||
public static function maybe_add_subscription_meta( $subscription ) {
|
public static function maybe_add_subscription_meta( $subscription ) {
|
||||||
if ( ! is_object( $subscription ) ) {
|
if ( ! is_object( $subscription ) ) {
|
||||||
@@ -1167,6 +1174,7 @@ class WC_Subscriptions_Synchroniser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( $subscription && ! self::subscription_contains_synced_product( $subscription ) ) {
|
if ( $subscription && ! self::subscription_contains_synced_product( $subscription ) ) {
|
||||||
|
/** @var WC_Order_Item_Product $item */
|
||||||
foreach ( $subscription->get_items() as $item ) {
|
foreach ( $subscription->get_items() as $item ) {
|
||||||
$product = $item->get_product();
|
$product = $item->get_product();
|
||||||
|
|
||||||
@@ -1183,8 +1191,8 @@ class WC_Subscriptions_Synchroniser {
|
|||||||
* When adding an item to an order/subscription via the Add/Edit Subscription administration interface, check if we should be setting
|
* When adding an item to an order/subscription via the Add/Edit Subscription administration interface, check if we should be setting
|
||||||
* the sync meta on the subscription.
|
* the sync meta on the subscription.
|
||||||
*
|
*
|
||||||
* @param int The order item ID of an item that was just added to the order
|
* @param int $item_id The order item ID of an item that was just added to the order
|
||||||
* @param array The order item details
|
* @param array $item The order item details
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
public static function ajax_maybe_add_meta_for_item( $item_id, $item ) {
|
public static function ajax_maybe_add_meta_for_item( $item_id, $item ) {
|
||||||
@@ -1200,9 +1208,9 @@ class WC_Subscriptions_Synchroniser {
|
|||||||
* When adding a product to an order/subscription via the WC_Subscription::add_product() method, check if we should be setting
|
* When adding a product to an order/subscription via the WC_Subscription::add_product() method, check if we should be setting
|
||||||
* the sync meta on the subscription.
|
* the sync meta on the subscription.
|
||||||
*
|
*
|
||||||
* @param int The post ID of a WC_Order or child object
|
* @param int $subscription_id The post ID of a WC_Order or child object
|
||||||
* @param int The order item ID of an item that was just added to the order
|
* @param int $item_id The order item ID of an item that was just added to the order
|
||||||
* @param object The WC_Product for which an item was just added
|
* @param object $product The WC_Product for which an item was just added
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
public static function maybe_add_meta_for_new_product( $subscription_id, $item_id, $product ) {
|
public static function maybe_add_meta_for_new_product( $subscription_id, $item_id, $product ) {
|
||||||
@@ -1216,7 +1224,7 @@ class WC_Subscriptions_Synchroniser {
|
|||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*
|
*
|
||||||
* @param int|WC_Subscription Accepts either a subscription object or ID.
|
* @param int|WC_Subscription $subscription Accepts either a subscription object or ID.
|
||||||
* @return bool True if the subscription is synced, false otherwise.
|
* @return bool True if the subscription is synced, false otherwise.
|
||||||
*/
|
*/
|
||||||
public static function subscription_contains_synced_product( $subscription ) {
|
public static function subscription_contains_synced_product( $subscription ) {
|
||||||
@@ -1257,9 +1265,9 @@ class WC_Subscriptions_Synchroniser {
|
|||||||
*
|
*
|
||||||
* Attached to WC 3.0+ hooks and uses WC 3.0 methods.
|
* Attached to WC 3.0+ hooks and uses WC 3.0 methods.
|
||||||
*
|
*
|
||||||
* @param int The new line item id
|
* @param int $item_id The new line item id
|
||||||
* @param WC_Order_Item
|
* @param WC_Order_Item $item
|
||||||
* @param int The post ID of a WC_Subscription
|
* @param int $subscription_id The post ID of a WC_Subscription
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.3
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.3
|
||||||
*/
|
*/
|
||||||
public static function maybe_add_meta_for_new_line_item( $item_id, $item, $subscription_id ) {
|
public static function maybe_add_meta_for_new_line_item( $item_id, $item, $subscription_id ) {
|
||||||
@@ -1552,7 +1560,7 @@ class WC_Subscriptions_Synchroniser {
|
|||||||
* Filters WC_Subscriptions_Order::get_sign_up_fee() to make sure the sign-up fee for a subscription product
|
* Filters WC_Subscriptions_Order::get_sign_up_fee() to make sure the sign-up fee for a subscription product
|
||||||
* that is synchronised is returned correctly.
|
* that is synchronised is returned correctly.
|
||||||
*
|
*
|
||||||
* @param float The initial sign-up fee charged when the subscription product in the order was first purchased, if any.
|
* @param float $sign_up_fee The initial sign-up fee charged when the subscription product in the order was first purchased, if any.
|
||||||
* @param mixed $order A WC_Order object or the ID of the order which the subscription was purchased in.
|
* @param mixed $order A WC_Order object or the ID of the order which the subscription was purchased in.
|
||||||
* @param int $product_id The post ID of the subscription WC_Product object purchased in the order. Defaults to the ID of the first product purchased in the order.
|
* @param int $product_id The post ID of the subscription WC_Product object purchased in the order. Defaults to the ID of the first product purchased in the order.
|
||||||
* @return float The initial sign-up fee charged when the subscription product in the order was first purchased, if any.
|
* @return float The initial sign-up fee charged when the subscription product in the order was first purchased, if any.
|
||||||
|
@@ -50,7 +50,7 @@ class WCS_Action_Scheduler_Customer_Notifications extends WCS_Scheduler {
|
|||||||
|
|
||||||
add_action( 'woocommerce_before_subscription_object_save', [ $this, 'update_notifications' ], 10, 2 );
|
add_action( 'woocommerce_before_subscription_object_save', [ $this, 'update_notifications' ], 10, 2 );
|
||||||
|
|
||||||
add_action( 'update_option_' . WC_Subscriptions_Admin::$option_prefix . WC_Subscriptions_Email_Notifications::$offset_setting_string, [ $this, 'set_time_offset_from_option' ], 5, 3 );
|
add_action( 'update_option_' . WC_Subscriptions_Admin::$option_prefix . WC_Subscriptions_Email_Notifications::$offset_setting_string, [ $this, 'set_time_offset_from_option' ], 5, 2 );
|
||||||
add_action( 'add_option_' . WC_Subscriptions_Admin::$option_prefix . WC_Subscriptions_Email_Notifications::$offset_setting_string, [ $this, 'set_time_offset_from_option' ], 5, 2 );
|
add_action( 'add_option_' . WC_Subscriptions_Admin::$option_prefix . WC_Subscriptions_Email_Notifications::$offset_setting_string, [ $this, 'set_time_offset_from_option' ], 5, 2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -85,9 +85,9 @@ class WCS_Action_Scheduler extends WCS_Scheduler {
|
|||||||
/**
|
/**
|
||||||
* When a subscription's status is updated, maybe schedule an event
|
* When a subscription's status is updated, maybe schedule an event
|
||||||
*
|
*
|
||||||
* @param object $subscription An instance of a WC_Subscription object
|
* @param WC_Subscription $subscription An instance of a WC_Subscription object
|
||||||
* @param string $date_type Can be 'trial_end', 'next_payment', 'end', 'end_of_prepaid_term' or a custom date type
|
* @param string $new_status Can be 'trial_end', 'next_payment', 'end', 'end_of_prepaid_term' or a custom date type
|
||||||
* @param string $datetime A MySQL formatted date/time string in the GMT/UTC timezone.
|
* @param string $old_status
|
||||||
*/
|
*/
|
||||||
public function update_status( $subscription, $new_status, $old_status ) {
|
public function update_status( $subscription, $new_status, $old_status ) {
|
||||||
|
|
||||||
@@ -230,7 +230,7 @@ class WCS_Action_Scheduler extends WCS_Scheduler {
|
|||||||
/**
|
/**
|
||||||
* Get the args to set on the scheduled action.
|
* Get the args to set on the scheduled action.
|
||||||
*
|
*
|
||||||
* @param string $$action_hook Name of event used as the hook for the scheduled action.
|
* @param string $action_hook Name of event used as the hook for the scheduled action.
|
||||||
* @param array $action_args Array of name => value pairs stored against the scheduled action.
|
* @param array $action_args Array of name => value pairs stored against the scheduled action.
|
||||||
*/
|
*/
|
||||||
protected function unschedule_actions( $action_hook, $action_args ) {
|
protected function unschedule_actions( $action_hook, $action_args ) {
|
||||||
|
@@ -78,8 +78,7 @@ class WCS_Batch_Processing_Controller {
|
|||||||
function ( $batch_process ) {
|
function ( $batch_process ) {
|
||||||
$this->process_next_batch_for_single_processor( $batch_process );
|
$this->process_next_batch_for_single_processor( $batch_process );
|
||||||
},
|
},
|
||||||
10,
|
10
|
||||||
2
|
|
||||||
);
|
);
|
||||||
|
|
||||||
add_action(
|
add_action(
|
||||||
@@ -271,7 +270,7 @@ class WCS_Batch_Processing_Controller {
|
|||||||
* @param float $time_taken Time take by the batch to complete processing.
|
* @param float $time_taken Time take by the batch to complete processing.
|
||||||
* @param \Exception|null $last_error Exception object in processing the batch, if there was one.
|
* @param \Exception|null $last_error Exception object in processing the batch, if there was one.
|
||||||
*/
|
*/
|
||||||
private function update_processor_state( WCS_Batch_Processor $batch_processor, float $time_taken, \Exception $last_error = null ): void {
|
private function update_processor_state( WCS_Batch_Processor $batch_processor, float $time_taken, ?\Exception $last_error = null ): void {
|
||||||
$current_status = $this->get_process_details( $batch_processor );
|
$current_status = $this->get_process_details( $batch_processor );
|
||||||
$current_status['total_time_spent'] += $time_taken;
|
$current_status['total_time_spent'] += $time_taken;
|
||||||
$current_status['last_error'] = null !== $last_error ? $last_error->getMessage() : null;
|
$current_status['last_error'] = null !== $last_error ? $last_error->getMessage() : null;
|
||||||
@@ -333,7 +332,8 @@ class WCS_Batch_Processing_Controller {
|
|||||||
* @throws \Exception If it's not possible to get an instance of the class.
|
* @throws \Exception If it's not possible to get an instance of the class.
|
||||||
*/
|
*/
|
||||||
private function get_processor_instance( string $processor_class_name ): WCS_Batch_Processor {
|
private function get_processor_instance( string $processor_class_name ): WCS_Batch_Processor {
|
||||||
if ( ! isset( $processor ) && class_exists( $processor_class_name ) ) {
|
$processor = null;
|
||||||
|
if ( class_exists( $processor_class_name ) ) {
|
||||||
// This is a fallback for when the batch processor is not registered in the container.
|
// This is a fallback for when the batch processor is not registered in the container.
|
||||||
$processor = new $processor_class_name();
|
$processor = new $processor_class_name();
|
||||||
}
|
}
|
||||||
|
@@ -44,7 +44,7 @@ class WCS_Cart_Initial_Payment extends WCS_Cart_Renewal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Pay for existing order
|
// Pay for existing order
|
||||||
$order_key = $_GET['key'];
|
$order_key = wc_clean( wp_unslash( $_GET['key'] ) );
|
||||||
$order_id = absint( $wp->query_vars['order-pay'] );
|
$order_id = absint( $wp->query_vars['order-pay'] );
|
||||||
$order = wc_get_order( $order_id );
|
$order = wc_get_order( $order_id );
|
||||||
|
|
||||||
@@ -135,11 +135,11 @@ class WCS_Cart_Initial_Payment extends WCS_Cart_Renewal {
|
|||||||
/**
|
/**
|
||||||
* Get the order object used to construct the initial payment cart.
|
* Get the order object used to construct the initial payment cart.
|
||||||
*
|
*
|
||||||
* @param Array The initial payment cart item.
|
* @param array $cart_item The initial payment cart item.
|
||||||
* @return WC_Order | The order object
|
* @return WC_Order The order object
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0.13
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0.13
|
||||||
*/
|
*/
|
||||||
protected function get_order( $cart_item = '' ) {
|
protected function get_order( $cart_item = array() ) {
|
||||||
$order = false;
|
$order = false;
|
||||||
|
|
||||||
if ( empty( $cart_item ) ) {
|
if ( empty( $cart_item ) ) {
|
||||||
|
@@ -178,7 +178,7 @@ class WCS_Cart_Renewal {
|
|||||||
if ( isset( $_GET['pay_for_order'] ) && isset( $_GET['key'] ) && isset( $wp->query_vars['order-pay'] ) ) {
|
if ( isset( $_GET['pay_for_order'] ) && isset( $_GET['key'] ) && isset( $wp->query_vars['order-pay'] ) ) {
|
||||||
|
|
||||||
// Pay for existing order
|
// Pay for existing order
|
||||||
$order_key = $_GET['key'];
|
$order_key = isset( $_GET['key'] ) ? wc_clean( wp_unslash( $_GET['key'] ) ) : '';
|
||||||
$order_id = isset( $wp->query_vars['order-pay'] ) ? $wp->query_vars['order-pay'] : absint( $_GET['order_id'] );
|
$order_id = isset( $wp->query_vars['order-pay'] ) ? $wp->query_vars['order-pay'] : absint( $_GET['order_id'] );
|
||||||
$order = wc_get_order( $order_id );
|
$order = wc_get_order( $order_id );
|
||||||
|
|
||||||
@@ -211,7 +211,7 @@ class WCS_Cart_Renewal {
|
|||||||
do_action( 'wcs_before_renewal_setup_cart_subscription', $subscription, $order );
|
do_action( 'wcs_before_renewal_setup_cart_subscription', $subscription, $order );
|
||||||
|
|
||||||
// Check if order/subscription can be paid for
|
// Check if order/subscription can be paid for
|
||||||
if ( empty( $subscription ) || ! $subscription->has_status( array( 'on-hold', 'pending' ) ) ) {
|
if ( ! $subscription->has_status( array( 'on-hold', 'pending' ) ) ) {
|
||||||
wc_add_notice( __( 'This order can no longer be paid because the corresponding subscription does not require payment at this time.', 'woocommerce-subscriptions' ), 'error' );
|
wc_add_notice( __( 'This order can no longer be paid because the corresponding subscription does not require payment at this time.', 'woocommerce-subscriptions' ), 'error' );
|
||||||
} else {
|
} else {
|
||||||
// Add the existing subscription items to the cart
|
// Add the existing subscription items to the cart
|
||||||
@@ -279,9 +279,9 @@ class WCS_Cart_Renewal {
|
|||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0
|
||||||
*
|
*
|
||||||
* @param WC_Abstract_Order $subscription The subscription or Order object to set up the cart from.
|
* @param WC_Subscription $subscription The subscription or Order object to set up the cart from.
|
||||||
* @param array $cart_item_data Additional cart item data to set on the cart items.
|
* @param array $cart_item_data Additional cart item data to set on the cart items.
|
||||||
* @param string $validation_type Whether all items are required or not. Optional. Can be 'all_items_not_required' or 'all_items_required'. 'all_items_not_required' by default.
|
* @param string $validation_type Whether all items are required or not. Optional. Can be 'all_items_not_required' or 'all_items_required'. 'all_items_not_required' by default.
|
||||||
* 'all_items_not_required' - If an order/subscription line item fails to be added to the cart, the remaining items will be added.
|
* 'all_items_not_required' - If an order/subscription line item fails to be added to the cart, the remaining items will be added.
|
||||||
* 'all_items_required' - If an order/subscription line item fails to be added to the cart, all items will be removed and the cart setup will be aborted.
|
* 'all_items_required' - If an order/subscription line item fails to be added to the cart, all items will be removed and the cart setup will be aborted.
|
||||||
*/
|
*/
|
||||||
@@ -671,7 +671,7 @@ class WCS_Cart_Renewal {
|
|||||||
$subscriptions = wcs_get_subscriptions_for_renewal_order( $order );
|
$subscriptions = wcs_get_subscriptions_for_renewal_order( $order );
|
||||||
|
|
||||||
foreach ( $subscriptions as $subscription ) {
|
foreach ( $subscriptions as $subscription ) {
|
||||||
if ( empty( $subscription ) || ! $subscription->has_status( array( 'on-hold', 'pending' ) ) ) {
|
if ( ! $subscription->has_status( array( 'on-hold', 'pending' ) ) ) {
|
||||||
unset( $actions['pay'] );
|
unset( $actions['pay'] );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -820,7 +820,7 @@ class WCS_Cart_Renewal {
|
|||||||
/**
|
/**
|
||||||
* Get original products for a renewal order - so that we can ensure renewal coupons are only applied to those
|
* Get original products for a renewal order - so that we can ensure renewal coupons are only applied to those
|
||||||
*
|
*
|
||||||
* @param object WC_Order | WC_Subscription $order
|
* @param WC_Order|WC_Subscription $order
|
||||||
* @return array $product_ids an array of product ids on a subscription/order
|
* @return array $product_ids an array of product ids on a subscription/order
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0.10
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0.10
|
||||||
*/
|
*/
|
||||||
@@ -843,12 +843,12 @@ class WCS_Cart_Renewal {
|
|||||||
/**
|
/**
|
||||||
* Store renewal coupon information in a session variable so we can access it later when coupon data is being retrieved
|
* Store renewal coupon information in a session variable so we can access it later when coupon data is being retrieved
|
||||||
*
|
*
|
||||||
* @param int $subscription_id subscription id
|
* @param int $order_id order id
|
||||||
* @param object $coupon coupon
|
* @param object $coupon coupon
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0.10
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0.10
|
||||||
*/
|
*/
|
||||||
protected function store_coupon( $order_id, $coupon ) {
|
protected function store_coupon( $order_id, $coupon ) {
|
||||||
if ( ! empty( $order_id ) && ! empty( $coupon ) ) {
|
if ( ! empty( $order_id ) ) {
|
||||||
$renewal_coupons = WC()->session->get( 'wcs_renewal_coupons', array() );
|
$renewal_coupons = WC()->session->get( 'wcs_renewal_coupons', array() );
|
||||||
$use_bools = wcs_is_woocommerce_pre( '3.0' ); // Some coupon properties have changed from accepting 'no' and 'yes' to true and false args.
|
$use_bools = wcs_is_woocommerce_pre( '3.0' ); // Some coupon properties have changed from accepting 'no' and 'yes' to true and false args.
|
||||||
$coupon_properties = array();
|
$coupon_properties = array();
|
||||||
@@ -975,11 +975,11 @@ class WCS_Cart_Renewal {
|
|||||||
/**
|
/**
|
||||||
* Get the order object used to construct the renewal cart.
|
* Get the order object used to construct the renewal cart.
|
||||||
*
|
*
|
||||||
* @param Array The renewal cart item.
|
* @param array $cart_item The renewal cart item.
|
||||||
* @return WC_Order | The order object
|
* @return WC_Order The order object
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0.13
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0.13
|
||||||
*/
|
*/
|
||||||
protected function get_order( $cart_item = '' ) {
|
protected function get_order( $cart_item = array() ) {
|
||||||
$order = false;
|
$order = false;
|
||||||
|
|
||||||
if ( empty( $cart_item ) ) {
|
if ( empty( $cart_item ) ) {
|
||||||
@@ -1027,8 +1027,8 @@ class WCS_Cart_Renewal {
|
|||||||
* Right before WC processes a renewal cart through the checkout, set the cart hash.
|
* Right before WC processes a renewal cart through the checkout, set the cart hash.
|
||||||
* This ensures legitimate changes to taxes and shipping methods don't cause a new order to be created.
|
* This ensures legitimate changes to taxes and shipping methods don't cause a new order to be created.
|
||||||
*
|
*
|
||||||
* @param Mixed | An order generated by third party plugins
|
* @param mixed $order An order generated by third party plugins
|
||||||
* @return Mixed | The unchanged order param
|
* @return mixed The unchanged order param
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.11
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.11
|
||||||
*/
|
*/
|
||||||
public function update_cart_hash( $order ) {
|
public function update_cart_hash( $order ) {
|
||||||
@@ -1054,8 +1054,8 @@ class WCS_Cart_Renewal {
|
|||||||
/**
|
/**
|
||||||
* Redirect back to pay for an order after successfully logging in.
|
* Redirect back to pay for an order after successfully logging in.
|
||||||
*
|
*
|
||||||
* @param string The redirect URL after successful login.
|
* @param string $redirect The redirect URL after successful login.
|
||||||
* @param WP_User The newly logged in user object.
|
* @param WP_User $user The newly logged in user object.
|
||||||
* @return string
|
* @return string
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.1.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.1.0
|
||||||
*/
|
*/
|
||||||
@@ -1064,7 +1064,7 @@ class WCS_Cart_Renewal {
|
|||||||
* Nonce verification is not needed here as it was already checked during the log-in process, see WC_Form_Handler::process_login().
|
* Nonce verification is not needed here as it was already checked during the log-in process, see WC_Form_Handler::process_login().
|
||||||
*/
|
*/
|
||||||
if ( isset( $_GET['wcs_redirect'], $_GET['wcs_redirect_id'] ) && 'pay_for_order' === $_GET['wcs_redirect'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
if ( isset( $_GET['wcs_redirect'], $_GET['wcs_redirect_id'] ) && 'pay_for_order' === $_GET['wcs_redirect'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||||
$order = wc_get_order( $_GET['wcs_redirect_id'] );
|
$order = wc_get_order( wc_clean( wp_unslash( $_GET['wcs_redirect_id'] ) ) );
|
||||||
|
|
||||||
if ( $order && $order->get_user_id() && user_can( $user, 'pay_for_order', $order->get_id() ) ) {
|
if ( $order && $order->get_user_id() && user_can( $user, 'pay_for_order', $order->get_id() ) ) {
|
||||||
$redirect = $order->get_checkout_payment_url();
|
$redirect = $order->get_checkout_payment_url();
|
||||||
@@ -1099,12 +1099,12 @@ class WCS_Cart_Renewal {
|
|||||||
* Prevent compounding dynamic discounts on cart items.
|
* Prevent compounding dynamic discounts on cart items.
|
||||||
* Dynamic discounts are copied from the subscription to the renewal order and so don't need to be applied again in the cart.
|
* Dynamic discounts are copied from the subscription to the renewal order and so don't need to be applied again in the cart.
|
||||||
*
|
*
|
||||||
* @param bool Whether to apply the dynamic discount
|
* @param bool $adjust_price Whether to apply the dynamic discount
|
||||||
* @param string The cart item key of the cart item the dynamic discount is being applied to.
|
* @param string $cart_item_key The cart item key of the cart item the dynamic discount is being applied to.
|
||||||
* @return bool
|
* @return bool
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.1.4
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.1.4
|
||||||
*/
|
*/
|
||||||
function prevent_compounding_dynamic_discounts( $adjust_price, $cart_item_key ) {
|
public function prevent_compounding_dynamic_discounts( $adjust_price, $cart_item_key ) {
|
||||||
|
|
||||||
if ( $adjust_price && isset( WC()->cart->cart_contents[ $cart_item_key ][ $this->cart_item_key ] ) ) {
|
if ( $adjust_price && isset( WC()->cart->cart_contents[ $cart_item_key ][ $this->cart_item_key ] ) ) {
|
||||||
$adjust_price = false;
|
$adjust_price = false;
|
||||||
@@ -1136,7 +1136,7 @@ class WCS_Cart_Renewal {
|
|||||||
* the cart so we can update it later.
|
* the cart so we can update it later.
|
||||||
*
|
*
|
||||||
* @param int|WC_Order $order_id
|
* @param int|WC_Order $order_id
|
||||||
* @param array $checkout_posted_data
|
* @param array $posted_checkout_data
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.1
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.1
|
||||||
*/
|
*/
|
||||||
public function set_order_item_id( $order_id, $posted_checkout_data = array() ) {
|
public function set_order_item_id( $order_id, $posted_checkout_data = array() ) {
|
||||||
@@ -1298,7 +1298,7 @@ class WCS_Cart_Renewal {
|
|||||||
* Used when WC 3.0 or newer is active. When prior versions are active,
|
* Used when WC 3.0 or newer is active. When prior versions are active,
|
||||||
* @see WCS_Cart_Renewal->add_order_item_meta() replaces this function
|
* @see WCS_Cart_Renewal->add_order_item_meta() replaces this function
|
||||||
*
|
*
|
||||||
* @param WC_Order_Item_Product
|
* @param WC_Order_Item_Product $item
|
||||||
* @param string $cart_item_key
|
* @param string $cart_item_key
|
||||||
* @param array $cart_item_data
|
* @param array $cart_item_data
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.11
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.11
|
||||||
@@ -1772,8 +1772,8 @@ class WCS_Cart_Renewal {
|
|||||||
* Right before WC processes a renewal cart through the checkout, set the cart hash.
|
* Right before WC processes a renewal cart through the checkout, set the cart hash.
|
||||||
* This ensures legitimate changes to taxes and shipping methods don't cause a new order to be created.
|
* This ensures legitimate changes to taxes and shipping methods don't cause a new order to be created.
|
||||||
*
|
*
|
||||||
* @param Mixed | An order generated by third party plugins
|
* @param mixed $order An order generated by third party plugins
|
||||||
* @return Mixed | The unchanged order param
|
* @return mixed The unchanged order param
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.1.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.1.0
|
||||||
*/
|
*/
|
||||||
public function set_renewal_order_cart_hash( $order ) {
|
public function set_renewal_order_cart_hash( $order ) {
|
||||||
@@ -1884,7 +1884,7 @@ class WCS_Cart_Renewal {
|
|||||||
* status as 'failed' until it is paid. By default, it will always set it to 'pending', but we need it left as 'failed'
|
* status as 'failed' until it is paid. By default, it will always set it to 'pending', but we need it left as 'failed'
|
||||||
* so that we can correctly identify the status change in @see self::maybe_change_subscription_status().
|
* so that we can correctly identify the status change in @see self::maybe_change_subscription_status().
|
||||||
*
|
*
|
||||||
* @param string Default order status for orders paid for via checkout. Default 'pending'
|
* @param string $order_status Default order status for orders paid for via checkout. Default 'pending'
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*
|
*
|
||||||
* @deprecated 6.3.0
|
* @deprecated 6.3.0
|
||||||
|
@@ -36,14 +36,22 @@ class WCS_Cart_Resubscribe extends WCS_Cart_Renewal {
|
|||||||
|
|
||||||
// Mock a free trial on the cart item to make sure the resubscribe total doesn't include any recurring amount when honoring prepaid term
|
// Mock a free trial on the cart item to make sure the resubscribe total doesn't include any recurring amount when honoring prepaid term
|
||||||
add_filter( 'woocommerce_before_calculate_totals', array( &$this, 'maybe_set_free_trial' ), 100, 1 );
|
add_filter( 'woocommerce_before_calculate_totals', array( &$this, 'maybe_set_free_trial' ), 100, 1 );
|
||||||
|
// @phpstan-ignore return.void
|
||||||
add_action( 'woocommerce_subscription_cart_before_grouping', array( &$this, 'maybe_unset_free_trial' ) );
|
add_action( 'woocommerce_subscription_cart_before_grouping', array( &$this, 'maybe_unset_free_trial' ) );
|
||||||
|
// @phpstan-ignore return.void
|
||||||
add_action( 'woocommerce_subscription_cart_after_grouping', array( &$this, 'maybe_set_free_trial' ) );
|
add_action( 'woocommerce_subscription_cart_after_grouping', array( &$this, 'maybe_set_free_trial' ) );
|
||||||
|
// @phpstan-ignore return.void
|
||||||
add_action( 'wcs_recurring_cart_start_date', array( &$this, 'maybe_unset_free_trial' ), 0, 1 );
|
add_action( 'wcs_recurring_cart_start_date', array( &$this, 'maybe_unset_free_trial' ), 0, 1 );
|
||||||
|
// @phpstan-ignore return.void
|
||||||
add_action( 'wcs_recurring_cart_end_date', array( &$this, 'maybe_set_free_trial' ), 100, 1 );
|
add_action( 'wcs_recurring_cart_end_date', array( &$this, 'maybe_set_free_trial' ), 100, 1 );
|
||||||
add_filter( 'woocommerce_subscriptions_calculated_total', array( &$this, 'maybe_unset_free_trial' ), 10000, 1 );
|
add_filter( 'woocommerce_subscriptions_calculated_total', array( &$this, 'maybe_unset_free_trial' ), 10000, 1 );
|
||||||
|
// @phpstan-ignore return.void
|
||||||
add_action( 'woocommerce_cart_totals_before_shipping', array( &$this, 'maybe_set_free_trial' ) );
|
add_action( 'woocommerce_cart_totals_before_shipping', array( &$this, 'maybe_set_free_trial' ) );
|
||||||
|
// @phpstan-ignore return.void
|
||||||
add_action( 'woocommerce_cart_totals_after_shipping', array( &$this, 'maybe_unset_free_trial' ) );
|
add_action( 'woocommerce_cart_totals_after_shipping', array( &$this, 'maybe_unset_free_trial' ) );
|
||||||
|
// @phpstan-ignore return.void
|
||||||
add_action( 'woocommerce_review_order_before_shipping', array( &$this, 'maybe_set_free_trial' ) );
|
add_action( 'woocommerce_review_order_before_shipping', array( &$this, 'maybe_set_free_trial' ) );
|
||||||
|
// @phpstan-ignore return.void
|
||||||
add_action( 'woocommerce_review_order_after_shipping', array( &$this, 'maybe_unset_free_trial' ) );
|
add_action( 'woocommerce_review_order_after_shipping', array( &$this, 'maybe_unset_free_trial' ) );
|
||||||
|
|
||||||
add_action( 'woocommerce_order_status_changed', array( &$this, 'maybe_cancel_existing_subscription' ), 10, 3 );
|
add_action( 'woocommerce_order_status_changed', array( &$this, 'maybe_cancel_existing_subscription' ), 10, 3 );
|
||||||
@@ -62,15 +70,12 @@ class WCS_Cart_Resubscribe extends WCS_Cart_Renewal {
|
|||||||
|
|
||||||
if ( isset( $_GET['resubscribe'] ) && isset( $_GET['_wpnonce'] ) ) {
|
if ( isset( $_GET['resubscribe'] ) && isset( $_GET['_wpnonce'] ) ) {
|
||||||
|
|
||||||
$subscription = wcs_get_subscription( $_GET['resubscribe'] );
|
$subscription = wcs_get_subscription( wc_clean( wp_unslash( $_GET['resubscribe'] ) ) );
|
||||||
$redirect_to = get_permalink( wc_get_page_id( 'myaccount' ) );
|
$redirect_to = get_permalink( wc_get_page_id( 'myaccount' ) );
|
||||||
|
|
||||||
if ( wp_verify_nonce( $_GET['_wpnonce'], $subscription->get_id() ) === false ) {
|
if ( wp_verify_nonce( wc_clean( wp_unslash( $_GET['_wpnonce'] ) ), $subscription->get_id() ) === false ) {
|
||||||
|
|
||||||
wc_add_notice( __( 'There was an error with your request to resubscribe. Please try again.', 'woocommerce-subscriptions' ), 'error' );
|
wc_add_notice( __( 'There was an error with your request to resubscribe. Please try again.', 'woocommerce-subscriptions' ), 'error' );
|
||||||
|
|
||||||
} elseif ( empty( $subscription ) ) {
|
} elseif ( empty( $subscription ) ) {
|
||||||
|
|
||||||
wc_add_notice( __( 'That subscription does not exist. Has it been deleted?', 'woocommerce-subscriptions' ), 'error' );
|
wc_add_notice( __( 'That subscription does not exist. Has it been deleted?', 'woocommerce-subscriptions' ), 'error' );
|
||||||
|
|
||||||
} elseif ( ! current_user_can( 'subscribe_again', $subscription->get_id() ) ) {
|
} elseif ( ! current_user_can( 'subscribe_again', $subscription->get_id() ) ) {
|
||||||
@@ -80,7 +85,6 @@ class WCS_Cart_Resubscribe extends WCS_Cart_Renewal {
|
|||||||
} elseif ( ! wcs_can_user_resubscribe_to( $subscription ) ) {
|
} elseif ( ! wcs_can_user_resubscribe_to( $subscription ) ) {
|
||||||
|
|
||||||
wc_add_notice( __( 'You can not resubscribe to that subscription. Please contact us if you need assistance.', 'woocommerce-subscriptions' ), 'error' );
|
wc_add_notice( __( 'You can not resubscribe to that subscription. Please contact us if you need assistance.', 'woocommerce-subscriptions' ), 'error' );
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
$this->setup_cart( $subscription, array(
|
$this->setup_cart( $subscription, array(
|
||||||
@@ -101,7 +105,7 @@ class WCS_Cart_Resubscribe extends WCS_Cart_Renewal {
|
|||||||
|
|
||||||
$order_id = ( isset( $wp->query_vars['order-pay'] ) ) ? $wp->query_vars['order-pay'] : absint( $_GET['order_id'] );
|
$order_id = ( isset( $wp->query_vars['order-pay'] ) ) ? $wp->query_vars['order-pay'] : absint( $_GET['order_id'] );
|
||||||
$order = wc_get_order( $wp->query_vars['order-pay'] );
|
$order = wc_get_order( $wp->query_vars['order-pay'] );
|
||||||
$order_key = $_GET['key'];
|
$order_key = wc_clean( wp_unslash( $_GET['key'] ) );
|
||||||
|
|
||||||
if ( wcs_get_objects_property( $order, 'order_key' ) == $order_key && $order->has_status( array( 'pending', 'failed' ) ) && wcs_order_contains_resubscribe( $order ) ) {
|
if ( wcs_get_objects_property( $order, 'order_key' ) == $order_key && $order->has_status( array( 'pending', 'failed' ) ) && wcs_order_contains_resubscribe( $order ) ) {
|
||||||
|
|
||||||
@@ -200,21 +204,21 @@ class WCS_Cart_Resubscribe extends WCS_Cart_Renewal {
|
|||||||
*
|
*
|
||||||
* @see wcs_cart_contains_resubscribe()
|
* @see wcs_cart_contains_resubscribe()
|
||||||
* @param WC_Cart $cart The cart object to search in.
|
* @param WC_Cart $cart The cart object to search in.
|
||||||
* @return bool | Array The cart item containing the renewal, else false.
|
* @return bool|array The cart item containing the renewal, else false.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0.10
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0.10
|
||||||
*/
|
*/
|
||||||
protected function cart_contains( $cart = '' ) {
|
protected function cart_contains( $cart = null ) {
|
||||||
return wcs_cart_contains_resubscribe( $cart );
|
return wcs_cart_contains_resubscribe( $cart );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the subscription object used to construct the resubscribe cart.
|
* Get the subscription object used to construct the resubscribe cart.
|
||||||
*
|
*
|
||||||
* @param Array The resubscribe cart item.
|
* @param array $cart_item The resubscribe cart item.
|
||||||
* @return WC_Subscription | The subscription object.
|
* @return WC_Subscription The subscription object.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0.13
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0.13
|
||||||
*/
|
*/
|
||||||
protected function get_order( $cart_item = '' ) {
|
protected function get_order( $cart_item = null ) {
|
||||||
$subscription = false;
|
$subscription = false;
|
||||||
|
|
||||||
if ( empty( $cart_item ) ) {
|
if ( empty( $cart_item ) ) {
|
||||||
|
@@ -45,8 +45,11 @@ class WCS_Change_Payment_Method_Admin {
|
|||||||
|
|
||||||
} elseif ( count( $valid_payment_methods ) == 1 ) {
|
} elseif ( count( $valid_payment_methods ) == 1 ) {
|
||||||
echo '<strong>' . esc_html__( 'Payment method', 'woocommerce-subscriptions' ) . '</strong><br/>' . esc_html( current( $valid_payment_methods ) );
|
echo '<strong>' . esc_html__( 'Payment method', 'woocommerce-subscriptions' ) . '</strong><br/>' . esc_html( current( $valid_payment_methods ) );
|
||||||
// translators: %s: gateway ID.
|
// @phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
echo wcs_help_tip( sprintf( _x( 'Gateway ID: [%s]', 'The gateway ID displayed on the Edit Subscriptions screen when editing payment method.', 'woocommerce-subscriptions' ), key( $valid_payment_methods ) ) );
|
echo wcs_help_tip(
|
||||||
|
// translators: %s: gateway ID.
|
||||||
|
sprintf( _x( 'Gateway ID: [%s]', 'The gateway ID displayed on the Edit Subscriptions screen when editing payment method.', 'woocommerce-subscriptions' ), key( $valid_payment_methods ) )
|
||||||
|
);
|
||||||
echo '<input type="hidden" value="' . esc_attr( key( $valid_payment_methods ) ) . '" id="_payment_method" name="_payment_method">';
|
echo '<input type="hidden" value="' . esc_attr( key( $valid_payment_methods ) ) . '" id="_payment_method" name="_payment_method">';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,7 +104,7 @@ class WCS_Change_Payment_Method_Admin {
|
|||||||
*/
|
*/
|
||||||
public static function save_meta( $subscription ) {
|
public static function save_meta( $subscription ) {
|
||||||
|
|
||||||
if ( empty( $_POST['_wcsnonce'] ) || ! wp_verify_nonce( $_POST['_wcsnonce'], 'wcs_change_payment_method_admin' ) ) {
|
if ( empty( $_POST['_wcsnonce'] ) || ! wp_verify_nonce( wc_clean( wp_unslash( $_POST['_wcsnonce'] ) ), 'wcs_change_payment_method_admin' ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +128,7 @@ class WCS_Change_Payment_Method_Admin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach ( $meta as $meta_key => $meta_data ) {
|
foreach ( $meta as $meta_key => $meta_data ) {
|
||||||
$payment_method_meta[ $meta_table ][ $meta_key ]['value'] = isset( $_POST['_payment_method_meta'][ $payment_method ][ $meta_table ][ $meta_key ] ) ? $_POST['_payment_method_meta'][ $payment_method ][ $meta_table ][ $meta_key ] : '';
|
$payment_method_meta[ $meta_table ][ $meta_key ]['value'] = isset( $_POST['_payment_method_meta'][ $payment_method ][ $meta_table ][ $meta_key ] ) ? wc_clean( wp_unslash( $_POST['_payment_method_meta'][ $payment_method ][ $meta_table ][ $meta_key ] ) ) : '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -158,8 +161,8 @@ class WCS_Change_Payment_Method_Admin {
|
|||||||
* Get a list of possible gateways that a subscription could be changed to by admins.
|
* Get a list of possible gateways that a subscription could be changed to by admins.
|
||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
* @param $subscription int | WC_Subscription
|
* @param int|WC_Subscription $subscription The subscription object
|
||||||
* @return
|
* @return array
|
||||||
*/
|
*/
|
||||||
public static function get_valid_payment_methods( $subscription ) {
|
public static function get_valid_payment_methods( $subscription ) {
|
||||||
|
|
||||||
|
@@ -77,7 +77,7 @@ class WCS_Download_Handler {
|
|||||||
|
|
||||||
foreach ( array_keys( $downloads ) as $download_id ) {
|
foreach ( array_keys( $downloads ) as $download_id ) {
|
||||||
// grant access on subscription if it does not already exist
|
// grant access on subscription if it does not already exist
|
||||||
if ( ! $wpdb->get_var( $wpdb->prepare( "SELECT download_id FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE `order_id` = %d AND `product_id` = %d AND `download_id` = '%s'", $subscription->get_id(), $product_id, $download_id ) ) ) {
|
if ( ! $wpdb->get_var( $wpdb->prepare( "SELECT download_id FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE `order_id` = %d AND `product_id` = %d AND `download_id` = %s", $subscription->get_id(), $product_id, $download_id ) ) ) {
|
||||||
wc_downloadable_file_permission( $download_id, $product_id, $subscription, $item['qty'] );
|
wc_downloadable_file_permission( $download_id, $product_id, $subscription, $item['qty'] );
|
||||||
}
|
}
|
||||||
self::revoke_downloadable_file_permission( $product_id, $order_id, $order->get_user_id() );
|
self::revoke_downloadable_file_permission( $product_id, $order_id, $order->get_user_id() );
|
||||||
|
@@ -121,6 +121,7 @@ class WCS_Failed_Scheduled_Action_Manager {
|
|||||||
// Log any exceptions caught by the exception listener in action logs.
|
// Log any exceptions caught by the exception listener in action logs.
|
||||||
if ( ! empty( $context['exceptions'] ) ) {
|
if ( ! empty( $context['exceptions'] ) ) {
|
||||||
foreach ( $context['exceptions'] as $exception_message ) {
|
foreach ( $context['exceptions'] as $exception_message ) {
|
||||||
|
// @phpstan-ignore-next-line
|
||||||
ActionScheduler_Logger::instance()->log( $action_id, $exception_message );
|
ActionScheduler_Logger::instance()->log( $action_id, $exception_message );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -243,7 +244,7 @@ class WCS_Failed_Scheduled_Action_Manager {
|
|||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.19
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.19
|
||||||
*/
|
*/
|
||||||
protected function maybe_disable_admin_notice() {
|
protected function maybe_disable_admin_notice() {
|
||||||
if ( isset( $_GET['_wcsnonce'] ) && wp_verify_nonce( $_GET['_wcsnonce'], 'wcs_scheduled_action_timeout_error_notice' ) && isset( $_GET['wcs_scheduled_action_timeout_error_notice'] ) ) {
|
if ( isset( $_GET['_wcsnonce'] ) && wp_verify_nonce( wc_clean( wp_unslash( $_GET['_wcsnonce'] ) ), 'wcs_scheduled_action_timeout_error_notice' ) && isset( $_GET['wcs_scheduled_action_timeout_error_notice'] ) ) {
|
||||||
delete_option( WC_Subscriptions_Admin::$option_prefix . '_failed_scheduled_actions' );
|
delete_option( WC_Subscriptions_Admin::$option_prefix . '_failed_scheduled_actions' );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -24,7 +24,7 @@ class WCS_Initial_Cart_Stock_Manager extends WCS_Renewal_Cart_Stock_Manager {
|
|||||||
parent::attach_callbacks();
|
parent::attach_callbacks();
|
||||||
|
|
||||||
// The parent class attaches a filter not needed for initial carts. So we remove it and attach the parent order equivalent.
|
// The parent class attaches a filter not needed for initial carts. So we remove it and attach the parent order equivalent.
|
||||||
remove_action( 'wcs_before_renewal_setup_cart_subscription', 'WCS_Renewal_Cart_Stock_Manager::maybe_adjust_stock_cart', 10, 2 );
|
remove_action( 'wcs_before_renewal_setup_cart_subscription', 'WCS_Renewal_Cart_Stock_Manager::maybe_adjust_stock_cart', 10 );
|
||||||
add_action( 'wcs_before_parent_order_setup_cart', array( get_called_class(), 'maybe_adjust_stock_cart' ), 10, 2 );
|
add_action( 'wcs_before_parent_order_setup_cart', array( get_called_class(), 'maybe_adjust_stock_cart' ), 10, 2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -163,7 +163,7 @@ class WCS_Limiter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Adding to cart
|
// Adding to cart
|
||||||
if ( isset( $_GET['switch-subscription'] ) && array_key_exists( $_GET['switch-subscription'], self::get_user_subscriptions_to_product( $product, $user_id, $product_limitation ) ) ) {
|
if ( isset( $_GET['switch-subscription'] ) && array_key_exists( wc_clean( wp_unslash( $_GET['switch-subscription'] ) ), self::get_user_subscriptions_to_product( $product, $user_id, $product_limitation ) ) ) {
|
||||||
$is_purchasable = true;
|
$is_purchasable = true;
|
||||||
} else {
|
} else {
|
||||||
// If we have a variation product get the variable product's ID. We can't use the variation ID for comparison because this function sometimes receives a variable product.
|
// If we have a variation product get the variable product's ID. We can't use the variation ID for comparison because this function sometimes receives a variable product.
|
||||||
@@ -198,9 +198,10 @@ class WCS_Limiter {
|
|||||||
*/
|
*/
|
||||||
public static function is_purchasable_renewal( $is_purchasable, $product ) {
|
public static function is_purchasable_renewal( $is_purchasable, $product ) {
|
||||||
if ( false === $is_purchasable && false === self::is_purchasable_product( $is_purchasable, $product ) ) {
|
if ( false === $is_purchasable && false === self::is_purchasable_product( $is_purchasable, $product ) ) {
|
||||||
|
$resubscribe_cart_item = wcs_cart_contains_resubscribe();
|
||||||
|
|
||||||
// Resubscribe logic
|
// Resubscribe logic
|
||||||
if ( isset( $_GET['resubscribe'] ) || false !== ( $resubscribe_cart_item = wcs_cart_contains_resubscribe() ) ) {
|
if ( isset( $_GET['resubscribe'] ) || false !== $resubscribe_cart_item ) {
|
||||||
$subscription_id = ( isset( $_GET['resubscribe'] ) ) ? absint( $_GET['resubscribe'] ) : $resubscribe_cart_item['subscription_resubscribe']['subscription_id'];
|
$subscription_id = ( isset( $_GET['resubscribe'] ) ) ? absint( $_GET['resubscribe'] ) : $resubscribe_cart_item['subscription_resubscribe']['subscription_id'];
|
||||||
$subscription = wcs_get_subscription( $subscription_id );
|
$subscription = wcs_get_subscription( $subscription_id );
|
||||||
|
|
||||||
|
@@ -34,8 +34,8 @@ class WCS_My_Account_Payment_Methods {
|
|||||||
/**
|
/**
|
||||||
* Add additional query args to delete token URLs which are being used for subscription automatic payments.
|
* Add additional query args to delete token URLs which are being used for subscription automatic payments.
|
||||||
*
|
*
|
||||||
* @param array data about the token including a list of actions which can be triggered by the customer from their my account page
|
* @param array $payment_token_data data about the token including a list of actions which can be triggered by the customer from their my account page
|
||||||
* @param WC_Payment_Token payment token object
|
* @param WC_Payment_Token $payment_token payment token object
|
||||||
* @return array payment token data
|
* @return array payment token data
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.7
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.7
|
||||||
*/
|
*/
|
||||||
@@ -63,8 +63,8 @@ class WCS_My_Account_Payment_Methods {
|
|||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v3.1.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v3.1.0
|
||||||
*
|
*
|
||||||
* @param bool Whether the delete button should be shown for tokens linked to a subscription. true - show, false - not shown (default).
|
* @param bool $allow_deletion Whether the delete button should be shown for tokens linked to a subscription. true - show, false - not shown (default).
|
||||||
* @param WC_Payment_Token The payment token in question.
|
* @param WC_Payment_Token $payment_token The payment token in question.
|
||||||
*/
|
*/
|
||||||
if ( isset( $payment_token_data['actions']['delete'] ) && ! apply_filters( 'wc_subscriptions_allow_subscription_token_deletion', false, $payment_token ) ) {
|
if ( isset( $payment_token_data['actions']['delete'] ) && ! apply_filters( 'wc_subscriptions_allow_subscription_token_deletion', false, $payment_token ) ) {
|
||||||
// Cannot delete a token used for active subscriptions where there is no alternative.
|
// Cannot delete a token used for active subscriptions where there is no alternative.
|
||||||
@@ -99,7 +99,7 @@ class WCS_My_Account_Payment_Methods {
|
|||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.7
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.7
|
||||||
*/
|
*/
|
||||||
public static function maybe_update_subscriptions_payment_meta( $deleted_token_id, $deleted_token ) {
|
public static function maybe_update_subscriptions_payment_meta( $deleted_token_id, $deleted_token ) {
|
||||||
if ( ! isset( $_GET['delete_subscription_token'] ) || empty( $_GET['wcs_nonce'] ) || ! wp_verify_nonce( $_GET['wcs_nonce'], 'delete_subscription_token_' . $_GET['delete_subscription_token'] ) ) {
|
if ( ! isset( $_GET['delete_subscription_token'] ) || empty( $_GET['wcs_nonce'] ) || ! wp_verify_nonce( wc_clean( wp_unslash( $_GET['wcs_nonce'] ) ), 'delete_subscription_token_' . wc_clean( wp_unslash( $_GET['delete_subscription_token'] ) ) ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,6 +108,7 @@ class WCS_My_Account_Payment_Methods {
|
|||||||
|
|
||||||
$new_token = WCS_Payment_Tokens::get_customers_alternative_token( $deleted_token );
|
$new_token = WCS_Payment_Tokens::get_customers_alternative_token( $deleted_token );
|
||||||
|
|
||||||
|
// @phpstan-ignore empty.variable
|
||||||
if ( empty( $new_token ) ) {
|
if ( empty( $new_token ) ) {
|
||||||
$notice = esc_html__( 'The deleted payment method was used for automatic subscription payments, we couldn\'t find an alternative token payment method token to change your subscriptions to.', 'woocommerce-subscriptions' );
|
$notice = esc_html__( 'The deleted payment method was used for automatic subscription payments, we couldn\'t find an alternative token payment method token to change your subscriptions to.', 'woocommerce-subscriptions' );
|
||||||
wc_add_notice( $notice, 'error' );
|
wc_add_notice( $notice, 'error' );
|
||||||
@@ -146,7 +147,7 @@ class WCS_My_Account_Payment_Methods {
|
|||||||
*
|
*
|
||||||
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.7.2
|
* @deprecated 1.0.0 - Migrated from WooCommerce Subscriptions v2.7.2
|
||||||
*
|
*
|
||||||
* @param WC_Payment_Token payment token object
|
* @param WC_Payment_Token $token payment token object
|
||||||
* @return string WC_Payment_Token label
|
* @return string WC_Payment_Token label
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.7
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.7
|
||||||
*/
|
*/
|
||||||
@@ -207,14 +208,14 @@ class WCS_My_Account_Payment_Methods {
|
|||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.3.3
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.3.3
|
||||||
*/
|
*/
|
||||||
public static function update_subscription_tokens() {
|
public static function update_subscription_tokens() {
|
||||||
if ( ! isset( $_GET['update-subscription-tokens'], $_GET['token-id'], $_GET['_wcsnonce'] ) || ! wp_verify_nonce( $_GET['_wcsnonce'], 'wcs-update-subscription-tokens' ) ) {
|
if ( ! isset( $_GET['update-subscription-tokens'], $_GET['token-id'], $_GET['_wcsnonce'] ) || ! wp_verify_nonce( wc_clean( wp_unslash( $_GET['_wcsnonce'] ) ), 'wcs-update-subscription-tokens' ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// init payment gateways
|
// init payment gateways
|
||||||
WC()->payment_gateways();
|
WC()->payment_gateways();
|
||||||
|
|
||||||
$default_token_id = $_GET['token-id'];
|
$default_token_id = wc_clean( wp_unslash( $_GET['token-id'] ) );
|
||||||
$default_token = WC_Payment_Tokens::get( $default_token_id );
|
$default_token = WC_Payment_Tokens::get( $default_token_id );
|
||||||
|
|
||||||
if ( ! $default_token ) {
|
if ( ! $default_token ) {
|
||||||
@@ -233,7 +234,7 @@ class WCS_My_Account_Payment_Methods {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wp_redirect( remove_query_arg( array( 'update-subscription-tokens', 'token-id', '_wcsnonce' ) ) );
|
wp_safe_redirect( remove_query_arg( array( 'update-subscription-tokens', 'token-id', '_wcsnonce' ) ) );
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -51,8 +51,8 @@ class WCS_Object_Data_Cache_Manager extends WCS_Post_Meta_Cache_Manager {
|
|||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param string The post type this cache manage acts on.
|
* @param string $object_type The post type this cache manage acts on.
|
||||||
* @param array The post meta keys this cache manager should act on.
|
* @param array $data_keys The post meta keys this cache manager should act on.
|
||||||
*/
|
*/
|
||||||
public function __construct( $object_type, $data_keys ) {
|
public function __construct( $object_type, $data_keys ) {
|
||||||
$this->object_type = $object_type;
|
$this->object_type = $object_type;
|
||||||
@@ -82,33 +82,35 @@ class WCS_Object_Data_Cache_Manager extends WCS_Post_Meta_Cache_Manager {
|
|||||||
* Relevant changes to the object's data is stored in the $this->object_changes property
|
* Relevant changes to the object's data is stored in the $this->object_changes property
|
||||||
* to be processed after the object is saved. See $this->action_object_cache_changes().
|
* to be processed after the object is saved. See $this->action_object_cache_changes().
|
||||||
*
|
*
|
||||||
* @param WC_Data $object The object which is being saved.
|
* @param WC_Subscription $subscription The object which is being saved.
|
||||||
* @param string $generate_type Optional. The data to generate the changes from. Defaults to 'changes_only' which will generate the data from changes to the object. 'all_fields' will fetch data from the object for all tracked data keys.
|
* @param string $generate_type Optional. The data to generate the changes from. Defaults to 'changes_only' which will generate the data from changes to the object. 'all_fields' will fetch data from the object for all tracked data keys.
|
||||||
*/
|
*/
|
||||||
public function prepare_object_changes( $object, $generate_type = 'changes_only' ) {
|
public function prepare_object_changes( $subscription, $generate_type = 'changes_only' ) {
|
||||||
// If the object hasn't been created yet, we can't do anything yet. We'll have to wait until after the object is saved.
|
// If the object hasn't been created yet, we can't do anything yet. We'll have to wait until after the object is saved.
|
||||||
if ( ! $object->get_id() ) {
|
if ( ! $subscription->get_id() ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$force_all_fields = 'all_fields' === $generate_type;
|
$force_all_fields = 'all_fields' === $generate_type;
|
||||||
$changes = $object->get_changes();
|
// @phpstan-ignore-next-line
|
||||||
$base_data = $object->get_base_data();
|
$changes = $subscription->get_changes();
|
||||||
$meta_data = $object->get_meta_data();
|
$base_data = $subscription->get_base_data();
|
||||||
|
// @phpstan-ignore-next-line
|
||||||
|
$meta_data = $subscription->get_meta_data();
|
||||||
|
|
||||||
// Deleted meta won't be included in the changes, so we need to fetch the previous value via the raw meta data.
|
// Deleted meta won't be included in the changes, so we need to fetch the previous value via the raw meta data.
|
||||||
$data_store = $object->get_data_store();
|
$data_store = $subscription->get_data_store();
|
||||||
$raw_meta_data = $data_store->read_meta( $object );
|
$raw_meta_data = $data_store->read_meta( $subscription );
|
||||||
$raw_meta_key_map = wp_list_pluck( $raw_meta_data, 'meta_key' );
|
$raw_meta_key_map = wp_list_pluck( $raw_meta_data, 'meta_key' );
|
||||||
|
|
||||||
// Record the object ID so we know that it has been handled in $this->action_object_cache_changes().
|
// Record the object ID so we know that it has been handled in $this->action_object_cache_changes().
|
||||||
$this->object_changes[ $object->get_id() ] = [];
|
$this->object_changes[ $subscription->get_id() ] = [];
|
||||||
|
|
||||||
foreach ( $this->data_keys as $data_key ) {
|
foreach ( $this->data_keys as $data_key ) {
|
||||||
|
|
||||||
// Check if the data key is a base property and if it has changed.
|
// Check if the data key is a base property and if it has changed.
|
||||||
if ( isset( $changes[ $data_key ] ) ) {
|
if ( isset( $changes[ $data_key ] ) ) {
|
||||||
$this->object_changes[ $object->get_id() ][ $data_key ] = [
|
$this->object_changes[ $subscription->get_id() ][ $data_key ] = [
|
||||||
'new' => $changes[ $data_key ],
|
'new' => $changes[ $data_key ],
|
||||||
'previous' => isset( $base_data[ $data_key ] ) ? $base_data[ $data_key ] : null,
|
'previous' => isset( $base_data[ $data_key ] ) ? $base_data[ $data_key ] : null,
|
||||||
'type' => 'update',
|
'type' => 'update',
|
||||||
@@ -117,7 +119,7 @@ class WCS_Object_Data_Cache_Manager extends WCS_Post_Meta_Cache_Manager {
|
|||||||
continue;
|
continue;
|
||||||
} elseif ( isset( $base_data[ $data_key ] ) && $force_all_fields ) {
|
} elseif ( isset( $base_data[ $data_key ] ) && $force_all_fields ) {
|
||||||
// If we're forcing all fields, fetch the base data as the new value.
|
// If we're forcing all fields, fetch the base data as the new value.
|
||||||
$this->object_changes[ $object->get_id() ][ $data_key ] = [
|
$this->object_changes[ $subscription->get_id() ][ $data_key ] = [
|
||||||
'new' => $base_data[ $data_key ],
|
'new' => $base_data[ $data_key ],
|
||||||
'type' => 'add',
|
'type' => 'add',
|
||||||
];
|
];
|
||||||
@@ -135,20 +137,22 @@ class WCS_Object_Data_Cache_Manager extends WCS_Post_Meta_Cache_Manager {
|
|||||||
|
|
||||||
if ( empty( $meta->id ) ) {
|
if ( empty( $meta->id ) ) {
|
||||||
// If the value is being added.
|
// If the value is being added.
|
||||||
$this->object_changes[ $object->get_id() ][ $data_key ] = [
|
$this->object_changes[ $subscription->get_id() ][ $data_key ] = [
|
||||||
'new' => $meta->value,
|
'new' => $meta->value,
|
||||||
'type' => 'add',
|
'type' => 'add',
|
||||||
];
|
];
|
||||||
} elseif ( $meta->get_changes() ) {
|
} elseif ( $meta->get_changes() ) {
|
||||||
// If the value is being updated.
|
// If the value is being updated.
|
||||||
$this->object_changes[ $object->get_id() ][ $data_key ] = [
|
$this->object_changes[ $subscription->get_id() ][ $data_key ] = [
|
||||||
|
// @phpstan-ignore-next-line
|
||||||
'new' => $meta->value,
|
'new' => $meta->value,
|
||||||
'previous' => isset( $previous_meta['value'] ) ? $previous_meta['value'] : null,
|
'previous' => isset( $previous_meta['value'] ) ? $previous_meta['value'] : null,
|
||||||
'type' => 'update',
|
'type' => 'update',
|
||||||
];
|
];
|
||||||
} elseif ( $force_all_fields ) {
|
} elseif ( $force_all_fields ) {
|
||||||
// If we're forcing all fields to be recorded.
|
// If we're forcing all fields to be recorded.
|
||||||
$this->object_changes[ $object->get_id() ][ $data_key ] = [
|
$this->object_changes[ $subscription->get_id() ][ $data_key ] = [
|
||||||
|
// @phpstan-ignore-next-line
|
||||||
'new' => $meta->value,
|
'new' => $meta->value,
|
||||||
'type' => 'add',
|
'type' => 'add',
|
||||||
];
|
];
|
||||||
@@ -159,10 +163,10 @@ class WCS_Object_Data_Cache_Manager extends WCS_Post_Meta_Cache_Manager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If we got this far, then the data key is stored as meta and has been deleted.
|
// If we got this far, then the data key is stored as meta and has been deleted.
|
||||||
// When meta is deleted it won't be returned by $object->get_meta_data(). So we need to check the raw meta data.
|
// When meta is deleted it won't be returned by $subscription->get_meta_data(). So we need to check the raw meta data.
|
||||||
if ( in_array( $data_key, $raw_meta_key_map, true ) ) {
|
if ( in_array( $data_key, $raw_meta_key_map, true ) ) {
|
||||||
$previous_meta = $raw_meta_data[ array_search( $data_key, $raw_meta_key_map, true ) ]->meta_value;
|
$previous_meta = $raw_meta_data[ array_search( $data_key, $raw_meta_key_map, true ) ]->meta_value;
|
||||||
$this->object_changes[ $object->get_id() ][ $data_key ] = [
|
$this->object_changes[ $subscription->get_id() ][ $data_key ] = [
|
||||||
'previous' => $previous_meta,
|
'previous' => $previous_meta,
|
||||||
'type' => 'delete',
|
'type' => 'delete',
|
||||||
];
|
];
|
||||||
@@ -316,7 +320,7 @@ class WCS_Object_Data_Cache_Manager extends WCS_Post_Meta_Cache_Manager {
|
|||||||
/**
|
/**
|
||||||
* Fetches an instance of the object with the given ID.
|
* Fetches an instance of the object with the given ID.
|
||||||
*
|
*
|
||||||
* @param int $object_id The ID of the object to fetch.
|
* @param int $id The ID of the object to fetch.
|
||||||
*
|
*
|
||||||
* @return mixed The object instance, or null if it doesn't exist.
|
* @return mixed The object instance, or null if it doesn't exist.
|
||||||
*/
|
*/
|
||||||
|
@@ -55,8 +55,8 @@ class WCS_Payment_Tokens extends WC_Payment_Tokens {
|
|||||||
/**
|
/**
|
||||||
* Enable third-party plugins to run their own updates and filter whether the token was updated or not.
|
* Enable third-party plugins to run their own updates and filter whether the token was updated or not.
|
||||||
*
|
*
|
||||||
* @param bool Whether the token was updated. Default is true.
|
* @param bool $updated Whether the token was updated. Default is true.
|
||||||
* @param WC_Subscription $subscription
|
* @param WC_Subscription $subscription
|
||||||
* @param WC_Payment_Token $new_token
|
* @param WC_Payment_Token $new_token
|
||||||
* @param WC_Payment_Token $old_token
|
* @param WC_Payment_Token $old_token
|
||||||
*/
|
*/
|
||||||
@@ -137,13 +137,13 @@ class WCS_Payment_Tokens extends WC_Payment_Tokens {
|
|||||||
/**
|
/**
|
||||||
* Get a list of customer payment tokens. Caches results to avoid multiple database queries per request
|
* Get a list of customer payment tokens. Caches results to avoid multiple database queries per request
|
||||||
*
|
*
|
||||||
* @param int (optional) The customer id - defaults to the current user.
|
* @param int $customer_id (optional) The customer id - defaults to the current user.
|
||||||
* @param string (optional) Gateway ID for getting tokens for a specific gateway.
|
* @param string $gateway_id (optional) Gateway ID for getting tokens for a specific gateway.
|
||||||
* @return array of WC_Payment_Token objects.
|
* @return array of WC_Payment_Token objects.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.7
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.7
|
||||||
*/
|
*/
|
||||||
public static function get_customer_tokens( $customer_id = '', $gateway_id = '' ) {
|
public static function get_customer_tokens( $customer_id = 0, $gateway_id = '' ) {
|
||||||
if ( '' === $customer_id ) {
|
if ( 0 === $customer_id ) {
|
||||||
$customer_id = get_current_user_id();
|
$customer_id = get_current_user_id();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -22,8 +22,8 @@ class WCS_Post_Meta_Cache_Manager {
|
|||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param string The post type this cache manage acts on.
|
* @param string $post_type The post type this cache manage acts on.
|
||||||
* @param array The post meta keys this cache manager should act on.
|
* @param array $meta_keys The post meta keys this cache manager should act on.
|
||||||
*/
|
*/
|
||||||
public function __construct( $post_type, $meta_keys ) {
|
public function __construct( $post_type, $meta_keys ) {
|
||||||
$this->post_type = $post_type;
|
$this->post_type = $post_type;
|
||||||
@@ -48,10 +48,10 @@ class WCS_Post_Meta_Cache_Manager {
|
|||||||
add_action( 'deleted_post_meta', array( $this, 'meta_deleted' ), 10, 4 );
|
add_action( 'deleted_post_meta', array( $this, 'meta_deleted' ), 10, 4 );
|
||||||
|
|
||||||
// Special handling for meta updates containing a previous order ID to make sure we also delete any previously linked relationship
|
// Special handling for meta updates containing a previous order ID to make sure we also delete any previously linked relationship
|
||||||
add_action( 'update_post_metadata', array( $this, 'meta_updated_with_previous' ), 10, 5 );
|
add_filter( 'update_post_metadata', array( $this, 'meta_updated_with_previous' ), 10, 5 );
|
||||||
|
|
||||||
// Special handling for meta deletion on all posts/orders, not a specific post/order ID
|
// Special handling for meta deletion on all posts/orders, not a specific post/order ID
|
||||||
add_action( 'delete_post_metadata', array( $this, 'meta_deleted_all' ), 100, 5 );
|
add_filter( 'delete_post_metadata', array( $this, 'meta_deleted_all' ), 100, 5 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -117,7 +117,7 @@ class WCS_Query extends WC_Query {
|
|||||||
/**
|
/**
|
||||||
* Insert the new endpoint into the My Account menu.
|
* Insert the new endpoint into the My Account menu.
|
||||||
*
|
*
|
||||||
* @param array $items
|
* @param array $menu_items
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function add_menu_items( $menu_items ) {
|
public function add_menu_items( $menu_items ) {
|
||||||
@@ -281,8 +281,8 @@ class WCS_Query extends WC_Query {
|
|||||||
/**
|
/**
|
||||||
* Add UI option for changing Subscription endpoints in WC settings
|
* Add UI option for changing Subscription endpoints in WC settings
|
||||||
*
|
*
|
||||||
* @param mixed $account_settings
|
* @param mixed $settings
|
||||||
* @return mixed $account_settings
|
* @return mixed $settings
|
||||||
*/
|
*/
|
||||||
public function add_endpoint_account_settings( $settings ) {
|
public function add_endpoint_account_settings( $settings ) {
|
||||||
$subscriptions_endpoint_setting = array(
|
$subscriptions_endpoint_setting = array(
|
||||||
|
@@ -69,14 +69,14 @@ class WCS_Remove_Item {
|
|||||||
public static function maybe_remove_or_add_item_to_subscription() {
|
public static function maybe_remove_or_add_item_to_subscription() {
|
||||||
|
|
||||||
if ( isset( $_GET['subscription_id'] ) && ( isset( $_GET['remove_item'] ) || isset( $_GET['undo_remove_item'] ) ) && isset( $_GET['_wpnonce'] ) ) {
|
if ( isset( $_GET['subscription_id'] ) && ( isset( $_GET['remove_item'] ) || isset( $_GET['undo_remove_item'] ) ) && isset( $_GET['_wpnonce'] ) ) {
|
||||||
|
$subscription_id = wc_clean( wp_unslash( $_GET['subscription_id'] ) );
|
||||||
$subscription = wcs_is_subscription( $_GET['subscription_id'] ) ? wcs_get_subscription( $_GET['subscription_id'] ) : false;
|
$subscription = wcs_get_subscription( $subscription_id );
|
||||||
$undo_request = isset( $_GET['undo_remove_item'] );
|
$undo_request = isset( $_GET['undo_remove_item'] );
|
||||||
$item_id = $undo_request ? $_GET['undo_remove_item'] : $_GET['remove_item'];
|
$item_id = wc_clean( wp_unslash( $undo_request ? $_GET['undo_remove_item'] : $_GET['remove_item'] ) );
|
||||||
|
|
||||||
if ( false === $subscription ) {
|
if ( false === $subscription ) {
|
||||||
// translators: %d: subscription ID.
|
// translators: %d: subscription ID.
|
||||||
wc_add_notice( sprintf( _x( 'Subscription #%d does not exist.', 'hash before subscription ID', 'woocommerce-subscriptions' ), $_GET['subscription_id'] ), 'error' );
|
wc_add_notice( sprintf( _x( 'Subscription #%d does not exist.', 'hash before subscription ID', 'woocommerce-subscriptions' ), $subscription_id ), 'error' );
|
||||||
wp_safe_redirect( wc_get_page_permalink( 'myaccount' ) );
|
wp_safe_redirect( wc_get_page_permalink( 'myaccount' ) );
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
@@ -175,7 +175,7 @@ class WCS_Remove_Item {
|
|||||||
$subscription_items = $subscription->get_items();
|
$subscription_items = $subscription->get_items();
|
||||||
$response = false;
|
$response = false;
|
||||||
|
|
||||||
if ( ! wp_verify_nonce( $_GET['_wpnonce'], $_GET['subscription_id'] ) ) {
|
if ( ! wp_verify_nonce( wc_clean( wp_unslash( $_GET['_wpnonce'] ) ), wc_clean( wp_unslash( $_GET['subscription_id'] ) ) ) ) {
|
||||||
|
|
||||||
wc_add_notice( __( 'Security error. Please contact us if you need assistance.', 'woocommerce-subscriptions' ), 'error' );
|
wc_add_notice( __( 'Security error. Please contact us if you need assistance.', 'woocommerce-subscriptions' ), 'error' );
|
||||||
|
|
||||||
|
@@ -72,7 +72,7 @@ class WCS_Select2 {
|
|||||||
$value = wcs_json_encode( $value );
|
$value = wcs_json_encode( $value );
|
||||||
}
|
}
|
||||||
|
|
||||||
$html[] = $this->get_property_name( $property ) . '="' . esc_attr( $value, 'woocommerce-subscriptions' ) . '"';
|
$html[] = $this->get_property_name( $property ) . '="' . esc_attr( $value ) . '"';
|
||||||
}
|
}
|
||||||
|
|
||||||
return implode( ' ', $html );
|
return implode( ' ', $html );
|
||||||
@@ -87,6 +87,7 @@ class WCS_Select2 {
|
|||||||
$allowed_attributes = array_map( array( $this, 'get_property_name' ), array_keys( $this->attributes ) );
|
$allowed_attributes = array_map( array( $this, 'get_property_name' ), array_keys( $this->attributes ) );
|
||||||
$allowed_attributes = array_fill_keys( $allowed_attributes, array() );
|
$allowed_attributes = array_fill_keys( $allowed_attributes, array() );
|
||||||
|
|
||||||
|
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
echo wp_kses_allow_underscores(
|
echo wp_kses_allow_underscores(
|
||||||
$this->get_html(),
|
$this->get_html(),
|
||||||
array(
|
array(
|
||||||
|
@@ -107,7 +107,7 @@ class WCS_Staging {
|
|||||||
|
|
||||||
if ( self::is_duplicate_site() && current_user_can( 'manage_options' ) ) {
|
if ( self::is_duplicate_site() && current_user_can( 'manage_options' ) ) {
|
||||||
|
|
||||||
if ( ! empty( $_REQUEST['_wcsnonce'] ) && wp_verify_nonce( $_REQUEST['_wcsnonce'], 'wcs_duplicate_site' ) && isset( $_GET['wc_subscription_duplicate_site'] ) ) {
|
if ( ! empty( $_REQUEST['_wcsnonce'] ) && wp_verify_nonce( wc_clean( wp_unslash( $_REQUEST['_wcsnonce'] ) ), 'wcs_duplicate_site' ) && isset( $_GET['wc_subscription_duplicate_site'] ) ) {
|
||||||
|
|
||||||
if ( 'update' === $_GET['wc_subscription_duplicate_site'] ) {
|
if ( 'update' === $_GET['wc_subscription_duplicate_site'] ) {
|
||||||
|
|
||||||
|
@@ -367,7 +367,7 @@ class WCS_Template_Loader {
|
|||||||
* @param string $template_name
|
* @param string $template_name
|
||||||
* @param array $args
|
* @param array $args
|
||||||
* @param string $template_path
|
* @param string $template_path
|
||||||
* @param
|
* @param string $default_path
|
||||||
*/
|
*/
|
||||||
public static function handle_relocated_templates( $template, $template_name, $args, $template_path, $default_path ) {
|
public static function handle_relocated_templates( $template, $template_name, $args, $template_path, $default_path ) {
|
||||||
// We only want to relocate subscription template files that can't be found.
|
// We only want to relocate subscription template files that can't be found.
|
||||||
|
@@ -28,9 +28,9 @@ class WCS_User_Change_Status_Handler {
|
|||||||
if ( isset( $_GET['change_subscription_to'], $_GET['subscription_id'], $_GET['_wpnonce'] ) && ! empty( $_GET['_wpnonce'] ) ) {
|
if ( isset( $_GET['change_subscription_to'], $_GET['subscription_id'], $_GET['_wpnonce'] ) && ! empty( $_GET['_wpnonce'] ) ) {
|
||||||
$user_id = get_current_user_id();
|
$user_id = get_current_user_id();
|
||||||
$subscription = wcs_get_subscription( absint( $_GET['subscription_id'] ) );
|
$subscription = wcs_get_subscription( absint( $_GET['subscription_id'] ) );
|
||||||
$new_status = wc_clean( $_GET['change_subscription_to'] );
|
$new_status = wc_clean( wp_unslash( $_GET['change_subscription_to'] ) );
|
||||||
|
|
||||||
if ( self::validate_request( $user_id, $subscription, $new_status, $_GET['_wpnonce'] ) ) {
|
if ( self::validate_request( $user_id, $subscription, $new_status, wc_clean( wp_unslash( $_GET['_wpnonce'] ) ) ) ) {
|
||||||
self::change_users_subscription( $subscription, $new_status );
|
self::change_users_subscription( $subscription, $new_status );
|
||||||
|
|
||||||
wp_safe_redirect( $subscription->get_view_order_url() );
|
wp_safe_redirect( $subscription->get_view_order_url() );
|
||||||
@@ -45,6 +45,7 @@ class WCS_User_Change_Status_Handler {
|
|||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
public static function change_users_subscription( $subscription, $new_status ) {
|
public static function change_users_subscription( $subscription, $new_status ) {
|
||||||
|
/** @var WC_Subscription $subscription */
|
||||||
$subscription = ( ! is_object( $subscription ) ) ? wcs_get_subscription( $subscription ) : $subscription;
|
$subscription = ( ! is_object( $subscription ) ) ? wcs_get_subscription( $subscription ) : $subscription;
|
||||||
$changed = false;
|
$changed = false;
|
||||||
|
|
||||||
|
@@ -317,7 +317,7 @@ class WCS_Customer_Store_Cached_CPT extends WCS_Customer_Store_CPT implements WC
|
|||||||
/**
|
/**
|
||||||
* Run the update for a single item.
|
* Run the update for a single item.
|
||||||
*
|
*
|
||||||
* @param mixed $item The item to update.
|
* @param mixed $user_id The user ID to update.
|
||||||
*/
|
*/
|
||||||
public function update_items_cache( $user_id ) {
|
public function update_items_cache( $user_id ) {
|
||||||
// Getting the subscription IDs also sets the cache when it's not already set
|
// Getting the subscription IDs also sets the cache when it's not already set
|
||||||
|
@@ -30,7 +30,7 @@ class WCS_Orders_Table_Data_Store_Controller {
|
|||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function init_hooks() {
|
public function init_hooks() {
|
||||||
add_filter( 'woocommerce_subscription_data_store', array( $this, 'get_orders_table_data_store' ), 10, 2 );
|
add_filter( 'woocommerce_subscription_data_store', array( $this, 'get_orders_table_data_store' ), 10 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -58,7 +58,7 @@ class WCS_Orders_Table_Subscription_Data_Store extends \Automattic\WooCommerce\I
|
|||||||
*
|
*
|
||||||
* All columns are inherited from orders except the `transaction_id` column isn't used for subscriptions.
|
* All columns are inherited from orders except the `transaction_id` column isn't used for subscriptions.
|
||||||
*
|
*
|
||||||
* @var \string[][]
|
* @var string[]
|
||||||
*/
|
*/
|
||||||
protected $order_column_mapping = array(
|
protected $order_column_mapping = array(
|
||||||
'id' => array(
|
'id' => array(
|
||||||
@@ -139,7 +139,7 @@ class WCS_Orders_Table_Subscription_Data_Store extends \Automattic\WooCommerce\I
|
|||||||
* - recorded_sales
|
* - recorded_sales
|
||||||
* - date_completed_gmt
|
* - date_completed_gmt
|
||||||
*
|
*
|
||||||
* @var \string[][]
|
* @var string[]
|
||||||
*/
|
*/
|
||||||
protected $operational_data_column_mapping = array(
|
protected $operational_data_column_mapping = array(
|
||||||
'id' => array( 'type' => 'int' ),
|
'id' => array( 'type' => 'int' ),
|
||||||
@@ -337,7 +337,7 @@ class WCS_Orders_Table_Subscription_Data_Store extends \Automattic\WooCommerce\I
|
|||||||
/**
|
/**
|
||||||
* Attempts to restore the specified subscription back to its original status (after having been trashed).
|
* Attempts to restore the specified subscription back to its original status (after having been trashed).
|
||||||
*
|
*
|
||||||
* @param \WC_Subscription $order The order to be untrashed.
|
* @param \WC_Subscription $subscription The subscription to be untrashed.
|
||||||
*
|
*
|
||||||
* @return bool If the operation was successful.
|
* @return bool If the operation was successful.
|
||||||
*/
|
*/
|
||||||
@@ -593,6 +593,7 @@ class WCS_Orders_Table_Subscription_Data_Store extends \Automattic\WooCommerce\I
|
|||||||
$is_date_prop = ( 'schedule_' === substr( $prop, 0, 9 ) );
|
$is_date_prop = ( 'schedule_' === substr( $prop, 0, 9 ) );
|
||||||
|
|
||||||
if ( $is_date_prop ) {
|
if ( $is_date_prop ) {
|
||||||
|
// @phpstan-ignore method.notFound
|
||||||
$meta_value = $subscription->get_date( $prop );
|
$meta_value = $subscription->get_date( $prop );
|
||||||
} else {
|
} else {
|
||||||
$meta_value = $subscription->{"get_$prop"}( 'edit' );
|
$meta_value = $subscription->{"get_$prop"}( 'edit' );
|
||||||
@@ -612,6 +613,7 @@ class WCS_Orders_Table_Subscription_Data_Store extends \Automattic\WooCommerce\I
|
|||||||
if ( empty( $existing_meta_data ) ) {
|
if ( empty( $existing_meta_data ) ) {
|
||||||
// If we're saving a start date for the first time and it's empty, set it to the created date as a default.
|
// If we're saving a start date for the first time and it's empty, set it to the created date as a default.
|
||||||
if ( '_schedule_start' === $new_meta_data['key'] && empty( $new_meta_data['value'] ) ) {
|
if ( '_schedule_start' === $new_meta_data['key'] && empty( $new_meta_data['value'] ) ) {
|
||||||
|
// @phpstan-ignore method.notFound
|
||||||
$new_meta_data['value'] = $subscription->get_date( 'date_created' );
|
$new_meta_data['value'] = $subscription->get_date( 'date_created' );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -626,7 +628,7 @@ class WCS_Orders_Table_Subscription_Data_Store extends \Automattic\WooCommerce\I
|
|||||||
/**
|
/**
|
||||||
* Initializes the subscription based on data received from the database.
|
* Initializes the subscription based on data received from the database.
|
||||||
*
|
*
|
||||||
* @param WC_Abstract_Order $subscription The subscription object.
|
* @param WC_Subscription $subscription The subscription object.
|
||||||
* @param int $subscription_id The subscription's ID.
|
* @param int $subscription_id The subscription's ID.
|
||||||
* @param stdClass $subscription_data All the subscription's data, retrieved from the database.
|
* @param stdClass $subscription_data All the subscription's data, retrieved from the database.
|
||||||
*/
|
*/
|
||||||
@@ -643,8 +645,8 @@ class WCS_Orders_Table_Subscription_Data_Store extends \Automattic\WooCommerce\I
|
|||||||
|
|
||||||
// Set subscription specific properties that we store in meta.
|
// Set subscription specific properties that we store in meta.
|
||||||
$meta_data = wp_list_pluck( $subscription_data->meta_data, 'meta_value', 'meta_key' );
|
$meta_data = wp_list_pluck( $subscription_data->meta_data, 'meta_value', 'meta_key' );
|
||||||
$dates_to_set = [];
|
$dates_to_set = array();
|
||||||
$props_to_set = [];
|
$props_to_set = array();
|
||||||
|
|
||||||
foreach ( $this->subscription_meta_keys_to_props as $meta_key => $prop_key ) {
|
foreach ( $this->subscription_meta_keys_to_props as $meta_key => $prop_key ) {
|
||||||
$is_scheduled_date = 0 === strpos( $prop_key, 'schedule' );
|
$is_scheduled_date = 0 === strpos( $prop_key, 'schedule' );
|
||||||
@@ -657,6 +659,7 @@ class WCS_Orders_Table_Subscription_Data_Store extends \Automattic\WooCommerce\I
|
|||||||
|
|
||||||
// If we're reading in the start date and it's missing, set it in memory to the created date.
|
// If we're reading in the start date and it's missing, set it in memory to the created date.
|
||||||
if ( 'schedule_start' === $prop_key && empty( $meta_data[ $meta_key ] ) ) {
|
if ( 'schedule_start' === $prop_key && empty( $meta_data[ $meta_key ] ) ) {
|
||||||
|
// @phpstan-ignore method.notFound
|
||||||
$meta_data[ $meta_key ] = $subscription->get_date( 'date_created' );
|
$meta_data[ $meta_key ] = $subscription->get_date( 'date_created' );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -673,8 +676,9 @@ class WCS_Orders_Table_Subscription_Data_Store extends \Automattic\WooCommerce\I
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set the dates and props.
|
// Set the dates and props.
|
||||||
if ( $dates_to_set ) {
|
if ( $dates_to_set && $subscription instanceof \WC_Subscription ) {
|
||||||
$subscription->update_dates( $dates_to_set );
|
// @phpstan-ignore method.notFound
|
||||||
|
$subscription->update_valid_dates( $dates_to_set );
|
||||||
}
|
}
|
||||||
|
|
||||||
$subscription->set_props( $props_to_set );
|
$subscription->set_props( $props_to_set );
|
||||||
@@ -784,6 +788,7 @@ class WCS_Orders_Table_Subscription_Data_Store extends \Automattic\WooCommerce\I
|
|||||||
$existing_meta_data = $subscription_meta_data[ $meta_key ] ?? false;
|
$existing_meta_data = $subscription_meta_data[ $meta_key ] ?? false;
|
||||||
$new_meta_data = [
|
$new_meta_data = [
|
||||||
'key' => $meta_key,
|
'key' => $meta_key,
|
||||||
|
// @phpstan-ignore method.notFound
|
||||||
'value' => $subscription->get_date( $date_type ),
|
'value' => $subscription->get_date( $date_type ),
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -794,6 +799,7 @@ class WCS_Orders_Table_Subscription_Data_Store extends \Automattic\WooCommerce\I
|
|||||||
$this->data_store_meta->add_meta( $subscription, (object) $new_meta_data );
|
$this->data_store_meta->add_meta( $subscription, (object) $new_meta_data );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @phpstan-ignore method.notFound
|
||||||
$dates_saved[ $date_prop ] = wcs_get_datetime_from( $subscription->get_time( $date_type ) );
|
$dates_saved[ $date_prop ] = wcs_get_datetime_from( $subscription->get_time( $date_type ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -835,7 +841,7 @@ class WCS_Orders_Table_Subscription_Data_Store extends \Automattic\WooCommerce\I
|
|||||||
*
|
*
|
||||||
* This function is hooked onto the 'woocommerce_order_table_search_query_meta_keys' filter.
|
* This function is hooked onto the 'woocommerce_order_table_search_query_meta_keys' filter.
|
||||||
*
|
*
|
||||||
* @param array The default order search fields.
|
* @param array $search_fields The default order search fields.
|
||||||
*
|
*
|
||||||
* @return array The subscription search fields.
|
* @return array The subscription search fields.
|
||||||
*/
|
*/
|
||||||
|
@@ -147,6 +147,7 @@ class WCS_Related_Order_Store_Cached_CPT extends WCS_Related_Order_Store_CPT imp
|
|||||||
*/
|
*/
|
||||||
public function get_related_order_ids( WC_Order $subscription, $relation_type ) {
|
public function get_related_order_ids( WC_Order $subscription, $relation_type ) {
|
||||||
$related_order_ids = $this->get_related_order_ids_from_cache( $subscription, $relation_type );
|
$related_order_ids = $this->get_related_order_ids_from_cache( $subscription, $relation_type );
|
||||||
|
$transient_key = null;
|
||||||
|
|
||||||
// get_related_order_ids_from_cache() returns false if the ID is invalid. This can arise when the subscription hasn't been created yet. In any case, the related IDs should be an empty array to avoid a boolean return from this function.
|
// get_related_order_ids_from_cache() returns false if the ID is invalid. This can arise when the subscription hasn't been created yet. In any case, the related IDs should be an empty array to avoid a boolean return from this function.
|
||||||
if ( false === $related_order_ids ) {
|
if ( false === $related_order_ids ) {
|
||||||
@@ -219,8 +220,8 @@ class WCS_Related_Order_Store_Cached_CPT extends WCS_Related_Order_Store_CPT imp
|
|||||||
/**
|
/**
|
||||||
* Finds orders related to a given subscription in a given way from the cache.
|
* Finds orders related to a given subscription in a given way from the cache.
|
||||||
*
|
*
|
||||||
* @param WC_Subscription|int $subscription_id The Subscription ID or subscription object to fetch related orders.
|
* @param WC_Subscription|int $subscription The subscription to fetch related orders.
|
||||||
* @param string $relation_type The relationship between the subscription and the orders. Must be 'renewal', 'switch' or 'resubscribe.
|
* @param string $relation_type The relationship between the subscription and the orders. Must be 'renewal', 'switch' or 'resubscribe.
|
||||||
*
|
*
|
||||||
* @return string|array An array of related orders in the cache, or an empty string when no matching row is found for the given key, meaning it's cache is not set yet or has been deleted
|
* @return string|array An array of related orders in the cache, or an empty string when no matching row is found for the given key, meaning it's cache is not set yet or has been deleted
|
||||||
*/
|
*/
|
||||||
@@ -388,7 +389,7 @@ class WCS_Related_Order_Store_Cached_CPT extends WCS_Related_Order_Store_CPT imp
|
|||||||
/**
|
/**
|
||||||
* Clears all related order caches for a given subscription.
|
* Clears all related order caches for a given subscription.
|
||||||
*
|
*
|
||||||
* @param WC_Subscription|int $subscription_id The ID of a subscription that may have linked orders.
|
* @param WC_Subscription|int $subscription The subscription that may have linked orders.
|
||||||
* @param string $relation_type The relationship between the subscription and the order. Must be 'renewal', 'switch' or 'resubscribe' unless custom relationships are implemented. Use 'any' to delete all cached.
|
* @param string $relation_type The relationship between the subscription and the order. Must be 'renewal', 'switch' or 'resubscribe' unless custom relationships are implemented. Use 'any' to delete all cached.
|
||||||
*/
|
*/
|
||||||
public function delete_caches_for_subscription( $subscription, $relation_type = 'any' ) {
|
public function delete_caches_for_subscription( $subscription, $relation_type = 'any' ) {
|
||||||
|
@@ -187,6 +187,7 @@ class WCS_Subscription_Data_Store_CPT extends WC_Order_Data_Store_CPT implements
|
|||||||
$date_type = str_replace( 'schedule_', '', $prop_key );
|
$date_type = str_replace( 'schedule_', '', $prop_key );
|
||||||
|
|
||||||
if ( 'start' === $date_type && ! $meta_value ) {
|
if ( 'start' === $date_type && ! $meta_value ) {
|
||||||
|
// @phpstan-ignore method.notFound
|
||||||
$meta_value = $subscription->get_date( 'date_created' );
|
$meta_value = $subscription->get_date( 'date_created' );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,6 +213,7 @@ class WCS_Subscription_Data_Store_CPT extends WC_Order_Data_Store_CPT implements
|
|||||||
$props_to_set['customer_id'] = $subscription->get_meta( '_customer_user', true );
|
$props_to_set['customer_id'] = $subscription->get_meta( '_customer_user', true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @phpstan-ignore method.notFound
|
||||||
$subscription->update_dates( $dates_to_set );
|
$subscription->update_dates( $dates_to_set );
|
||||||
$subscription->set_props( $props_to_set );
|
$subscription->set_props( $props_to_set );
|
||||||
}
|
}
|
||||||
@@ -341,7 +343,7 @@ class WCS_Subscription_Data_Store_CPT extends WC_Order_Data_Store_CPT implements
|
|||||||
/**
|
/**
|
||||||
* Return count of subscriptions with type.
|
* Return count of subscriptions with type.
|
||||||
*
|
*
|
||||||
* @param string $type
|
* @param string $status
|
||||||
* @return int
|
* @return int
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0
|
||||||
*/
|
*/
|
||||||
@@ -562,18 +564,21 @@ class WCS_Subscription_Data_Store_CPT extends WC_Order_Data_Store_CPT implements
|
|||||||
|
|
||||||
$subscription_ids = array_unique( array_merge(
|
$subscription_ids = array_unique( array_merge(
|
||||||
$wpdb->get_col(
|
$wpdb->get_col(
|
||||||
$wpdb->prepare( "
|
$wpdb->prepare(
|
||||||
SELECT DISTINCT p1.post_id
|
// phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.LikeWildcardsInQueryWithPlaceholder
|
||||||
FROM {$wpdb->postmeta} p1
|
"SELECT DISTINCT p1.post_id FROM {$wpdb->postmeta} p1 WHERE p1.meta_value LIKE '%%%s%%'",
|
||||||
WHERE p1.meta_value LIKE '%%%s%%'", $wpdb->esc_like( wc_clean( $term ) ) ) . " AND p1.meta_key IN ('" . implode( "','", array_map( 'esc_sql', $search_fields ) ) . "')"
|
$wpdb->esc_like(
|
||||||
|
wc_clean( $term )
|
||||||
|
)
|
||||||
|
) . " AND p1.meta_key IN ('" . implode( "','", array_map( 'esc_sql', $search_fields ) ) . "')"
|
||||||
),
|
),
|
||||||
$wpdb->get_col(
|
$wpdb->get_col(
|
||||||
$wpdb->prepare( "
|
$wpdb->prepare( "
|
||||||
SELECT order_id
|
SELECT order_id
|
||||||
FROM {$wpdb->prefix}woocommerce_order_items as order_items
|
FROM {$wpdb->prefix}woocommerce_order_items as order_items
|
||||||
WHERE order_item_name LIKE '%%%s%%'
|
WHERE order_item_name LIKE %s
|
||||||
",
|
",
|
||||||
$wpdb->esc_like( wc_clean( $term ) )
|
'%' . $wpdb->esc_like( wc_clean( $term ) ) . '%'
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
$wpdb->get_col(
|
$wpdb->get_col(
|
||||||
@@ -582,11 +587,11 @@ class WCS_Subscription_Data_Store_CPT extends WC_Order_Data_Store_CPT implements
|
|||||||
FROM {$wpdb->posts} p1
|
FROM {$wpdb->posts} p1
|
||||||
INNER JOIN {$wpdb->postmeta} p2 ON p1.ID = p2.post_id
|
INNER JOIN {$wpdb->postmeta} p2 ON p1.ID = p2.post_id
|
||||||
INNER JOIN {$wpdb->users} u ON p2.meta_value = u.ID
|
INNER JOIN {$wpdb->users} u ON p2.meta_value = u.ID
|
||||||
WHERE u.user_email LIKE '%%%s%%'
|
WHERE u.user_email LIKE %s
|
||||||
AND p2.meta_key = '_customer_user'
|
AND p2.meta_key = '_customer_user'
|
||||||
AND p1.post_type = 'shop_subscription'
|
AND p1.post_type = 'shop_subscription'
|
||||||
",
|
",
|
||||||
esc_attr( $term )
|
'%' . $wpdb->esc_like( wc_clean( $term ) ) . '%'
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
$subscription_ids
|
$subscription_ids
|
||||||
|
@@ -163,8 +163,7 @@ class WCS_Filter_Deprecator extends WCS_Hook_Deprecator {
|
|||||||
$original_id = self::get_order_id( $subscription );
|
$original_id = self::get_order_id( $subscription );
|
||||||
|
|
||||||
// Now we need to find the new orders role, if the calling function is wcs_create_resubscribe_order(), the role is parent, otherwise it's child
|
// Now we need to find the new orders role, if the calling function is wcs_create_resubscribe_order(), the role is parent, otherwise it's child
|
||||||
$backtrace = debug_backtrace();
|
$order_role = 'child';
|
||||||
$order_role = ( 'wcs_create_resubscribe_order' == $backtrace[1]['function'] ) ? 'parent' : 'child';
|
|
||||||
|
|
||||||
// Old arg spec: $order_items, $original_order_id, $renewal_order_id, $product_id, $new_order_role
|
// Old arg spec: $order_items, $original_order_id, $renewal_order_id, $product_id, $new_order_role
|
||||||
if ( 'woocommerce_subscriptions_renewal_order_items' == $old_hook ) {
|
if ( 'woocommerce_subscriptions_renewal_order_items' == $old_hook ) {
|
||||||
@@ -195,9 +194,7 @@ class WCS_Filter_Deprecator extends WCS_Hook_Deprecator {
|
|||||||
$renewal_order = $new_callback_args[0];
|
$renewal_order = $new_callback_args[0];
|
||||||
$subscription = $new_callback_args[1];
|
$subscription = $new_callback_args[1];
|
||||||
|
|
||||||
// Now we need to find the new orders role, if the calling function is wcs_create_resubscribe_order(), the role is parent, otherwise it's child
|
$order_role = 'child';
|
||||||
$backtrace = debug_backtrace();
|
|
||||||
$order_role = ( 'wcs_create_resubscribe_order' == $backtrace[1]['function'] ) ? 'parent' : 'child';
|
|
||||||
|
|
||||||
$renewal_order_id = apply_filters( $old_hook, $return_value->id, self::get_order( $subscription ), self::get_product_id( $subscription ), $order_role );
|
$renewal_order_id = apply_filters( $old_hook, $return_value->id, self::get_order( $subscription ), self::get_product_id( $subscription ), $order_role );
|
||||||
|
|
||||||
|
@@ -98,7 +98,7 @@ class WC_Subscriptions_Core_Payment_Gateways {
|
|||||||
} elseif (
|
} elseif (
|
||||||
! wcs_cart_contains_renewal() &&
|
! wcs_cart_contains_renewal() &&
|
||||||
! WC_Subscriptions_Cart::cart_contains_subscription() &&
|
! WC_Subscriptions_Cart::cart_contains_subscription() &&
|
||||||
( ! isset( $_GET['order_id'] ) || ! wcs_order_contains_subscription( $_GET['order_id'] ) )
|
( ! isset( $_GET['order_id'] ) || ! wcs_order_contains_subscription( wc_clean( wp_unslash( $_GET['order_id'] ) ) ) )
|
||||||
) {
|
) {
|
||||||
return $available_gateways;
|
return $available_gateways;
|
||||||
}
|
}
|
||||||
@@ -115,8 +115,6 @@ class WC_Subscriptions_Core_Payment_Gateways {
|
|||||||
/**
|
/**
|
||||||
* Check the content of the cart and add required payment methods.
|
* Check the content of the cart and add required payment methods.
|
||||||
*
|
*
|
||||||
* @param array $features of required features for the cart checkout.
|
|
||||||
*
|
|
||||||
* @return array list of features required by cart items.
|
* @return array list of features required by cart items.
|
||||||
*/
|
*/
|
||||||
public static function inject_payment_feature_requirements_for_cart_api() {
|
public static function inject_payment_feature_requirements_for_cart_api() {
|
||||||
@@ -327,7 +325,7 @@ class WC_Subscriptions_Core_Payment_Gateways {
|
|||||||
*
|
*
|
||||||
* @param string $title Widget title.
|
* @param string $title Widget title.
|
||||||
* @param array $instance Array of widget data.
|
* @param array $instance Array of widget data.
|
||||||
* @param string $widget ID/name of the widget being displayed.
|
* @param string $widget_id ID/name of the widget being displayed.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
@@ -346,7 +344,7 @@ class WC_Subscriptions_Core_Payment_Gateways {
|
|||||||
*
|
*
|
||||||
* @param string $title Widget title.
|
* @param string $title Widget title.
|
||||||
* @param array $instance Array of widget data.
|
* @param array $instance Array of widget data.
|
||||||
* @param string $widget ID/name of the widget being displayed.
|
* @param string $widget_id ID/name of the widget being displayed.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
|
@@ -51,8 +51,8 @@ class WC_Subscriptions_Gateway_Restrictions_Manager {
|
|||||||
*
|
*
|
||||||
* @since 1.5.0
|
* @since 1.5.0
|
||||||
*
|
*
|
||||||
* @param false|float The minimum amount that can be processed in the given currency.
|
* @param false|float $minimum_processable_amount The minimum amount that can be processed in the given currency.
|
||||||
* @param string The currency.
|
* @param string $currency The currency.
|
||||||
*/
|
*/
|
||||||
$minimum_processable_amount = apply_filters( 'woocommerce_subscriptions_minimum_processable_recurring_amount', false, get_woocommerce_currency() );
|
$minimum_processable_amount = apply_filters( 'woocommerce_subscriptions_minimum_processable_recurring_amount', false, get_woocommerce_currency() );
|
||||||
|
|
||||||
@@ -68,4 +68,3 @@ class WC_Subscriptions_Gateway_Restrictions_Manager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -208,7 +208,7 @@ class WCS_PayPal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get token to retrieve checkout details with
|
// get token to retrieve checkout details with
|
||||||
$token = esc_attr( $_GET['token'] );
|
$token = wc_clean( wp_unslash( $_GET['token'] ) );
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
@@ -284,7 +284,7 @@ class WCS_PayPal {
|
|||||||
|
|
||||||
wc_add_notice( __( 'An error occurred, please try again or try an alternate form of payment.', 'woocommerce-subscriptions' ), 'error' );
|
wc_add_notice( __( 'An error occurred, please try again or try an alternate form of payment.', 'woocommerce-subscriptions' ), 'error' );
|
||||||
|
|
||||||
wp_redirect( wc_get_cart_url() );
|
wp_safe_redirect( wc_get_cart_url() );
|
||||||
}
|
}
|
||||||
|
|
||||||
exit;
|
exit;
|
||||||
|
@@ -299,7 +299,7 @@ abstract class WCS_SV_API_Base {
|
|||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v4.1.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v4.1.0
|
||||||
* @param string $uri current request URI
|
* @param string $uri current request URI
|
||||||
* @param \WCS_SV_API_Base class instance
|
* @param \WCS_SV_API_Base $this class instance
|
||||||
*/
|
*/
|
||||||
return apply_filters( 'wc_' . $this->get_api_id() . '_api_request_uri', $uri, $this );
|
return apply_filters( 'wc_' . $this->get_api_id() . '_api_request_uri', $uri, $this );
|
||||||
}
|
}
|
||||||
@@ -335,7 +335,7 @@ abstract class WCS_SV_API_Base {
|
|||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0
|
||||||
* @param array $args request arguments
|
* @param array $args request arguments
|
||||||
* @param \WCS_SV_API_Base class instance
|
* @param \WCS_SV_API_Base $this class instance
|
||||||
*/
|
*/
|
||||||
return apply_filters( 'wc_' . $this->get_api_id() . '_http_request_args', $args, $this );
|
return apply_filters( 'wc_' . $this->get_api_id() . '_http_request_args', $args, $this );
|
||||||
}
|
}
|
||||||
|
@@ -71,7 +71,7 @@ class WCS_PayPal_Admin {
|
|||||||
*/
|
*/
|
||||||
public static function maybe_check_account() {
|
public static function maybe_check_account() {
|
||||||
|
|
||||||
if ( isset( $_GET['wcs_paypal'] ) && 'check_reference_transaction_support' === $_GET['wcs_paypal'] && wp_verify_nonce( $_GET['_wpnonce'], __CLASS__ ) ) {
|
if ( isset( $_GET['wcs_paypal'] ) && 'check_reference_transaction_support' === $_GET['wcs_paypal'] && wp_verify_nonce( wc_clean( wp_unslash( $_GET['_wpnonce'] ) ), __CLASS__ ) ) {
|
||||||
|
|
||||||
$redirect_url = remove_query_arg( array( 'wcs_paypal', '_wpnonce' ) );
|
$redirect_url = remove_query_arg( array( 'wcs_paypal', '_wpnonce' ) );
|
||||||
|
|
||||||
@@ -237,7 +237,7 @@ class WCS_PayPal_Admin {
|
|||||||
public static function maybe_update_credentials_error_flag() {
|
public static function maybe_update_credentials_error_flag() {
|
||||||
|
|
||||||
// Check if the API credentials are being saved - we can't do this on the 'woocommerce_update_options_payment_gateways_paypal' hook because it is triggered after 'admin_notices'
|
// Check if the API credentials are being saved - we can't do this on the 'woocommerce_update_options_payment_gateways_paypal' hook because it is triggered after 'admin_notices'
|
||||||
if ( ! empty( $_REQUEST['_wpnonce'] ) && wp_verify_nonce( $_REQUEST['_wpnonce'], 'woocommerce-settings' ) && isset( $_POST['woocommerce_paypal_api_username'] ) || isset( $_POST['woocommerce_paypal_api_password'] ) || isset( $_POST['woocommerce_paypal_api_signature'] ) ) {
|
if ( ! empty( $_REQUEST['_wpnonce'] ) && wp_verify_nonce( wc_clean( wp_unslash( $_REQUEST['_wpnonce'] ) ), 'woocommerce-settings' ) && ( isset( $_POST['woocommerce_paypal_api_username'] ) || isset( $_POST['woocommerce_paypal_api_password'] ) || isset( $_POST['woocommerce_paypal_api_signature'] ) ) ) {
|
||||||
|
|
||||||
$credentials_updated = false;
|
$credentials_updated = false;
|
||||||
|
|
||||||
|
@@ -675,7 +675,7 @@ class WCS_PayPal_Reference_Transaction_API_Request {
|
|||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v3.3.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v3.3.0
|
||||||
* @param bool $skip_line_items True if line items should be skipped, false otherwise
|
* @param bool $skip_line_items True if line items should be skipped, false otherwise
|
||||||
* @param WC_Order/null $order The WC_Order object or null.
|
* @param WC_Order|null $order The WC_Order object or null.
|
||||||
*/
|
*/
|
||||||
return apply_filters( 'wcs_paypal_reference_transaction_skip_line_items', $skip_line_items, $order );
|
return apply_filters( 'wcs_paypal_reference_transaction_skip_line_items', $skip_line_items, $order );
|
||||||
}
|
}
|
||||||
|
@@ -678,8 +678,8 @@ class WCS_PayPal_Standard_IPN_Handler extends WC_Gateway_Paypal_IPN_Handler {
|
|||||||
* Used when switching payment methods with PayPal Standard to make sure that
|
* Used when switching payment methods with PayPal Standard to make sure that
|
||||||
* the old subscription's profile ID is cancelled, not the new one.
|
* the old subscription's profile ID is cancelled, not the new one.
|
||||||
*
|
*
|
||||||
* @param WC_Subscription A subscription object
|
* @param WC_Subscription $subscription A subscription object
|
||||||
* @param string A PayPal Subscription Profile ID
|
* @param string $old_paypal_subscriber_id A PayPal Subscription Profile ID
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
protected static function cancel_subscription( $subscription, $old_paypal_subscriber_id ) {
|
protected static function cancel_subscription( $subscription, $old_paypal_subscriber_id ) {
|
||||||
@@ -733,9 +733,9 @@ class WCS_PayPal_Standard_IPN_Handler extends WC_Gateway_Paypal_IPN_Handler {
|
|||||||
/**
|
/**
|
||||||
* Get an order associated with a subscription that has a specified transaction id.
|
* Get an order associated with a subscription that has a specified transaction id.
|
||||||
*
|
*
|
||||||
* @param WC_Subscription object $subscription
|
* @param WC_Subscription $subscription
|
||||||
* @param int $transaction_id Id from transaction details as provided by PayPal
|
* @param int $transaction_id Id from transaction details as provided by PayPal
|
||||||
* @param array|string Order type we want. Defaults to any.
|
* @param array|string $order_types Order type we want. Defaults to any.
|
||||||
*
|
*
|
||||||
* @return WC_Order|null If order with that transaction id, WC_Order object, otherwise null
|
* @return WC_Order|null If order with that transaction id, WC_Order object, otherwise null
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.4.3
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.4.3
|
||||||
@@ -757,7 +757,7 @@ class WCS_PayPal_Standard_IPN_Handler extends WC_Gateway_Paypal_IPN_Handler {
|
|||||||
/**
|
/**
|
||||||
* Get a renewal order associated with a subscription that has a specified transaction id.
|
* Get a renewal order associated with a subscription that has a specified transaction id.
|
||||||
*
|
*
|
||||||
* @param WC_Subscription object $subscription
|
* @param WC_Subscription $subscription
|
||||||
* @param int $transaction_id Id from transaction details as provided by PayPal
|
* @param int $transaction_id Id from transaction details as provided by PayPal
|
||||||
* @return WC_Order|null If order with that transaction id, WC_Order object, otherwise null
|
* @return WC_Order|null If order with that transaction id, WC_Order object, otherwise null
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.1
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.1
|
||||||
@@ -769,7 +769,7 @@ class WCS_PayPal_Standard_IPN_Handler extends WC_Gateway_Paypal_IPN_Handler {
|
|||||||
/**
|
/**
|
||||||
* Get a parent order associated with a subscription that has a specified transaction id.
|
* Get a parent order associated with a subscription that has a specified transaction id.
|
||||||
*
|
*
|
||||||
* @param WC_Subscription object $subscription
|
* @param WC_Subscription $subscription
|
||||||
* @param int $transaction_id Id from transaction details as provided by PayPal
|
* @param int $transaction_id Id from transaction details as provided by PayPal
|
||||||
*
|
*
|
||||||
* @return WC_Order|null If order with that transaction id, WC_Order object, otherwise null
|
* @return WC_Order|null If order with that transaction id, WC_Order object, otherwise null
|
||||||
|
@@ -226,7 +226,7 @@ class WCS_PayPal_Standard_Switcher {
|
|||||||
*/
|
*/
|
||||||
public static function get_available_payment_gateways( $available_gateways ) {
|
public static function get_available_payment_gateways( $available_gateways ) {
|
||||||
|
|
||||||
if ( ! is_wc_endpoint_url( 'order-pay' ) && ( wcs_cart_contains_switches() || ( isset( $_GET['order_id'] ) && wcs_order_contains_switch( $_GET['order_id'] ) ) ) ) {
|
if ( ! is_wc_endpoint_url( 'order-pay' ) && ( wcs_cart_contains_switches() || ( isset( $_GET['order_id'] ) && wcs_order_contains_switch( wc_clean( wp_unslash( $_GET['order_id'] ) ) ) ) ) ) {
|
||||||
foreach ( $available_gateways as $gateway_id => $gateway ) {
|
foreach ( $available_gateways as $gateway_id => $gateway ) {
|
||||||
if ( 'paypal' == $gateway_id && false == WCS_PayPal::are_reference_transactions_enabled() ) {
|
if ( 'paypal' == $gateway_id && false == WCS_PayPal::are_reference_transactions_enabled() ) {
|
||||||
unset( $available_gateways[ $gateway_id ] );
|
unset( $available_gateways[ $gateway_id ] );
|
||||||
|
@@ -91,10 +91,11 @@ class WC_PayPal_Standard_Subscriptions {
|
|||||||
/**
|
/**
|
||||||
* Returns a PayPal Subscription ID/Recurring Payment Profile ID based on a user ID and subscription key
|
* Returns a PayPal Subscription ID/Recurring Payment Profile ID based on a user ID and subscription key
|
||||||
*
|
*
|
||||||
* @param WC_Order|WC_Subscription A WC_Order object or child object (i.e. WC_Subscription)
|
* @param WC_Order|WC_Subscription $order_id A WC_Order object or child object (i.e. WC_Subscription)
|
||||||
|
* @param int $product_id The product ID.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.1
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.1
|
||||||
*/
|
*/
|
||||||
public static function get_subscriptions_paypal_id( $order_id, $product_id = '' ) {
|
public static function get_subscriptions_paypal_id( $order_id, $product_id = 0 ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'wcs_get_paypal_id( $order_id )' );
|
_deprecated_function( __METHOD__, '2.0', 'wcs_get_paypal_id( $order_id )' );
|
||||||
return wcs_get_paypal_id( $order_id );
|
return wcs_get_paypal_id( $order_id );
|
||||||
}
|
}
|
||||||
@@ -176,9 +177,12 @@ class WC_PayPal_Standard_Subscriptions {
|
|||||||
/**
|
/**
|
||||||
* When a store manager or user cancels a subscription in the store, also cancel the subscription with PayPal.
|
* When a store manager or user cancels a subscription in the store, also cancel the subscription with PayPal.
|
||||||
*
|
*
|
||||||
|
* @param WC_Order $order A WC_Order object.
|
||||||
|
* @param int $product_id The ID of the product.
|
||||||
|
* @param string $profile_id The ID of the profile.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.1
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.1
|
||||||
*/
|
*/
|
||||||
public static function cancel_subscription_with_paypal( $order, $product_id = '', $profile_id = '' ) {
|
public static function cancel_subscription_with_paypal( $order, $product_id = 0, $profile_id = '' ) {
|
||||||
_deprecated_function( __METHOD__, '2.0', 'WCS_PayPal_Status_Manager::cancel_subscription( $subscription )' );
|
_deprecated_function( __METHOD__, '2.0', 'WCS_PayPal_Status_Manager::cancel_subscription( $subscription )' );
|
||||||
foreach ( wcs_get_subscriptions_for_order( $order, array( 'order_type' => 'parent' ) ) as $subscription ) {
|
foreach ( wcs_get_subscriptions_for_order( $order, array( 'order_type' => 'parent' ) ) as $subscription ) {
|
||||||
self::change_subscription_status( $profile_id, 'Cancel', $subscription );
|
self::change_subscription_status( $profile_id, 'Cancel', $subscription );
|
||||||
|
@@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
/**
|
/**
|
||||||
* Returns a PayPal Subscription ID or Billing Agreement ID use to process payment for a given subscription or order.
|
* Returns a PayPal Subscription ID or Billing Agreement ID use to process payment for a given subscription or order.
|
||||||
*
|
*
|
||||||
* @param int The ID of a WC_Order or WC_Subscription object
|
* @param int|object $order The ID of a WC_Order or WC_Subscription object
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
function wcs_get_paypal_id( $order ) {
|
function wcs_get_paypal_id( $order ) {
|
||||||
@@ -32,8 +32,8 @@ function wcs_get_paypal_id( $order ) {
|
|||||||
/**
|
/**
|
||||||
* Stores a PayPal Standard Subscription ID or Billing Agreement ID in the post meta of a given order and the user meta of the order's user.
|
* Stores a PayPal Standard Subscription ID or Billing Agreement ID in the post meta of a given order and the user meta of the order's user.
|
||||||
*
|
*
|
||||||
* @param int|object A WC_Order or WC_Subscription object or the ID of a WC_Order or WC_Subscription object
|
* @param int|WC_Order|WC_Subscription $order A WC_Order or WC_Subscription object or the ID of a WC_Order or WC_Subscription object
|
||||||
* @param string A PayPal Standard Subscription ID or Express Checkout Billing Agreement ID
|
* @param string $paypal_subscription_id A PayPal Standard Subscription ID or Express Checkout Billing Agreement ID
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
function wcs_set_paypal_id( $order, $paypal_subscription_id ) {
|
function wcs_set_paypal_id( $order, $paypal_subscription_id ) {
|
||||||
@@ -65,6 +65,8 @@ function wcs_set_paypal_id( $order, $paypal_subscription_id ) {
|
|||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
function wcs_is_paypal_profile_a( $profile_id, $profile_type ) {
|
function wcs_is_paypal_profile_a( $profile_id, $profile_type ) {
|
||||||
|
$profile_id = (string) $profile_id;
|
||||||
|
$profile_type = (string) $profile_type;
|
||||||
|
|
||||||
if ( 'billing_agreement' === $profile_type && 'B-' == substr( $profile_id, 0, 2 ) ) {
|
if ( 'billing_agreement' === $profile_type && 'B-' == substr( $profile_id, 0, 2 ) ) {
|
||||||
$is_a = true;
|
$is_a = true;
|
||||||
@@ -160,9 +162,8 @@ function wcs_calculate_paypal_trial_periods_until( $future_timestamp ) {
|
|||||||
* like from WC_Subscriptions_Product::is_purchasable() and WC_Product_Subscription_Variation::is_purchasable(),
|
* like from WC_Subscriptions_Product::is_purchasable() and WC_Product_Subscription_Variation::is_purchasable(),
|
||||||
* both of which are called within WC_Cart::get_cart_from_session(), which is run before query vars are setup.
|
* both of which are called within WC_Cart::get_cart_from_session(), which is run before query vars are setup.
|
||||||
*
|
*
|
||||||
* @return 2.0.13
|
|
||||||
* @return bool
|
* @return bool
|
||||||
**/
|
**/
|
||||||
function wcs_is_paypal_api_page() {
|
function wcs_is_paypal_api_page() {
|
||||||
return ( false !== strpos( $_SERVER['REQUEST_URI'], 'wc-api/wcs_paypal' ) );
|
return ( false !== strpos( wc_clean( wp_unslash( $_SERVER['REQUEST_URI'] ) ), 'wc-api/wcs_paypal' ) );
|
||||||
}
|
}
|
||||||
|
@@ -210,10 +210,10 @@ class WC_Product_Variable_Subscription_Legacy extends WC_Product_Variable_Subscr
|
|||||||
/**
|
/**
|
||||||
* Sync variable product prices with the children lowest/highest prices.
|
* Sync variable product prices with the children lowest/highest prices.
|
||||||
*
|
*
|
||||||
* @access public
|
* @param int $product_id The ID of the product.
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function variable_product_sync( $product_id = '' ) {
|
public function variable_product_sync( $product_id = 0 ) {
|
||||||
|
|
||||||
WC_Product_Variable::variable_product_sync( $product_id );
|
WC_Product_Variable::variable_product_sync( $product_id );
|
||||||
|
|
||||||
|
@@ -62,7 +62,7 @@ class WCS_Privacy_Background_Updater {
|
|||||||
* Schedule subscription related order anonymization, if it's not already scheduled.
|
* Schedule subscription related order anonymization, if it's not already scheduled.
|
||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.20
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.20
|
||||||
* @param int The subscription ID.
|
* @param int $subscription_id The subscription ID.
|
||||||
*/
|
*/
|
||||||
protected function schedule_subscription_orders_anonymization( $subscription_id ) {
|
protected function schedule_subscription_orders_anonymization( $subscription_id ) {
|
||||||
$action_args = array( 'subscription_id' => intval( $subscription_id ) );
|
$action_args = array( 'subscription_id' => intval( $subscription_id ) );
|
||||||
@@ -76,7 +76,7 @@ class WCS_Privacy_Background_Updater {
|
|||||||
* Unschedule a specific subscription's related order anonymization hook.
|
* Unschedule a specific subscription's related order anonymization hook.
|
||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.20
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.20
|
||||||
* @param int The subscription ID.
|
* @param int $subscription_id The subscription ID.
|
||||||
*/
|
*/
|
||||||
protected function unschedule_subscription_orders_anonymization( $subscription_id ) {
|
protected function unschedule_subscription_orders_anonymization( $subscription_id ) {
|
||||||
as_unschedule_action( $this->subscription_orders_anonymization_hook, array( 'subscription_id' => intval( $subscription_id ) ) );
|
as_unschedule_action( $this->subscription_orders_anonymization_hook, array( 'subscription_id' => intval( $subscription_id ) ) );
|
||||||
@@ -86,7 +86,7 @@ class WCS_Privacy_Background_Updater {
|
|||||||
* Schedule a specific order's anonymization action.
|
* Schedule a specific order's anonymization action.
|
||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.20
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.20
|
||||||
* @param int The order ID.
|
* @param int $order_id The order ID.
|
||||||
*/
|
*/
|
||||||
protected function schedule_order_anonymization( $order_id ) {
|
protected function schedule_order_anonymization( $order_id ) {
|
||||||
as_schedule_single_action( time(), $this->order_anonymization_hook, array( 'order_id' => intval( $order_id ) ) );
|
as_schedule_single_action( time(), $this->order_anonymization_hook, array( 'order_id' => intval( $order_id ) ) );
|
||||||
@@ -96,7 +96,7 @@ class WCS_Privacy_Background_Updater {
|
|||||||
* Check if an order has a scheduled anonymization action.
|
* Check if an order has a scheduled anonymization action.
|
||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.20
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.20
|
||||||
* @param int The order ID.
|
* @param int $order_id The order ID.
|
||||||
* @return bool Whether the order has a scheduled anonymization action.
|
* @return bool Whether the order has a scheduled anonymization action.
|
||||||
*/
|
*/
|
||||||
protected function order_anonymization_is_scheduled( $order_id ) {
|
protected function order_anonymization_is_scheduled( $order_id ) {
|
||||||
@@ -209,7 +209,7 @@ class WCS_Privacy_Background_Updater {
|
|||||||
/**
|
/**
|
||||||
* Anonymize an order.
|
* Anonymize an order.
|
||||||
*
|
*
|
||||||
* @param int The ID of the order to be anonymized.
|
* @param int $order_id The ID of the order to be anonymized.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.20
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.20
|
||||||
*/
|
*/
|
||||||
public function anonymize_order( $order_id ) {
|
public function anonymize_order( $order_id ) {
|
||||||
|
@@ -161,7 +161,7 @@ class WCS_Privacy_Erasers {
|
|||||||
* Expose a way to control the anonymized value of a prop via 3rd party code.
|
* Expose a way to control the anonymized value of a prop via 3rd party code.
|
||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.20
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.20
|
||||||
* @param bool $anonymized_data Value of this prop after anonymization.
|
* @param string $anonymized_data Value of this prop after anonymization.
|
||||||
* @param string $prop Name of the prop being removed.
|
* @param string $prop Name of the prop being removed.
|
||||||
* @param string $value Current value of the data.
|
* @param string $value Current value of the data.
|
||||||
* @param string $data_type Type of data.
|
* @param string $data_type Type of data.
|
||||||
|
@@ -69,10 +69,10 @@ class WCS_Privacy extends WC_Abstract_Privacy {
|
|||||||
add_filter( 'woocommerce_account_settings', array( __CLASS__, 'add_subscription_data_retention_settings' ) );
|
add_filter( 'woocommerce_account_settings', array( __CLASS__, 'add_subscription_data_retention_settings' ) );
|
||||||
|
|
||||||
// Attach callbacks to prevent subscription related orders being trashed or anonymized
|
// Attach callbacks to prevent subscription related orders being trashed or anonymized
|
||||||
add_filter( 'woocommerce_trash_pending_orders_query_args', array( __CLASS__, 'remove_subscription_orders_from_anonymization_query' ), 10, 2 );
|
add_filter( 'woocommerce_trash_pending_orders_query_args', array( __CLASS__, 'remove_subscription_orders_from_anonymization_query' ) );
|
||||||
add_filter( 'woocommerce_trash_failed_orders_query_args', array( __CLASS__, 'remove_subscription_orders_from_anonymization_query' ), 10, 2 );
|
add_filter( 'woocommerce_trash_failed_orders_query_args', array( __CLASS__, 'remove_subscription_orders_from_anonymization_query' ) );
|
||||||
add_filter( 'woocommerce_trash_cancelled_orders_query_args', array( __CLASS__, 'remove_subscription_orders_from_anonymization_query' ), 10, 2 );
|
add_filter( 'woocommerce_trash_cancelled_orders_query_args', array( __CLASS__, 'remove_subscription_orders_from_anonymization_query' ) );
|
||||||
add_filter( 'woocommerce_anonymize_completed_orders_query_args', array( __CLASS__, 'remove_subscription_orders_from_anonymization_query' ), 10, 2 );
|
add_filter( 'woocommerce_anonymize_completed_orders_query_args', array( __CLASS__, 'remove_subscription_orders_from_anonymization_query' ) );
|
||||||
|
|
||||||
add_action( 'woocommerce_cleanup_personal_data', array( $this, 'queue_cleanup_personal_data' ) );
|
add_action( 'woocommerce_cleanup_personal_data', array( $this, 'queue_cleanup_personal_data' ) );
|
||||||
|
|
||||||
|
@@ -8,29 +8,58 @@
|
|||||||
* the data be upgraded to the new schema without hassle. A hassle could easily occur if 100,000 orders were being
|
* the data be upgraded to the new schema without hassle. A hassle could easily occur if 100,000 orders were being
|
||||||
* modified - memory exhaustion, script time out etc.
|
* modified - memory exhaustion, script time out etc.
|
||||||
*
|
*
|
||||||
|
* ⚠️ Since 7.7.0, when triggering migrations and upgrade routines we should reference self::$active_plugin_version
|
||||||
|
* (which corresponds with the actual plugin version) and not self::$active_core_library_version (which is the
|
||||||
|
* Subscriptions Core library version, and therefore a historic side-effect of a time when development was split
|
||||||
|
* across two repositories).
|
||||||
|
*
|
||||||
* @author Prospress
|
* @author Prospress
|
||||||
* @category Admin
|
* @category Admin
|
||||||
* @package WooCommerce Subscriptions/Admin/Upgrades
|
* @package WooCommerce Subscriptions/Admin/Upgrades
|
||||||
* @version 1.0.0 - Migrated from WooCommerce Subscriptions v2.0.0
|
* @version 1.0.0 - Migrated from WooCommerce Subscriptions v2.0.0
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
|
* @since 7.7.0 Added support for upgrades based on the plugin version number, as opposed to the core library version number.
|
||||||
*/
|
*/
|
||||||
class WC_Subscriptions_Upgrader {
|
class WC_Subscriptions_Upgrader {
|
||||||
|
/**
|
||||||
|
* @var string The database-persisted version number of the Subscriptions Core framework. Retained to support historic migrations.
|
||||||
|
* @since 7.7.0
|
||||||
|
*/
|
||||||
|
private static string $stored_core_library_version;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string The database version of Subscriptions.
|
* @var string The database-persisted version number of WooCommerce Subscriptions.
|
||||||
|
* @since 7.7.0
|
||||||
*/
|
*/
|
||||||
private static $active_version;
|
private static string $stored_plugin_version;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if plugin upgrade routines should potentially be triggered.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
* @since 7.7.0
|
||||||
|
*/
|
||||||
|
private static bool $plugin_upgrades_may_be_needed = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string The minimum supported version that this class can upgrade from.
|
* @var string The minimum supported version that this class can upgrade from.
|
||||||
*/
|
*/
|
||||||
private static $minimum_supported_version = '3.0';
|
private static $minimum_supported_version = '3.0';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if core library upgrade routines should potentially be triggered.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
* @since 7.7.0
|
||||||
|
*/
|
||||||
|
private static bool $core_library_upgrades_may_be_needed = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array An array of WCS_Background_Updater objects used to run upgrade scripts in the background.
|
* @var array An array of WCS_Background_Updater objects used to run upgrade scripts in the background.
|
||||||
*/
|
*/
|
||||||
protected static $background_updaters = array();
|
protected static $background_updaters = array();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deprecated variables.
|
* Deprecated variables.
|
||||||
*
|
*
|
||||||
@@ -49,12 +78,14 @@ class WC_Subscriptions_Upgrader {
|
|||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
*/
|
*/
|
||||||
public static function init() {
|
public static function init() {
|
||||||
self::$active_version = get_option( WC_Subscriptions_Admin::$option_prefix . '_active_version', '0' );
|
self::$stored_core_library_version = (string) get_option( WC_Subscriptions_Admin::$option_prefix . '_active_version', '0' );
|
||||||
self::$about_page_url = admin_url( 'admin.php?page=wc-admin' );
|
self::$stored_plugin_version = (string) get_option( WC_Subscriptions::PLUGIN_VERSION_OPTION_NAME, '0' );
|
||||||
$version_out_of_date = version_compare( self::$active_version, WC_Subscriptions_Core_Plugin::instance()->get_library_version(), '<' );
|
self::$about_page_url = admin_url( 'admin.php?page=wc-admin' );
|
||||||
|
self::$plugin_upgrades_may_be_needed = version_compare( self::$stored_plugin_version, WC_Subscriptions::$version, '<' );
|
||||||
|
self::$core_library_upgrades_may_be_needed = version_compare( self::$stored_core_library_version, WC_Subscriptions_Core_Plugin::instance()->get_library_version(), '<' );
|
||||||
|
|
||||||
// Show warning that upgrades are no longer supported.
|
// Show warning that upgrades are no longer supported.
|
||||||
if ( '0' !== self::$active_version && version_compare( self::$active_version, self::$minimum_supported_version, '<=' ) ) {
|
if ( '0' !== self::$stored_core_library_version && version_compare( self::$stored_core_library_version, self::$minimum_supported_version, '<=' ) ) {
|
||||||
add_action(
|
add_action(
|
||||||
'admin_notices',
|
'admin_notices',
|
||||||
function () {
|
function () {
|
||||||
@@ -64,7 +95,7 @@ class WC_Subscriptions_Upgrader {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( @current_user_can( 'activate_plugins' ) && $version_out_of_date ) { // phpcs:ignore WordPress.PHP.NoSilencedErrors
|
if ( @current_user_can( 'activate_plugins' ) && ( self::$plugin_upgrades_may_be_needed || self::$core_library_upgrades_may_be_needed ) ) { // phpcs:ignore WordPress.PHP.NoSilencedErrors
|
||||||
// Run upgrades as soon as admin hits site
|
// Run upgrades as soon as admin hits site
|
||||||
add_action( 'wp_loaded', [ __CLASS__, 'upgrade' ], 11 );
|
add_action( 'wp_loaded', [ __CLASS__, 'upgrade' ], 11 );
|
||||||
}
|
}
|
||||||
@@ -78,16 +109,53 @@ class WC_Subscriptions_Upgrader {
|
|||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.2
|
||||||
*/
|
*/
|
||||||
public static function upgrade() {
|
public static function upgrade() {
|
||||||
global $wpdb;
|
update_option( WC_Subscriptions_Admin::$option_prefix . '_previous_version', self::$stored_core_library_version );
|
||||||
|
update_option( WC_Subscriptions::PLUGIN_VERSION_OPTION_NAME . '_previous', self::$stored_plugin_version );
|
||||||
update_option( WC_Subscriptions_Admin::$option_prefix . '_previous_version', self::$active_version );
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* before upgrade hook.
|
* Runs before the plugin upgrade process begins.
|
||||||
|
*
|
||||||
|
* Note that, since 7.7.0, the plugin version and active plugin version are the values we are most intereted in.
|
||||||
|
* The core library and active core library version numbers are retained to support migrations from historic
|
||||||
|
* versions of the plugin.
|
||||||
|
*
|
||||||
|
* @since 7.7.0 Added $plugin_version and $active_plugin_version.
|
||||||
|
*
|
||||||
|
* @param string $core_library_version The current Subscriptions Core library version number.
|
||||||
|
* @param string $stored_core_library_version The database-persisted Subscriptions Core library version number (what we are updating from).
|
||||||
|
* @param string $plugin_version The current plugin version number.
|
||||||
|
* @param string $stored_plugin_version The database-persisted plugin version number (what we are updating from).
|
||||||
*/
|
*/
|
||||||
do_action( 'woocommerce_subscriptions_before_upgrade', WC_Subscriptions_Core_Plugin::instance()->get_library_version(), self::$active_version );
|
do_action(
|
||||||
|
'woocommerce_subscriptions_before_upgrade',
|
||||||
|
WC_Subscriptions_Core_Plugin::instance()->get_library_version(),
|
||||||
|
self::$stored_core_library_version,
|
||||||
|
WC_Subscriptions::$version,
|
||||||
|
self::$stored_plugin_version,
|
||||||
|
);
|
||||||
|
|
||||||
if ( '0' === self::$active_version ) {
|
if ( self::$core_library_upgrades_may_be_needed ) {
|
||||||
|
self::legacy_core_library_upgrades();
|
||||||
|
}
|
||||||
|
|
||||||
|
self::plugin_upgrades();
|
||||||
|
self::upgrade_complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method contains migrations for changes introduced before WooCommerce Subscriptions 7.7.0.
|
||||||
|
*
|
||||||
|
* The version numbers tested here are core library version numbers. For any new migrations or upgrade routines,
|
||||||
|
* we should use the actual plugin version number. This boils down to one simple rule:
|
||||||
|
*
|
||||||
|
* ⚠️ New migrations/upgrade routines should not be added to this method.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private static function legacy_core_library_upgrades(): void {
|
||||||
|
global $wpdb;
|
||||||
|
|
||||||
|
if ( '0' === self::$stored_core_library_version ) {
|
||||||
// Update the hold stock notification to be one week (if it's still at the default 60 minutes) to prevent cancelling subscriptions using manual renewals and payment methods that can take more than 1 hour (i.e. PayPal eCheck)
|
// Update the hold stock notification to be one week (if it's still at the default 60 minutes) to prevent cancelling subscriptions using manual renewals and payment methods that can take more than 1 hour (i.e. PayPal eCheck)
|
||||||
$hold_stock_duration = get_option( 'woocommerce_hold_stock_minutes' );
|
$hold_stock_duration = get_option( 'woocommerce_hold_stock_minutes' );
|
||||||
|
|
||||||
@@ -106,39 +174,53 @@ class WC_Subscriptions_Upgrader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Delete old subscription period string ranges transients.
|
// Delete old subscription period string ranges transients.
|
||||||
if ( version_compare( self::$active_version, '3.0.10', '<' ) ) {
|
if ( version_compare( self::$stored_core_library_version, '3.0.10', '<' ) ) {
|
||||||
$deleted_rows = $wpdb->query( "DELETE FROM {$wpdb->options} WHERE `option_name` LIKE '_transient_timeout_wcs-sub-ranges-%' OR `option_name` LIKE '_transient_wcs-sub-ranges-%'" );
|
$deleted_rows = $wpdb->query( "DELETE FROM {$wpdb->options} WHERE `option_name` LIKE '_transient_timeout_wcs-sub-ranges-%' OR `option_name` LIKE '_transient_wcs-sub-ranges-%'" );
|
||||||
}
|
}
|
||||||
|
|
||||||
// When upgrading from version 3.0.12, delete `switch_totals_calc_base_length` meta from product post meta as it was saved rather than set in memory.
|
// When upgrading from version 3.0.12, delete `switch_totals_calc_base_length` meta from product post meta as it was saved rather than set in memory.
|
||||||
if ( version_compare( self::$active_version, '3.0.12', '==' ) ) {
|
if ( version_compare( self::$stored_core_library_version, '3.0.12', '==' ) ) {
|
||||||
$deleted_rows = $wpdb->query( "DELETE FROM {$wpdb->postmeta} WHERE `meta_key` = '_switch_totals_calc_base_length'" );
|
$deleted_rows = $wpdb->query( "DELETE FROM {$wpdb->postmeta} WHERE `meta_key` = '_switch_totals_calc_base_length'" );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( version_compare( self::$active_version, '3.1.0', '<' ) ) {
|
if ( version_compare( self::$stored_core_library_version, '3.1.0', '<' ) ) {
|
||||||
// Upon upgrading to 3.1.0 from a version after 3.0.10, repair subscriptions _subtracted_base_location_tax line item meta.
|
// Upon upgrading to 3.1.0 from a version after 3.0.10, repair subscriptions _subtracted_base_location_tax line item meta.
|
||||||
if ( version_compare( self::$active_version, '3.0.10', '>=' ) ) {
|
if ( version_compare( self::$stored_core_library_version, '3.0.10', '>=' ) ) {
|
||||||
self::$background_updaters['3.1']['subtracted_base_tax_repair']->schedule_repair();
|
self::$background_updaters['3.1']['subtracted_base_tax_repair']->schedule_repair();
|
||||||
}
|
}
|
||||||
|
|
||||||
WCS_Upgrade_3_1_0::migrate_subscription_webhooks_using_api_version_3();
|
WCS_Upgrade_3_1_0::migrate_subscription_webhooks_using_api_version_3();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( version_compare( self::$active_version, '6.8.0', '<' ) ) {
|
if ( version_compare( self::$stored_core_library_version, '6.8.0', '<' ) ) {
|
||||||
// Upon upgrading to 6.8.0 delete the 'wcs_cleanup_big_logs' WP Cron job that is no longer used.
|
// Upon upgrading to 6.8.0 delete the 'wcs_cleanup_big_logs' WP Cron job that is no longer used.
|
||||||
wp_unschedule_hook( 'wcs_cleanup_big_logs' );
|
wp_unschedule_hook( 'wcs_cleanup_big_logs' );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( version_compare( self::$active_version, '8.0.0', '<' ) ) {
|
if ( version_compare( self::$stored_core_library_version, '8.0.0', '<' ) ) {
|
||||||
// As of Subscriptions 7.2.0 (Core 8.0.0), admin notices are stored one transient per-user.
|
// As of Subscriptions 7.2.0 (Core 8.0.0), admin notices are stored one transient per-user.
|
||||||
delete_transient( '_wcs_admin_notices' );
|
delete_transient( '_wcs_admin_notices' );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( version_compare( self::$active_version, '8.3.0', '<' ) ) {
|
if ( version_compare( self::$stored_core_library_version, '8.3.0', '<' ) ) {
|
||||||
WCS_Upgrade_8_3_0::migrate_subscription_email_templates();
|
WCS_Upgrade_8_3_0::migrate_subscription_email_templates();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self::upgrade_complete();
|
/**
|
||||||
|
* Plugin upgrades should be triggered from this method.
|
||||||
|
*
|
||||||
|
* Here is an example of doing some work when the user updates to 8.0.0:
|
||||||
|
*
|
||||||
|
* if ( version_compare( self::$stored_plugin_version, '8.0.0', '<' ) ) {
|
||||||
|
* self::do_something_when_updating_to_8_0_0();
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private static function plugin_upgrades(): void {
|
||||||
|
// This method is currently just a placeholder. Once we're ready to add a migration in a future release, this
|
||||||
|
// comment can of course be deleted.
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -148,7 +230,29 @@ class WC_Subscriptions_Upgrader {
|
|||||||
*/
|
*/
|
||||||
public static function upgrade_complete() {
|
public static function upgrade_complete() {
|
||||||
update_option( WC_Subscriptions_Admin::$option_prefix . '_active_version', WC_Subscriptions_Core_Plugin::instance()->get_library_version() );
|
update_option( WC_Subscriptions_Admin::$option_prefix . '_active_version', WC_Subscriptions_Core_Plugin::instance()->get_library_version() );
|
||||||
do_action( 'woocommerce_subscriptions_upgraded', WC_Subscriptions_Core_Plugin::instance()->get_library_version(), self::$active_version );
|
update_option( WC_Subscriptions::PLUGIN_VERSION_OPTION_NAME, WC_Subscriptions::$version );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs after plugin upgrades have been set in motion.
|
||||||
|
*
|
||||||
|
* Note that, since 7.7.0, the plugin version and active plugin version are the values we are most interested in.
|
||||||
|
* The core library and active core library version numbers are retained only to support migrations from historic
|
||||||
|
* versions of the plugin.
|
||||||
|
*
|
||||||
|
* @since 7.7.0 Added $plugin_version and $active_plugin_version.
|
||||||
|
*
|
||||||
|
* @param string $core_library_version The current Subscriptions Core library version number.
|
||||||
|
* @param string $stored_core_library_version The database-persisted Subscriptions Core library version number (what we are updating from).
|
||||||
|
* @param string $plugin_version The current plugin version number.
|
||||||
|
* @param string $stored_plugin_version The database-persisted plugin version number (what we are updating from).
|
||||||
|
*/
|
||||||
|
do_action(
|
||||||
|
'woocommerce_subscriptions_upgraded',
|
||||||
|
WC_Subscriptions_Core_Plugin::instance()->get_library_version(),
|
||||||
|
self::$stored_core_library_version,
|
||||||
|
WC_Subscriptions::$version,
|
||||||
|
self::$stored_plugin_version,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -216,7 +320,7 @@ class WC_Subscriptions_Upgrader {
|
|||||||
// If WC hasn't run the update routine yet we can hook into theirs to update subscriptions, otherwise we'll need to schedule our own update.
|
// If WC hasn't run the update routine yet we can hook into theirs to update subscriptions, otherwise we'll need to schedule our own update.
|
||||||
if ( version_compare( get_option( 'woocommerce_db_version' ), '3.5.0', '<' ) ) {
|
if ( version_compare( get_option( 'woocommerce_db_version' ), '3.5.0', '<' ) ) {
|
||||||
self::$background_updaters['2.4']['subscription_post_author']->hook_into_wc_350_update();
|
self::$background_updaters['2.4']['subscription_post_author']->hook_into_wc_350_update();
|
||||||
} elseif ( version_compare( self::$active_version, '2.4.0', '<' ) ) {
|
} elseif ( version_compare( self::$stored_core_library_version, '2.4.0', '<' ) ) {
|
||||||
self::$background_updaters['2.4']['subscription_post_author']->schedule_repair();
|
self::$background_updaters['2.4']['subscription_post_author']->schedule_repair();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -244,7 +348,7 @@ class WC_Subscriptions_Upgrader {
|
|||||||
wcs_deprecated_function( __METHOD__, '1.2.0' );
|
wcs_deprecated_function( __METHOD__, '1.2.0' );
|
||||||
|
|
||||||
// If there's no downgrade, exit early. self::$active_version is a bit of a misnomer here but in an upgrade context it refers to the database version of the plugin.
|
// If there's no downgrade, exit early. self::$active_version is a bit of a misnomer here but in an upgrade context it refers to the database version of the plugin.
|
||||||
if ( ! version_compare( wcs_get_minor_version_string( self::$active_version ), wcs_get_minor_version_string( WC_Subscriptions_Core_Plugin::instance()->get_library_version() ), '>' ) ) {
|
if ( ! version_compare( wcs_get_minor_version_string( self::$stored_core_library_version ), wcs_get_minor_version_string( WC_Subscriptions_Core_Plugin::instance()->get_library_version() ), '>' ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,7 +359,7 @@ class WC_Subscriptions_Upgrader {
|
|||||||
esc_html__( '%1$sWarning!%2$s It appears that you have downgraded %1$sWooCommerce Subscriptions%2$s from %3$s to %4$s. Downgrading the plugin in this way may cause issues. Please update to %3$s or higher, or %5$sopen a new support ticket%6$s for further assistance. %7$sLearn more »%8$s', 'woocommerce-subscriptions' ),
|
esc_html__( '%1$sWarning!%2$s It appears that you have downgraded %1$sWooCommerce Subscriptions%2$s from %3$s to %4$s. Downgrading the plugin in this way may cause issues. Please update to %3$s or higher, or %5$sopen a new support ticket%6$s for further assistance. %7$sLearn more »%8$s', 'woocommerce-subscriptions' ),
|
||||||
'<strong>',
|
'<strong>',
|
||||||
'</strong>',
|
'</strong>',
|
||||||
'<code>' . self::$active_version . '</code>',
|
'<code>' . self::$stored_core_library_version . '</code>',
|
||||||
'<code>' . WC_Subscriptions_Core_Plugin::instance()->get_library_version() . '</code>',
|
'<code>' . WC_Subscriptions_Core_Plugin::instance()->get_library_version() . '</code>',
|
||||||
'<a href="https://woocommerce.com/my-account/marketplace-ticket-form/" target="_blank">',
|
'<a href="https://woocommerce.com/my-account/marketplace-ticket-form/" target="_blank">',
|
||||||
'</a>',
|
'</a>',
|
||||||
@@ -338,7 +442,7 @@ class WC_Subscriptions_Upgrader {
|
|||||||
private static function ajax_upgrade_handler() {
|
private static function ajax_upgrade_handler() {
|
||||||
wcs_deprecated_function( __METHOD__, 'subscriptions-core 7.7.0' );
|
wcs_deprecated_function( __METHOD__, 'subscriptions-core 7.7.0' );
|
||||||
|
|
||||||
$_GET['wcs_upgrade_step'] = ( ! isset( $_GET['wcs_upgrade_step'] ) ) ? 0 : $_GET['wcs_upgrade_step'];
|
$_GET['wcs_upgrade_step'] = ( ! isset( $_GET['wcs_upgrade_step'] ) ) ? 0 : wc_clean( wp_unslash( $_GET['wcs_upgrade_step'] ) );
|
||||||
|
|
||||||
switch ( (int) $_GET['wcs_upgrade_step'] ) {
|
switch ( (int) $_GET['wcs_upgrade_step'] ) {
|
||||||
case 1:
|
case 1:
|
||||||
@@ -375,7 +479,7 @@ class WC_Subscriptions_Upgrader {
|
|||||||
|
|
||||||
self::set_upgrade_limits();
|
self::set_upgrade_limits();
|
||||||
|
|
||||||
WCS_Upgrade_Logger::add( sprintf( 'Starting upgrade step: %s', $_POST['upgrade_step'] ) );
|
WCS_Upgrade_Logger::add( sprintf( 'Starting upgrade step: %s', wc_clean( wp_unslash( $_POST['upgrade_step'] ) ) ) );
|
||||||
|
|
||||||
if ( ini_get( 'max_execution_time' ) < 600 ) {
|
if ( ini_get( 'max_execution_time' ) < 600 ) {
|
||||||
@set_time_limit( 600 );
|
@set_time_limit( 600 );
|
||||||
@@ -428,7 +532,7 @@ class WC_Subscriptions_Upgrader {
|
|||||||
|
|
||||||
} catch ( Exception $e ) {
|
} catch ( Exception $e ) {
|
||||||
|
|
||||||
WCS_Upgrade_Logger::add( sprintf( 'Error on upgrade step: %s. Error: %s', $_POST['upgrade_step'], $e->getMessage() ) );
|
WCS_Upgrade_Logger::add( sprintf( 'Error on upgrade step: %s. Error: %s', wc_clean( wp_unslash( $_POST['upgrade_step'] ) ), $e->getMessage() ) );
|
||||||
|
|
||||||
$results = array(
|
$results = array(
|
||||||
'upgraded_count' => 0,
|
'upgraded_count' => 0,
|
||||||
@@ -474,7 +578,7 @@ class WC_Subscriptions_Upgrader {
|
|||||||
|
|
||||||
} catch ( Exception $e ) {
|
} catch ( Exception $e ) {
|
||||||
|
|
||||||
WCS_Upgrade_Logger::add( sprintf( 'Error on upgrade step: %s. Error: %s', $_POST['upgrade_step'], $e->getMessage() ) );
|
WCS_Upgrade_Logger::add( sprintf( 'Error on upgrade step: %s. Error: %s', wc_clean( wp_unslash( $_POST['upgrade_step'] ) ), $e->getMessage() ) );
|
||||||
|
|
||||||
$results = array(
|
$results = array(
|
||||||
'repaired_count' => 0,
|
'repaired_count' => 0,
|
||||||
@@ -501,9 +605,10 @@ class WC_Subscriptions_Upgrader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WCS_Upgrade_Logger::add( sprintf( 'Completed upgrade step: %s', $_POST['upgrade_step'] ) );
|
WCS_Upgrade_Logger::add( sprintf( 'Completed upgrade step: %s', wc_clean( wp_unslash( $_POST['upgrade_step'] ) ) ) );
|
||||||
|
|
||||||
header( 'Content-Type: application/json; charset=utf-8' );
|
header( 'Content-Type: application/json; charset=utf-8' );
|
||||||
|
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
echo wcs_json_encode( $results );
|
echo wcs_json_encode( $results );
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
@@ -517,7 +622,7 @@ class WC_Subscriptions_Upgrader {
|
|||||||
private static function upgrade_really_old_versions() {
|
private static function upgrade_really_old_versions() {
|
||||||
wcs_deprecated_function( __METHOD__, 'subscriptions-core 7.7.0' );
|
wcs_deprecated_function( __METHOD__, 'subscriptions-core 7.7.0' );
|
||||||
|
|
||||||
if ( '0' != self::$active_version && version_compare( self::$active_version, '1.2', '<' ) ) {
|
if ( '0' !== self::$stored_core_library_version && version_compare( self::$stored_core_library_version, '1.2', '<' ) ) {
|
||||||
WCS_Upgrade_1_2::init();
|
WCS_Upgrade_1_2::init();
|
||||||
self::generate_renewal_orders();
|
self::generate_renewal_orders();
|
||||||
update_option( WC_Subscriptions_Admin::$option_prefix . '_active_version', '1.2' );
|
update_option( WC_Subscriptions_Admin::$option_prefix . '_active_version', '1.2' );
|
||||||
@@ -525,14 +630,14 @@ class WC_Subscriptions_Upgrader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add Variable Subscription product type term
|
// Add Variable Subscription product type term
|
||||||
if ( '0' != self::$active_version && version_compare( self::$active_version, '1.3', '<' ) ) {
|
if ( '0' !== self::$stored_core_library_version && version_compare( self::$stored_core_library_version, '1.3', '<' ) ) {
|
||||||
WCS_Upgrade_1_3::init();
|
WCS_Upgrade_1_3::init();
|
||||||
update_option( WC_Subscriptions_Admin::$option_prefix . '_active_version', '1.3' );
|
update_option( WC_Subscriptions_Admin::$option_prefix . '_active_version', '1.3' );
|
||||||
$upgraded_versions .= '1.3 & ';
|
$upgraded_versions .= '1.3 & ';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Moving subscription meta out of user meta and into item meta
|
// Moving subscription meta out of user meta and into item meta
|
||||||
if ( '0' != self::$active_version && version_compare( self::$active_version, '1.4', '<' ) ) {
|
if ( '0' !== self::$stored_core_library_version && version_compare( self::$stored_core_library_version, '1.4', '<' ) ) {
|
||||||
WCS_Upgrade_1_4::init();
|
WCS_Upgrade_1_4::init();
|
||||||
update_option( WC_Subscriptions_Admin::$option_prefix . '_active_version', '1.4' );
|
update_option( WC_Subscriptions_Admin::$option_prefix . '_active_version', '1.4' );
|
||||||
$upgraded_versions .= '1.4.';
|
$upgraded_versions .= '1.4.';
|
||||||
@@ -700,7 +805,7 @@ class WC_Subscriptions_Upgrader {
|
|||||||
public static function admin_css() {
|
public static function admin_css() {
|
||||||
wcs_deprecated_function( __METHOD__, 'subscriptions-core 7.7.0' );
|
wcs_deprecated_function( __METHOD__, 'subscriptions-core 7.7.0' );
|
||||||
|
|
||||||
wp_enqueue_style( 'woocommerce-subscriptions-about', WC_Subscriptions_Core_Plugin::instance()->get_subscriptions_core_directory_url( 'assets/css/about.css' ), array(), self::$active_version );
|
wp_enqueue_style( 'woocommerce-subscriptions-about', WC_Subscriptions_Core_Plugin::instance()->get_subscriptions_core_directory_url( 'assets/css/about.css' ), array(), self::$stored_core_library_version );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -719,7 +824,7 @@ class WC_Subscriptions_Upgrader {
|
|||||||
public static function about_screen() {
|
public static function about_screen() {
|
||||||
wcs_deprecated_function( __METHOD__, 'subscriptions-core 7.7.0' );
|
wcs_deprecated_function( __METHOD__, 'subscriptions-core 7.7.0' );
|
||||||
|
|
||||||
$active_version = self::$active_version;
|
$active_version = self::$stored_core_library_version;
|
||||||
$settings_page = admin_url( 'admin.php?page=wc-settings&tab=subscriptions' );
|
$settings_page = admin_url( 'admin.php?page=wc-settings&tab=subscriptions' );
|
||||||
|
|
||||||
include_once( dirname( __FILE__ ) . '/templates/wcs-about.php' );
|
include_once( dirname( __FILE__ ) . '/templates/wcs-about.php' );
|
||||||
@@ -765,12 +870,12 @@ class WC_Subscriptions_Upgrader {
|
|||||||
|
|
||||||
$query = self::get_subscription_query();
|
$query = self::get_subscription_query();
|
||||||
|
|
||||||
|
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
||||||
$wpdb->get_results( $query );
|
$wpdb->get_results( $query );
|
||||||
|
|
||||||
return $wpdb->num_rows;
|
return $wpdb->num_rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Single source of truth for the query
|
* Single source of truth for the query
|
||||||
* @param integer $limit the number of subscriptions to get
|
* @param integer $limit the number of subscriptions to get
|
||||||
@@ -782,30 +887,34 @@ class WC_Subscriptions_Upgrader {
|
|||||||
|
|
||||||
if ( null === $batch_size ) {
|
if ( null === $batch_size ) {
|
||||||
$select = 'SELECT DISTINCT items.order_item_id';
|
$select = 'SELECT DISTINCT items.order_item_id';
|
||||||
$limit = '';
|
$limit = '';
|
||||||
} else {
|
} else {
|
||||||
$select = 'SELECT meta.*, items.*';
|
$select = 'SELECT meta.*, items.*';
|
||||||
$limit = sprintf( ' LIMIT 0, %d', $batch_size );
|
$limit = sprintf( ' LIMIT 0, %d', $batch_size );
|
||||||
}
|
}
|
||||||
|
|
||||||
$query = sprintf( "%s FROM `{$wpdb->prefix}woocommerce_order_itemmeta` AS meta
|
$query = sprintf(
|
||||||
LEFT JOIN `{$wpdb->prefix}woocommerce_order_items` AS items USING (order_item_id)
|
"%s FROM `{$wpdb->prefix}woocommerce_order_itemmeta` AS meta
|
||||||
LEFT JOIN (
|
LEFT JOIN `{$wpdb->prefix}woocommerce_order_items` AS items USING (order_item_id)
|
||||||
SELECT a.order_item_id FROM `{$wpdb->prefix}woocommerce_order_itemmeta` AS a
|
|
||||||
LEFT JOIN (
|
LEFT JOIN (
|
||||||
SELECT `{$wpdb->prefix}woocommerce_order_itemmeta`.order_item_id FROM `{$wpdb->prefix}woocommerce_order_itemmeta`
|
SELECT a.order_item_id FROM `{$wpdb->prefix}woocommerce_order_itemmeta` AS a
|
||||||
WHERE `{$wpdb->prefix}woocommerce_order_itemmeta`.meta_key = '_subscription_status'
|
LEFT JOIN (
|
||||||
) AS s
|
SELECT `{$wpdb->prefix}woocommerce_order_itemmeta`.order_item_id FROM `{$wpdb->prefix}woocommerce_order_itemmeta`
|
||||||
USING (order_item_id)
|
WHERE `{$wpdb->prefix}woocommerce_order_itemmeta`.meta_key = '_subscription_status'
|
||||||
WHERE 1=1
|
) AS s
|
||||||
AND a.order_item_id = s.order_item_id
|
USING (order_item_id)
|
||||||
AND a.meta_key = '_subscription_start_date'
|
WHERE 1=1
|
||||||
ORDER BY CASE WHEN CAST(a.meta_value AS DATETIME) IS NULL THEN 1 ELSE 0 END, CAST(a.meta_value AS DATETIME) ASC
|
AND a.order_item_id = s.order_item_id
|
||||||
%s
|
AND a.meta_key = '_subscription_start_date'
|
||||||
) AS a3 USING (order_item_id)
|
ORDER BY CASE WHEN CAST(a.meta_value AS DATETIME) IS NULL THEN 1 ELSE 0 END, CAST(a.meta_value AS DATETIME) ASC
|
||||||
WHERE meta.meta_key REGEXP '_subscription_(.*)|_product_id|_variation_id'
|
%s
|
||||||
AND meta.order_item_id = a3.order_item_id
|
) AS a3 USING (order_item_id)
|
||||||
AND items.order_item_id IS NOT NULL", $select, $limit );
|
WHERE meta.meta_key REGEXP '_subscription_(.*)|_product_id|_variation_id'
|
||||||
|
AND meta.order_item_id = a3.order_item_id
|
||||||
|
AND items.order_item_id IS NOT NULL",
|
||||||
|
$select,
|
||||||
|
$limit
|
||||||
|
);
|
||||||
|
|
||||||
return $query;
|
return $query;
|
||||||
}
|
}
|
||||||
@@ -908,7 +1017,7 @@ class WC_Subscriptions_Upgrader {
|
|||||||
$action = 'wcs_external_cache_warning';
|
$action = 'wcs_external_cache_warning';
|
||||||
|
|
||||||
// First, check if the notice is being dismissed.
|
// First, check if the notice is being dismissed.
|
||||||
if ( isset( $_GET[ $action ], $_GET[ $nonce ] ) && wp_verify_nonce( $_GET[ $nonce ], $action ) ) {
|
if ( isset( $_GET[ $action ], $_GET[ $nonce ] ) && wp_verify_nonce( wc_clean( wp_unslash( $_GET[ $nonce ] ) ), $action ) ) {
|
||||||
delete_option( $option_name );
|
delete_option( $option_name );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -56,10 +56,14 @@ class WCS_Repair_Subtracted_Base_Tax_Line_Item_Meta extends WCS_Background_Repai
|
|||||||
$offset = ( $page - 1 ) * $limit;
|
$offset = ( $page - 1 ) * $limit;
|
||||||
|
|
||||||
return $wpdb->get_col(
|
return $wpdb->get_col(
|
||||||
"SELECT DISTINCT order_item_id
|
$wpdb->prepare(
|
||||||
FROM {$wpdb->prefix}woocommerce_order_itemmeta
|
"SELECT DISTINCT order_item_id
|
||||||
WHERE `meta_key` = '_subtracted_base_location_tax'
|
FROM {$wpdb->prefix}woocommerce_order_itemmeta
|
||||||
LIMIT {$offset}, {$limit}"
|
WHERE `meta_key` = '_subtracted_base_location_tax'
|
||||||
|
LIMIT %d, %d",
|
||||||
|
$offset,
|
||||||
|
$limit
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -26,8 +26,6 @@ class WCS_Upgrade_1_4 {
|
|||||||
global $wpdb;
|
global $wpdb;
|
||||||
|
|
||||||
$subscriptions_meta_key = $wpdb->get_blog_prefix() . 'woocommerce_subscriptions';
|
$subscriptions_meta_key = $wpdb->get_blog_prefix() . 'woocommerce_subscriptions';
|
||||||
$order_items_table = $wpdb->get_blog_prefix() . 'woocommerce_order_items';
|
|
||||||
$order_item_meta_table = $wpdb->get_blog_prefix() . 'woocommerce_order_itemmeta';
|
|
||||||
|
|
||||||
// Get the IDs of all users who have a subscription
|
// Get the IDs of all users who have a subscription
|
||||||
$users_to_upgrade = get_users(
|
$users_to_upgrade = get_users(
|
||||||
@@ -69,7 +67,7 @@ class WCS_Upgrade_1_4 {
|
|||||||
|
|
||||||
$wpdb->query(
|
$wpdb->query(
|
||||||
$wpdb->prepare(
|
$wpdb->prepare(
|
||||||
"INSERT INTO $order_item_meta_table (order_item_id, meta_key, meta_value)
|
"INSERT INTO {$wpdb->prefix}woocommerce_order_itemmeta (order_item_id, meta_key, meta_value)
|
||||||
VALUES
|
VALUES
|
||||||
(%d,%s,%s),
|
(%d,%s,%s),
|
||||||
(%d,%s,%s),
|
(%d,%s,%s),
|
||||||
@@ -128,9 +126,9 @@ class WCS_Upgrade_1_4 {
|
|||||||
|
|
||||||
// Get the ID of all orders for a subscription with a free trial and no sign-up fee
|
// Get the ID of all orders for a subscription with a free trial and no sign-up fee
|
||||||
$order_ids = $wpdb->get_col(
|
$order_ids = $wpdb->get_col(
|
||||||
"SELECT order_items.order_id FROM $order_items_table AS order_items
|
"SELECT order_items.order_id FROM {$wpdb->prefix}woocommerce_order_itemmeta AS order_items
|
||||||
LEFT JOIN $order_item_meta_table AS itemmeta USING (order_item_id)
|
LEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS itemmeta USING (order_item_id)
|
||||||
LEFT JOIN $order_item_meta_table AS itemmeta2 USING (order_item_id)
|
LEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS itemmeta2 USING (order_item_id)
|
||||||
WHERE itemmeta.meta_key = '_subscription_trial_length'
|
WHERE itemmeta.meta_key = '_subscription_trial_length'
|
||||||
AND itemmeta.meta_value > 0
|
AND itemmeta.meta_value > 0
|
||||||
AND itemmeta2.meta_key = '_subscription_sign_up_fee'
|
AND itemmeta2.meta_key = '_subscription_sign_up_fee'
|
||||||
@@ -145,19 +143,18 @@ class WCS_Upgrade_1_4 {
|
|||||||
"UPDATE $wpdb->postmeta
|
"UPDATE $wpdb->postmeta
|
||||||
SET `meta_value` = 0
|
SET `meta_value` = 0
|
||||||
WHERE `meta_key` IN ( '_order_total', '_order_tax', '_order_shipping_tax', '_order_shipping', '_order_discount', '_cart_discount' )
|
WHERE `meta_key` IN ( '_order_total', '_order_tax', '_order_shipping_tax', '_order_shipping', '_order_discount', '_cart_discount' )
|
||||||
AND `post_id` IN ( $order_ids )"
|
AND `post_id` IN ( $order_ids )" // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||||
);
|
);
|
||||||
|
|
||||||
// Now set the line totals to $0
|
// Now set the line totals to $0
|
||||||
$wpdb->query(
|
$wpdb->query(
|
||||||
"UPDATE $order_item_meta_table
|
"UPDATE {$wpdb->prefix}woocommerce_order_itemmeta
|
||||||
SET `meta_value` = 0
|
SET `meta_value` = 0
|
||||||
WHERE `meta_key` IN ( '_line_subtotal', '_line_subtotal_tax', '_line_total', '_line_tax', 'tax_amount', 'shipping_tax_amount' )
|
WHERE `meta_key` IN ( '_line_subtotal', '_line_subtotal_tax', '_line_total', '_line_tax', 'tax_amount', 'shipping_tax_amount' )
|
||||||
AND `order_item_id` IN (
|
AND `order_item_id` IN (
|
||||||
SELECT `order_item_id` FROM $order_items_table
|
SELECT `order_item_id` FROM {$wpdb->prefix}woocommerce_order_items
|
||||||
WHERE `order_item_type` IN ('tax','line_item')
|
WHERE `order_item_type` IN ('tax','line_item')
|
||||||
AND `order_id` IN ( $order_ids )
|
AND `order_id` IN ( $order_ids ) )" // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||||
)"
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -26,16 +26,20 @@ class WCS_Upgrade_1_5 {
|
|||||||
public static function upgrade_products() {
|
public static function upgrade_products() {
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
|
|
||||||
$sql = "SELECT DISTINCT ID FROM {$wpdb->posts} as posts
|
$subscription_product_ids = $wpdb->get_results(
|
||||||
JOIN {$wpdb->postmeta} as postmeta
|
$wpdb->prepare(
|
||||||
ON posts.ID = postmeta.post_id
|
"SELECT DISTINCT ID FROM {$wpdb->posts} as posts
|
||||||
AND (postmeta.meta_key LIKE '_subscription%')
|
JOIN {$wpdb->postmeta} as postmeta
|
||||||
JOIN {$wpdb->postmeta} AS soldindividually
|
ON posts.ID = postmeta.post_id
|
||||||
ON posts.ID = soldindividually.post_id
|
AND (postmeta.meta_key LIKE %s)
|
||||||
AND ( soldindividually.meta_key LIKE '_sold_individually' AND soldindividually.meta_value != 'yes' )
|
JOIN {$wpdb->postmeta} AS soldindividually
|
||||||
WHERE posts.post_type = 'product'";
|
ON posts.ID = soldindividually.post_id
|
||||||
|
AND ( soldindividually.meta_key LIKE %s AND soldindividually.meta_value != 'yes' )
|
||||||
$subscription_product_ids = $wpdb->get_results( $sql );
|
WHERE posts.post_type = 'product'",
|
||||||
|
$wpdb->esc_like( '_subscription' ) . '%',
|
||||||
|
$wpdb->esc_like( '_sold_individually' )
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
foreach ( $subscription_product_ids as $product_id ) {
|
foreach ( $subscription_product_ids as $product_id ) {
|
||||||
update_post_meta( $product_id->ID, '_sold_individually', 'yes' );
|
update_post_meta( $product_id->ID, '_sold_individually', 'yes' );
|
||||||
|
@@ -205,6 +205,7 @@ class WCS_Upgrade_2_0 {
|
|||||||
|
|
||||||
$wpdb->query( 'SET SQL_BIG_SELECTS = 1;' );
|
$wpdb->query( 'SET SQL_BIG_SELECTS = 1;' );
|
||||||
|
|
||||||
|
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
||||||
$raw_subscriptions = $wpdb->get_results( $query );
|
$raw_subscriptions = $wpdb->get_results( $query );
|
||||||
|
|
||||||
$subscriptions = array();
|
$subscriptions = array();
|
||||||
@@ -427,11 +428,13 @@ class WCS_Upgrade_2_0 {
|
|||||||
// Now that we've copied over the old data, prefix some the subscription meta keys with _wcs_migrated to deprecate it without deleting it (yet)
|
// Now that we've copied over the old data, prefix some the subscription meta keys with _wcs_migrated to deprecate it without deleting it (yet)
|
||||||
$subscription_item_meta_key_string = implode( "','", esc_sql( self::$subscription_item_meta_keys ) );
|
$subscription_item_meta_key_string = implode( "','", esc_sql( self::$subscription_item_meta_keys ) );
|
||||||
|
|
||||||
$rows_affected = $wpdb->query( $wpdb->prepare(
|
$rows_affected = $wpdb->query(
|
||||||
"UPDATE `{$wpdb->prefix}woocommerce_order_itemmeta` SET `meta_key` = concat( '_wcs_migrated', `meta_key` )
|
$wpdb->prepare(
|
||||||
WHERE `order_item_id` = %d AND `meta_key` IN ('{$subscription_item_meta_key_string}')",
|
"UPDATE `{$wpdb->prefix}woocommerce_order_itemmeta` SET `meta_key` = concat( '_wcs_migrated', `meta_key` )
|
||||||
$order_item_id
|
WHERE `order_item_id` = %d AND `meta_key` IN ('{$subscription_item_meta_key_string}')", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||||
) );
|
$order_item_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
return $rows_affected;
|
return $rows_affected;
|
||||||
}
|
}
|
||||||
@@ -662,11 +665,13 @@ class WCS_Upgrade_2_0 {
|
|||||||
|
|
||||||
// Do a single bulk insert instead of using update_post_meta() to massively reduce query time
|
// Do a single bulk insert instead of using update_post_meta() to massively reduce query time
|
||||||
if ( ! empty( $query_meta_values ) ) {
|
if ( ! empty( $query_meta_values ) ) {
|
||||||
$rows_affected = $wpdb->query( $wpdb->prepare(
|
$rows_affected = $wpdb->query(
|
||||||
"INSERT INTO {$wpdb->postmeta} (post_id, meta_key, meta_value)
|
$wpdb->prepare(
|
||||||
VALUES " . implode( ', ', $query_placeholders ),
|
"INSERT INTO {$wpdb->postmeta} (post_id, meta_key, meta_value)
|
||||||
$query_meta_values
|
VALUES " . implode( ', ', $query_placeholders ), // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare, WordPress.DB.PreparedSQL.NotPrepared
|
||||||
) );
|
$query_meta_values
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
WCS_Upgrade_Logger::add( sprintf( 'For subscription %d: %d rows of post meta added', $subscription_id, $rows_affected ) );
|
WCS_Upgrade_Logger::add( sprintf( 'For subscription %d: %d rows of post meta added', $subscription_id, $rows_affected ) );
|
||||||
}
|
}
|
||||||
@@ -710,11 +715,13 @@ class WCS_Upgrade_2_0 {
|
|||||||
|
|
||||||
$post_meta_to_deprecate = implode( "','", esc_sql( $post_meta_to_deprecate ) );
|
$post_meta_to_deprecate = implode( "','", esc_sql( $post_meta_to_deprecate ) );
|
||||||
|
|
||||||
$rows_affected = $wpdb->query( $wpdb->prepare(
|
$rows_affected = $wpdb->query(
|
||||||
"UPDATE {$wpdb->postmeta} SET `meta_key` = concat( '_wcs_migrated', `meta_key` )
|
$wpdb->prepare(
|
||||||
WHERE `post_id` = %d AND `meta_key` IN ('{$post_meta_to_deprecate}')",
|
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||||
$order_id
|
"UPDATE {$wpdb->postmeta} SET `meta_key` = concat( '_wcs_migrated', `meta_key` ) WHERE `post_id` = %d AND `meta_key` IN ('{$post_meta_to_deprecate}')",
|
||||||
) );
|
$order_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
return $rows_affected;
|
return $rows_affected;
|
||||||
}
|
}
|
||||||
@@ -735,12 +742,17 @@ class WCS_Upgrade_2_0 {
|
|||||||
"UPDATE {$wpdb->comments} SET `comment_post_ID` = %d
|
"UPDATE {$wpdb->comments} SET `comment_post_ID` = %d
|
||||||
WHERE `comment_post_id` = %d
|
WHERE `comment_post_id` = %d
|
||||||
AND (
|
AND (
|
||||||
`comment_content` LIKE '%%subscription%%'
|
`comment_content` LIKE %s
|
||||||
OR `comment_content` LIKE '%%Recurring%%'
|
OR `comment_content` LIKE %s
|
||||||
OR `comment_content` LIKE '%%Renewal%%'
|
OR `comment_content` LIKE %s
|
||||||
OR `comment_content` LIKE '%%Simplify payment error%%'
|
OR `comment_content` LIKE %s
|
||||||
)",
|
)",
|
||||||
$subscription_id, $order_id
|
$subscription_id,
|
||||||
|
$order_id,
|
||||||
|
'%' . $wpdb->esc_like( 'subscription' ) . '%',
|
||||||
|
'%' . $wpdb->esc_like( 'Recurring' ) . '%',
|
||||||
|
'%' . $wpdb->esc_like( 'Renewal' ) . '%',
|
||||||
|
'%' . $wpdb->esc_like( 'Simplify payment error' ) . '%'
|
||||||
) );
|
) );
|
||||||
|
|
||||||
WCS_Upgrade_Logger::add( sprintf( 'For subscription %d: migrated %d order notes', $subscription_id, $rows_affected ) );
|
WCS_Upgrade_Logger::add( sprintf( 'For subscription %d: migrated %d order notes', $subscription_id, $rows_affected ) );
|
||||||
|
@@ -120,7 +120,7 @@ class WCS_Upgrade_2_2_7 {
|
|||||||
/**
|
/**
|
||||||
* Add a message to the wcs-upgrade-end-of-prepaid-term-repair log
|
* Add a message to the wcs-upgrade-end-of-prepaid-term-repair log
|
||||||
*
|
*
|
||||||
* @param string The message to be logged
|
* @param string $message The message to be logged
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.7
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.7
|
||||||
*/
|
*/
|
||||||
protected static function log( $message ) {
|
protected static function log( $message ) {
|
||||||
|
@@ -117,7 +117,7 @@ class WCS_Upgrade_2_2_9 {
|
|||||||
/**
|
/**
|
||||||
* Add a message to the wcs-upgrade-subscriptions-containing-synced-variations log
|
* Add a message to the wcs-upgrade-subscriptions-containing-synced-variations log
|
||||||
*
|
*
|
||||||
* @param string The message to be logged
|
* @param string $message The message to be logged
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.9
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.9
|
||||||
*/
|
*/
|
||||||
protected static function log( $message ) {
|
protected static function log( $message ) {
|
||||||
|
@@ -25,8 +25,8 @@ class WCS_Upgrade_Logger {
|
|||||||
|
|
||||||
public static function init() {
|
public static function init() {
|
||||||
|
|
||||||
add_action( 'woocommerce_subscriptions_upgraded', array( __CLASS__, 'schedule_cleanup' ), 10, 2 );
|
add_action( 'woocommerce_subscriptions_upgraded', array( __CLASS__, 'schedule_cleanup' ), 10, 4 );
|
||||||
add_action( 'woocommerce_subscriptions_upgraded', array( __CLASS__, 'add_more_info' ), 10 );
|
add_action( 'woocommerce_subscriptions_upgraded', array( __CLASS__, 'add_more_info' ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -86,6 +86,13 @@ class WCS_Upgrade_Logger {
|
|||||||
self::add( sprintf( 'Active Plugins:' ) );
|
self::add( sprintf( 'Active Plugins:' ) );
|
||||||
|
|
||||||
foreach ( $active_plugins as $plugin ) {
|
foreach ( $active_plugins as $plugin ) {
|
||||||
|
// In unusual cases, the stored list of active plugins may be out-of-sync with the set of installed plugins.
|
||||||
|
// This would be true if a plugin was manually deleted without WordPress's knowledge in the current request,
|
||||||
|
// for example.
|
||||||
|
if ( ! isset( $all_plugins[ $plugin ] ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$author = empty( $all_plugins[ $plugin ]['Author'] ) ? 'Unknown' : $all_plugins[ $plugin ]['Author'];
|
$author = empty( $all_plugins[ $plugin ]['Author'] ) ? 'Unknown' : $all_plugins[ $plugin ]['Author'];
|
||||||
$version = empty( $all_plugins[ $plugin ]['Version'] ) ? 'Unknown version' : $all_plugins[ $plugin ]['Version'];
|
$version = empty( $all_plugins[ $plugin ]['Version'] ) ? 'Unknown version' : $all_plugins[ $plugin ]['Version'];
|
||||||
self::add( sprintf( ' %s by %s – %s', $all_plugins[ $plugin ]['Name'], $author, $version ) );
|
self::add( sprintf( ' %s by %s – %s', $all_plugins[ $plugin ]['Name'], $author, $version ) );
|
||||||
@@ -94,10 +101,25 @@ class WCS_Upgrade_Logger {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Schedule a hook to automatically clear the log after 8 weeks
|
* Schedule a hook to automatically clear the log after 8 weeks
|
||||||
|
*
|
||||||
|
* @since 7.7.0 Updated to reference the plugin version, rather than the legacy core library version.
|
||||||
|
*
|
||||||
|
* @param string $current_library_version Disused.
|
||||||
|
* @param string $old_library_version Disused.
|
||||||
|
* @param string $current_version Current version of WooCommerce Subscriptions.
|
||||||
|
* @param string $old_version Old version of WooCommerce Subscriptions.
|
||||||
*/
|
*/
|
||||||
public static function schedule_cleanup( $current_version, $old_version ) {
|
public static function schedule_cleanup( string $current_library_version, string $old_library_version, string $current_version, string $old_version ): void {
|
||||||
$wc_version = defined( 'WC_VERSION' ) ? WC_VERSION : 'undefined';
|
$wc_version = defined( 'WC_VERSION' ) ? WC_VERSION : 'undefined';
|
||||||
self::add( sprintf( '%s upgrade complete from Subscriptions v%s while WooCommerce WC_VERSION %s and database version %s was active.', $current_version, $old_version, $wc_version, get_option( 'woocommerce_db_version' ) ) );
|
self::add(
|
||||||
|
sprintf(
|
||||||
|
'WooCommerce Subscriptions completed its upgrade to %1$s from %2$s while WooCommerce WC_VERSION %3$s and database version %4$s was active.',
|
||||||
|
$current_version,
|
||||||
|
$old_version,
|
||||||
|
$wc_version,
|
||||||
|
get_option( 'woocommerce_db_version' )
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -18,9 +18,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
/**
|
/**
|
||||||
* Display a recurring cart's subtotal
|
* Display a recurring cart's subtotal
|
||||||
*
|
*
|
||||||
* @access public
|
|
||||||
* @param WC_Cart $cart The cart do print the subtotal html for.
|
* @param WC_Cart $cart The cart do print the subtotal html for.
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
function wcs_cart_totals_subtotal_html( $cart ) {
|
function wcs_cart_totals_subtotal_html( $cart ) {
|
||||||
$subtotal_html = wcs_cart_price_string( wc_price( $cart->get_displayed_subtotal() ), $cart );
|
$subtotal_html = wcs_cart_price_string( wc_price( $cart->get_displayed_subtotal() ), $cart );
|
||||||
@@ -38,8 +36,6 @@ function wcs_cart_totals_subtotal_html( $cart ) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get recurring shipping methods.
|
* Get recurring shipping methods.
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*/
|
*/
|
||||||
function wcs_cart_totals_shipping_html() {
|
function wcs_cart_totals_shipping_html() {
|
||||||
$initial_packages = WC()->shipping->get_packages();
|
$initial_packages = WC()->shipping->get_packages();
|
||||||
@@ -164,7 +160,6 @@ function wcs_cart_totals_shipping_html() {
|
|||||||
* @param object $shipping_method
|
* @param object $shipping_method
|
||||||
* @param string $chosen_method
|
* @param string $chosen_method
|
||||||
* @param string $input_type
|
* @param string $input_type
|
||||||
* @return null
|
|
||||||
*/
|
*/
|
||||||
function wcs_cart_print_shipping_input( $shipping_method_index, $shipping_method, $chosen_method = '', $input_type = 'hidden' ) {
|
function wcs_cart_print_shipping_input( $shipping_method_index, $shipping_method, $chosen_method = '', $input_type = 'hidden' ) {
|
||||||
|
|
||||||
@@ -332,7 +327,7 @@ function wcs_cart_totals_coupon_html( $coupon, $cart ) {
|
|||||||
/**
|
/**
|
||||||
* Gets recurring total html including inc tax if needed.
|
* Gets recurring total html including inc tax if needed.
|
||||||
*
|
*
|
||||||
* @param WC_Cart The cart to display the total for.
|
* @param WC_Cart $cart The cart to display the total for.
|
||||||
*/
|
*/
|
||||||
function wcs_cart_totals_order_total_html( $cart ) {
|
function wcs_cart_totals_order_total_html( $cart ) {
|
||||||
$order_total_html = '<strong>' . $cart->get_total() . '</strong> ';
|
$order_total_html = '<strong>' . $cart->get_total() . '</strong> ';
|
||||||
|
@@ -140,7 +140,7 @@ function wcs_get_objects_property( $object, $property, $single = 'single', $defa
|
|||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
function wcs_set_objects_property( &$object, $key, $value, $save = 'save', $meta_id = '', $prefix_meta_key = 'prefix_meta_key' ) {
|
function wcs_set_objects_property( &$object, $key, $value, $save = 'save', $meta_id = 0, $prefix_meta_key = 'prefix_meta_key' ) {
|
||||||
|
|
||||||
$prefixed_key = wcs_maybe_prefix_key( $key );
|
$prefixed_key = wcs_maybe_prefix_key( $key );
|
||||||
|
|
||||||
@@ -194,13 +194,13 @@ function wcs_set_objects_property( &$object, $key, $value, $save = 'save', $meta
|
|||||||
*
|
*
|
||||||
* @param WC_Order|WC_Product|WC_Subscription $object The object whose property we want to access.
|
* @param WC_Order|WC_Product|WC_Subscription $object The object whose property we want to access.
|
||||||
* @param string $key The meta key name without '_' prefix
|
* @param string $key The meta key name without '_' prefix
|
||||||
* @param mixed $value The data to set as the value of the meta
|
|
||||||
* @param string $save Whether to save the data or not, 'save' to save the data, otherwise it won't be saved.
|
* @param string $save Whether to save the data or not, 'save' to save the data, otherwise it won't be saved.
|
||||||
|
* @param int $meta_id The meta ID.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0
|
||||||
* @deprecated 2.4.0 Use of this compatibility function is no longer required, setters should be used on the objects instead.
|
* @deprecated 2.4.0 Use of this compatibility function is no longer required, setters should be used on the objects instead.
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
function wcs_delete_objects_property( &$object, $key, $save = 'save', $meta_id = '' ) {
|
function wcs_delete_objects_property( &$object, $key, $save = 'save', $meta_id = 0 ) {
|
||||||
|
|
||||||
$prefixed_key = wcs_maybe_prefix_key( $key );
|
$prefixed_key = wcs_maybe_prefix_key( $key );
|
||||||
|
|
||||||
@@ -477,7 +477,8 @@ function wcs_is_rest_api_request() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$rest_prefix = trailingslashit( rest_get_url_prefix() );
|
$rest_prefix = trailingslashit( rest_get_url_prefix() );
|
||||||
|
// @phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
|
||||||
$is_rest_api_request = ( false !== strpos( $_SERVER['REQUEST_URI'], $rest_prefix ) );
|
$is_rest_api_request = ( false !== strpos( $_SERVER['REQUEST_URI'], $rest_prefix ) );
|
||||||
|
|
||||||
return apply_filters( 'woocommerce_is_rest_api_request', $is_rest_api_request );
|
return apply_filters( 'woocommerce_is_rest_api_request', $is_rest_api_request );
|
||||||
@@ -567,7 +568,7 @@ function wcs_add_woocommerce_dependent_action( $tag, $function, $woocommerce_ver
|
|||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v4.0.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v4.0.0
|
||||||
*
|
*
|
||||||
* @param string The version string to check in a version_compare() compatible format.
|
* @param string $version The version string to check in a version_compare() compatible format.
|
||||||
* @return bool Whether the installed version of WC is prior to the given version string.
|
* @return bool Whether the installed version of WC is prior to the given version string.
|
||||||
*/
|
*/
|
||||||
function wcs_is_woocommerce_pre( $version ) {
|
function wcs_is_woocommerce_pre( $version ) {
|
||||||
|
@@ -21,10 +21,11 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
* in some cases, like WC_Subscriptions_Product::is_purchasable() and WC_Product_Subscription_Variation::is_purchasable(), both
|
* in some cases, like WC_Subscriptions_Product::is_purchasable() and WC_Product_Subscription_Variation::is_purchasable(), both
|
||||||
* called within WC_Cart::get_cart_from_session(), which is run before query vars are setup.
|
* called within WC_Cart::get_cart_from_session(), which is run before query vars are setup.
|
||||||
*
|
*
|
||||||
* @return 2.0.13
|
|
||||||
* @return bool
|
* @return bool
|
||||||
**/
|
**/
|
||||||
function wcs_is_order_received_page() {
|
function wcs_is_order_received_page() {
|
||||||
return ( false !== strpos( $_SERVER['REQUEST_URI'], 'order-received' ) );
|
// @phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
|
||||||
}
|
$request_uri = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( $_SERVER['REQUEST_URI'] ) : '';
|
||||||
|
|
||||||
|
return ( false !== strpos( $request_uri, 'order-received' ) );
|
||||||
|
}
|
||||||
|
@@ -21,8 +21,8 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0
|
||||||
* @param string $function
|
* @param string $function
|
||||||
|
* @param string $message
|
||||||
* @param string $version
|
* @param string $version
|
||||||
* @param string $replacement
|
|
||||||
*/
|
*/
|
||||||
function wcs_doing_it_wrong( $function, $message, $version ) {
|
function wcs_doing_it_wrong( $function, $message, $version ) {
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ function wcs_deprecated_function( $function, $version, $replacement = null ) {
|
|||||||
* Reimplement similar logic to wc_deprecated_argument() without the first parameter confusion.
|
* Reimplement similar logic to wc_deprecated_argument() without the first parameter confusion.
|
||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0
|
||||||
* @param string $argument
|
* @param string $function
|
||||||
* @param string $version
|
* @param string $version
|
||||||
* @param string $message
|
* @param string $message
|
||||||
*/
|
*/
|
||||||
@@ -174,6 +174,7 @@ function wcs_get_subscription_from_key( $subscription_key ) {
|
|||||||
$subscription = wcs_get_subscription( $subscription_id );
|
$subscription = wcs_get_subscription( $subscription_id );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @phpstan-ignore variable.undefined
|
||||||
if ( ! is_object( $subscription ) ) {
|
if ( ! is_object( $subscription ) ) {
|
||||||
// translators: placeholder is either subscription key or a subscription id, or, failing that, empty (e.g. "145_21" or "145")
|
// translators: placeholder is either subscription key or a subscription id, or, failing that, empty (e.g. "145_21" or "145")
|
||||||
throw new InvalidArgumentException( sprintf( __( 'Could not get subscription. Most likely the subscription key does not refer to a subscription. The key was: "%s".', 'woocommerce-subscriptions' ), $subscription_key ) );
|
throw new InvalidArgumentException( sprintf( __( 'Could not get subscription. Most likely the subscription key does not refer to a subscription. The key was: "%s".', 'woocommerce-subscriptions' ), $subscription_key ) );
|
||||||
@@ -282,7 +283,7 @@ function wcs_deprecated_hook( $hook, $version, $replacement = null, $message = n
|
|||||||
|
|
||||||
error_log( $log_string . $message );
|
error_log( $log_string . $message );
|
||||||
} else {
|
} else {
|
||||||
_deprecated_hook( $hook, $version, $replacement, $message );
|
wc_deprecated_hook( $hook, $version, $replacement, $message );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -285,7 +285,7 @@ function wp_kses_allow_underscores( $content, $allowed_html ) {
|
|||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v4.0.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v4.0.0
|
||||||
*
|
*
|
||||||
* @param string The number to append the ordinal suffix to.
|
* @param string $number The number to append the ordinal suffix to.
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
function wcs_append_numeral_suffix( $number ) {
|
function wcs_append_numeral_suffix( $number ) {
|
||||||
|
@@ -301,8 +301,8 @@ function wcs_get_subscription_date_types() {
|
|||||||
/**
|
/**
|
||||||
* Find whether to display a specific date type in the admin area
|
* Find whether to display a specific date type in the admin area
|
||||||
*
|
*
|
||||||
* @param string A subscription date type key. One of the array key values returned by @see wcs_get_subscription_date_types().
|
* @param string $date_type A subscription date type key. One of the array key values returned by @see wcs_get_subscription_date_types().
|
||||||
* @param WC_Subscription
|
* @param WC_Subscription $subscription
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.1
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.1
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
@@ -472,9 +472,6 @@ function wcs_get_subscriptions( $args ) {
|
|||||||
'meta_query' => isset( $working_args['meta_query'] ) ? $working_args['meta_query'] : array(), // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
|
'meta_query' => isset( $working_args['meta_query'] ) ? $working_args['meta_query'] : array(), // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
|
||||||
);
|
);
|
||||||
|
|
||||||
// Remove Subscriptions-specific args which exist as aliases of regular order query args.
|
|
||||||
unset( $query_args['subscription_status'], $query_args['subscriptions_per_page'] );
|
|
||||||
|
|
||||||
// Maybe only get subscriptions created by a certain order
|
// Maybe only get subscriptions created by a certain order
|
||||||
if ( 0 !== $working_args['order_id'] && is_numeric( $working_args['order_id'] ) ) {
|
if ( 0 !== $working_args['order_id'] && is_numeric( $working_args['order_id'] ) ) {
|
||||||
$query_args['parent'] = $working_args['order_id'];
|
$query_args['parent'] = $working_args['order_id'];
|
||||||
@@ -646,12 +643,12 @@ function wcs_get_subscriptions_for_product( $product_ids, $fields = 'ids', $args
|
|||||||
/**
|
/**
|
||||||
* Get all subscription items which have a trial.
|
* Get all subscription items which have a trial.
|
||||||
*
|
*
|
||||||
* @param mixed WC_Subscription|post_id
|
* @param mixed $subscription_id WC_Subscription|post_id
|
||||||
* @return array
|
* @return array
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
function wcs_get_line_items_with_a_trial( $subscription_id ) {
|
function wcs_get_line_items_with_a_trial( $subscription_id ) {
|
||||||
|
/** @var WC_Subscription $subscription */
|
||||||
$subscription = ( is_object( $subscription_id ) ) ? $subscription_id : wcs_get_subscription( $subscription_id );
|
$subscription = ( is_object( $subscription_id ) ) ? $subscription_id : wcs_get_subscription( $subscription_id );
|
||||||
$trial_items = array();
|
$trial_items = array();
|
||||||
|
|
||||||
@@ -684,7 +681,7 @@ function wcs_can_items_be_removed( $subscription ) {
|
|||||||
/**
|
/**
|
||||||
* Checks if the user can be granted the permission to remove a particular line item from the subscription.
|
* Checks if the user can be granted the permission to remove a particular line item from the subscription.
|
||||||
*
|
*
|
||||||
* @param WC_Order_item $item An instance of a WC_Order_item object
|
* @param WC_Order_Item $item An instance of a WC_Order_item object
|
||||||
* @param WC_Subscription $subscription An instance of a WC_Subscription object
|
* @param WC_Subscription $subscription An instance of a WC_Subscription object
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.15
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.15
|
||||||
*/
|
*/
|
||||||
@@ -696,7 +693,7 @@ function wcs_can_item_be_removed( $item, $subscription ) {
|
|||||||
* Get the Product ID for an order's line item (only the product ID, not the variation ID, even if the order item
|
* Get the Product ID for an order's line item (only the product ID, not the variation ID, even if the order item
|
||||||
* is for a variation).
|
* is for a variation).
|
||||||
*
|
*
|
||||||
* @param int An order item ID
|
* @param int $item_id An order item ID
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
function wcs_get_order_items_product_id( $item_id ) {
|
function wcs_get_order_items_product_id( $item_id ) {
|
||||||
@@ -719,7 +716,7 @@ function wcs_get_order_items_product_id( $item_id ) {
|
|||||||
* items representing a variation, that means the 'variation_id' value, if the item is not a variation, that means
|
* items representing a variation, that means the 'variation_id' value, if the item is not a variation, that means
|
||||||
* the 'product_id value. This function helps save keystrokes on the idiom to check if an item is to a variation or not.
|
* the 'product_id value. This function helps save keystrokes on the idiom to check if an item is to a variation or not.
|
||||||
*
|
*
|
||||||
* @param array or object $item Either a cart item, order/subscription line item, or a product.
|
* @param array|object $item_or_product Either a cart item, order/subscription line item, or a product.
|
||||||
*/
|
*/
|
||||||
function wcs_get_canonical_product_id( $item_or_product ) {
|
function wcs_get_canonical_product_id( $item_or_product ) {
|
||||||
|
|
||||||
@@ -817,22 +814,24 @@ function wcs_subscription_search( $term ) {
|
|||||||
FROM {$wpdb->postmeta} p1
|
FROM {$wpdb->postmeta} p1
|
||||||
INNER JOIN {$wpdb->postmeta} p2 ON p1.post_id = p2.post_id
|
INNER JOIN {$wpdb->postmeta} p2 ON p1.post_id = p2.post_id
|
||||||
WHERE
|
WHERE
|
||||||
( p1.meta_key = '_billing_first_name' AND p2.meta_key = '_billing_last_name' AND CONCAT(p1.meta_value, ' ', p2.meta_value) LIKE '%%%s%%' )
|
( p1.meta_key = '_billing_first_name' AND p2.meta_key = '_billing_last_name' AND CONCAT(p1.meta_value, ' ', p2.meta_value) LIKE %s )
|
||||||
OR
|
OR
|
||||||
( p1.meta_key = '_shipping_first_name' AND p2.meta_key = '_shipping_last_name' AND CONCAT(p1.meta_value, ' ', p2.meta_value) LIKE '%%%s%%' )
|
( p1.meta_key = '_shipping_first_name' AND p2.meta_key = '_shipping_last_name' AND CONCAT(p1.meta_value, ' ', p2.meta_value) LIKE %s )
|
||||||
OR
|
OR
|
||||||
( p1.meta_key IN ('" . implode( "','", esc_sql( $search_fields ) ) . "') AND p1.meta_value LIKE '%%%s%%' )
|
( p1.meta_key IN ('" . implode( "','", esc_sql( $search_fields ) ) . "') AND p1.meta_value LIKE %s )
|
||||||
",
|
",
|
||||||
esc_attr( $term ), esc_attr( $term ), esc_attr( $term )
|
'%' . $wpdb->esc_like( esc_attr( $term ) ) . '%',
|
||||||
|
'%' . $wpdb->esc_like( esc_attr( $term ) ) . '%',
|
||||||
|
'%' . $wpdb->esc_like( esc_attr( $term ) ) . '%'
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
$wpdb->get_col(
|
$wpdb->get_col(
|
||||||
$wpdb->prepare( "
|
$wpdb->prepare( "
|
||||||
SELECT order_id
|
SELECT order_id
|
||||||
FROM {$wpdb->prefix}woocommerce_order_items as order_items
|
FROM {$wpdb->prefix}woocommerce_order_items as order_items
|
||||||
WHERE order_item_name LIKE '%%%s%%'
|
WHERE order_item_name LIKE %s
|
||||||
",
|
",
|
||||||
esc_attr( $term )
|
'%' . $wpdb->esc_like( esc_attr( $term ) ) . '%'
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
$wpdb->get_col(
|
$wpdb->get_col(
|
||||||
@@ -841,11 +840,11 @@ function wcs_subscription_search( $term ) {
|
|||||||
FROM {$wpdb->posts} p1
|
FROM {$wpdb->posts} p1
|
||||||
INNER JOIN {$wpdb->postmeta} p2 ON p1.ID = p2.post_id
|
INNER JOIN {$wpdb->postmeta} p2 ON p1.ID = p2.post_id
|
||||||
INNER JOIN {$wpdb->users} u ON p2.meta_value = u.ID
|
INNER JOIN {$wpdb->users} u ON p2.meta_value = u.ID
|
||||||
WHERE u.user_email LIKE '%%%s%%'
|
WHERE u.user_email LIKE %s
|
||||||
AND p2.meta_key = '_customer_user'
|
AND p2.meta_key = '_customer_user'
|
||||||
AND p1.post_type = 'shop_subscription'
|
AND p1.post_type = 'shop_subscription'
|
||||||
",
|
",
|
||||||
esc_attr( $term )
|
'%' . $wpdb->esc_like( esc_attr( $term ) ) . '%'
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
array( $search_order_id )
|
array( $search_order_id )
|
||||||
@@ -897,7 +896,7 @@ function wcs_set_payment_meta( $subscription, $payment_meta ) {
|
|||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.6.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.6.0
|
||||||
*
|
*
|
||||||
* @param WC_Order|WC_Subscription $subscription Order or subscription object.
|
* @param WC_Order|WC_Subscription $order Order or subscription object.
|
||||||
* @param WC_Product $product The product to get the total quantity of.
|
* @param WC_Product $product The product to get the total quantity of.
|
||||||
* @param string $product_match_method The way to find matching products. Optional. Default is 'stock_managed' Can be:
|
* @param string $product_match_method The way to find matching products. Optional. Default is 'stock_managed' Can be:
|
||||||
* 'stock_managed' - Products with matching stock managed IDs are grouped. Helpful for getting the total quantity of variation parents if they are managed on the product level, not on the variation level - @see WC_Product::get_stock_managed_by_id().
|
* 'stock_managed' - Products with matching stock managed IDs are grouped. Helpful for getting the total quantity of variation parents if they are managed on the product level, not on the variation level - @see WC_Product::get_stock_managed_by_id().
|
||||||
|
@@ -15,7 +15,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
/**
|
/**
|
||||||
* Display date/time input fields
|
* Display date/time input fields
|
||||||
*
|
*
|
||||||
* @param int (optional) A timestamp for a certain date in the site's timezome. If left empty, or 0, it will be set to today's date.
|
* @param int|null $timestamp (optional) A timestamp for a certain date in the site's timezome. If left empty, or 0, it will be set to today's date.
|
||||||
* @param array $args A set of name => value pairs to customise the input fields
|
* @param array $args A set of name => value pairs to customise the input fields
|
||||||
* 'id_attr': (string) the date to display in the selector in MySQL format ('Y-m-d H:i:s'). Required.
|
* 'id_attr': (string) the date to display in the selector in MySQL format ('Y-m-d H:i:s'). Required.
|
||||||
* 'date': (string) the date to display in the selector in MySQL format ('Y-m-d H:i:s'). Required.
|
* 'date': (string) the date to display in the selector in MySQL format ('Y-m-d H:i:s'). Required.
|
||||||
@@ -121,7 +121,7 @@ function wcs_json_encode( $data ) {
|
|||||||
* @param $haystack An array to insert the element into
|
* @param $haystack An array to insert the element into
|
||||||
* @param $new_key The key to insert
|
* @param $new_key The key to insert
|
||||||
* @param $new_value An value to insert
|
* @param $new_value An value to insert
|
||||||
* @return The new array if the $needle key exists, otherwise an unmodified $haystack
|
* @return array The new array if the $needle key exists, otherwise an unmodified $haystack
|
||||||
*/
|
*/
|
||||||
function wcs_array_insert_after( $needle, $haystack, $new_key, $new_value ) {
|
function wcs_array_insert_after( $needle, $haystack, $new_key, $new_value ) {
|
||||||
|
|
||||||
@@ -314,7 +314,7 @@ function wcs_trial_has_passed( $subscription ) {
|
|||||||
* @param array $array The array of items to check.
|
* @param array $array The array of items to check.
|
||||||
* @param array $property The name of object's property to check. Optional. Default is '' - the array element value as a boolean will be used, the same as array_filter().
|
* @param array $property The name of object's property to check. Optional. Default is '' - the array element value as a boolean will be used, the same as array_filter().
|
||||||
*/
|
*/
|
||||||
function wcs_apply_array_filter( $filter, $array, $property = '' ) {
|
function wcs_apply_array_filter( $filter, $array, $property = array() ) {
|
||||||
|
|
||||||
foreach ( $array as $index => $element ) {
|
foreach ( $array as $index => $element ) {
|
||||||
$value = empty( $property ) ? $element : $element->{$property};
|
$value = empty( $property ) ? $element : $element->{$property};
|
||||||
|
@@ -255,6 +255,7 @@ function wcs_create_order_from_subscription( $subscription, $type ) {
|
|||||||
|
|
||||||
// If the line item we're adding is a product line item and that product still exists, set any applicable backorder meta.
|
// If the line item we're adding is a product line item and that product still exists, set any applicable backorder meta.
|
||||||
if ( $item->is_type( 'line_item' ) && $item->get_product() ) {
|
if ( $item->is_type( 'line_item' ) && $item->get_product() ) {
|
||||||
|
// @phpstan-ignore-next-line
|
||||||
$order_item->set_backorder_meta();
|
$order_item->set_backorder_meta();
|
||||||
$order_item->save();
|
$order_item->save();
|
||||||
}
|
}
|
||||||
@@ -631,7 +632,8 @@ function wcs_update_order_item_type( $item_id, $new_type, $order_or_subscription
|
|||||||
/**
|
/**
|
||||||
* Get an instance of WC_Order_Item_Meta for an order item
|
* Get an instance of WC_Order_Item_Meta for an order item
|
||||||
*
|
*
|
||||||
* @param array
|
* @param WC_Order_Item $item
|
||||||
|
* @param WC_Product $product
|
||||||
* @return WC_Order_Item_Meta
|
* @return WC_Order_Item_Meta
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
@@ -706,7 +708,7 @@ function wcs_get_order_item_name( $order_item, $include = array() ) {
|
|||||||
* Get the full name for a order/subscription line item, including the items non hidden meta
|
* Get the full name for a order/subscription line item, including the items non hidden meta
|
||||||
* (i.e. attributes), as a flat string.
|
* (i.e. attributes), as a flat string.
|
||||||
*
|
*
|
||||||
* @param array
|
* @param array $line_item
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
function wcs_get_line_item_name( $line_item ) {
|
function wcs_get_line_item_name( $line_item ) {
|
||||||
@@ -762,7 +764,7 @@ function wcs_get_line_item_name( $line_item ) {
|
|||||||
* Display item meta data in a version compatible way.
|
* Display item meta data in a version compatible way.
|
||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0
|
||||||
* @param WC_Item $item
|
* @param WC_Order_Item $item
|
||||||
* @param WC_Order $order
|
* @param WC_Order $order
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
@@ -778,7 +780,7 @@ function wcs_display_item_meta( $item, $order ) {
|
|||||||
* Display item download links in a version compatible way.
|
* Display item download links in a version compatible way.
|
||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0
|
||||||
* @param WC_Item $item
|
* @param WC_Order_Item $item
|
||||||
* @param WC_Order $order
|
* @param WC_Order $order
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
@@ -828,6 +830,7 @@ function wcs_copy_order_item( $from_item, &$to_item ) {
|
|||||||
) );
|
) );
|
||||||
break;
|
break;
|
||||||
case 'shipping':
|
case 'shipping':
|
||||||
|
/** @var WC_Order_Item_Shipping $to_item */
|
||||||
/** @var WC_Order_Item_Shipping $from_item */
|
/** @var WC_Order_Item_Shipping $from_item */
|
||||||
$to_item->set_props( array(
|
$to_item->set_props( array(
|
||||||
'method_id' => $from_item->get_method_id(),
|
'method_id' => $from_item->get_method_id(),
|
||||||
@@ -966,6 +969,8 @@ function wcs_seconds_since_order_created( $order ) {
|
|||||||
function wcs_find_matching_line_item( $order, $subscription_item, $match_type = 'match_product_ids' ) {
|
function wcs_find_matching_line_item( $order, $subscription_item, $match_type = 'match_product_ids' ) {
|
||||||
$matching_item = false;
|
$matching_item = false;
|
||||||
|
|
||||||
|
$subscription_item_attributes = array();
|
||||||
|
|
||||||
if ( 'match_attributes' === $match_type ) {
|
if ( 'match_attributes' === $match_type ) {
|
||||||
$subscription_item_attributes = wp_list_pluck( $subscription_item->get_formatted_meta_data( '_', true ), 'value', 'key' );
|
$subscription_item_attributes = wp_list_pluck( $subscription_item->get_formatted_meta_data( '_', true ), 'value', 'key' );
|
||||||
}
|
}
|
||||||
@@ -1051,7 +1056,7 @@ function wcs_order_contains_early_renewal( $order ) {
|
|||||||
*
|
*
|
||||||
* @return string The item's subscription grouping key.
|
* @return string The item's subscription grouping key.
|
||||||
*/
|
*/
|
||||||
function wcs_get_subscription_item_grouping_key( $item, $renewal_time = '' ) {
|
function wcs_get_subscription_item_grouping_key( $item, $renewal_time = 0 ) {
|
||||||
return apply_filters( 'woocommerce_subscriptions_item_grouping_key', wcs_get_subscription_grouping_key( $item->get_product(), $renewal_time ), $item );
|
return apply_filters( 'woocommerce_subscriptions_item_grouping_key', wcs_get_subscription_grouping_key( $item->get_product(), $renewal_time ), $item );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1063,7 +1068,7 @@ function wcs_get_subscription_item_grouping_key( $item, $renewal_time = '' ) {
|
|||||||
*
|
*
|
||||||
* Note: If the line item has a custom total that doesn't match the expected price, don't override it.
|
* Note: If the line item has a custom total that doesn't match the expected price, don't override it.
|
||||||
*
|
*
|
||||||
* @param WC_Order_Item $item Subscription line item.
|
* @param WC_Order_Item_Product $item Subscription line item.
|
||||||
*/
|
*/
|
||||||
function wcs_set_recurring_item_total( &$item ) {
|
function wcs_set_recurring_item_total( &$item ) {
|
||||||
$product = $item->get_product();
|
$product = $item->get_product();
|
||||||
|
@@ -144,7 +144,7 @@ function wcs_get_min_max_variation_data( $variable_product, $child_variation_ids
|
|||||||
* Determine the minimum and maximum values for a set of structured subscription
|
* Determine the minimum and maximum values for a set of structured subscription
|
||||||
* price data in a form created by @see wcs_get_min_max_variation_data()
|
* price data in a form created by @see wcs_get_min_max_variation_data()
|
||||||
*
|
*
|
||||||
* @param array $child_variation_ids the IDs of product variation children ids
|
* @param array $variations_data the IDs of product variation children ids
|
||||||
* @return array
|
* @return array
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0
|
||||||
*/
|
*/
|
||||||
|
@@ -105,11 +105,11 @@ function wcs_get_users_resubscribe_link_for_product( $product_id ) {
|
|||||||
/**
|
/**
|
||||||
* Checks the cart to see if it contains a subscription product renewal.
|
* Checks the cart to see if it contains a subscription product renewal.
|
||||||
*
|
*
|
||||||
* @param bool | Array The cart item containing the renewal, else false.
|
* @param bool|array $cart The cart item containing the renewal, else false.
|
||||||
* @return string
|
* @return string
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
function wcs_cart_contains_resubscribe( $cart = '' ) {
|
function wcs_cart_contains_resubscribe( $cart = null ) {
|
||||||
|
|
||||||
$contains_resubscribe = false;
|
$contains_resubscribe = false;
|
||||||
|
|
||||||
@@ -153,12 +153,12 @@ function wcs_get_subscriptions_for_resubscribe_order( $order ) {
|
|||||||
* 5. have a recurring amount greater than $0, to avoid allowing resubscribes to subscriptions
|
* 5. have a recurring amount greater than $0, to avoid allowing resubscribes to subscriptions
|
||||||
* where the entire cost is charged in a sign-up fee
|
* where the entire cost is charged in a sign-up fee
|
||||||
*
|
*
|
||||||
* @param int | WC_Subscription $subscription Post ID of a 'shop_subscription' post, or instance of a WC_Subscription object
|
* @param int|WC_Subscription $subscription Post ID of a 'shop_subscription' post, or instance of a WC_Subscription object
|
||||||
* @param int The ID of a user
|
* @param int $user_id The ID of a user
|
||||||
* @return bool
|
* @return bool
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
function wcs_can_user_resubscribe_to( $subscription, $user_id = '' ) {
|
function wcs_can_user_resubscribe_to( $subscription, $user_id = 0 ) {
|
||||||
|
|
||||||
if ( ! is_object( $subscription ) ) {
|
if ( ! is_object( $subscription ) ) {
|
||||||
$subscription = wcs_get_subscription( $subscription );
|
$subscription = wcs_get_subscription( $subscription );
|
||||||
|
@@ -36,7 +36,7 @@ function wcs_order_contains_switch( $order ) {
|
|||||||
/**
|
/**
|
||||||
* Get the subscriptions that had an item switch for a given order (if any).
|
* Get the subscriptions that had an item switch for a given order (if any).
|
||||||
*
|
*
|
||||||
* @param int|WC_Order $order_id The post_id of a shop_order post or an instance of a WC_Order object
|
* @param int|WC_Order $order The post_id of a shop_order post or an instance of a WC_Order object
|
||||||
* @return array Subscription details in post_id => WC_Subscription form.
|
* @return array Subscription details in post_id => WC_Subscription form.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
|
@@ -18,8 +18,8 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
/**
|
/**
|
||||||
* Return an i18n'ified associative array of all possible subscription periods.
|
* Return an i18n'ified associative array of all possible subscription periods.
|
||||||
*
|
*
|
||||||
* @param int (optional) An interval in the range 1-6
|
* @param int|null $number (optional) An interval in the range 1-6
|
||||||
* @param string (optional) One of day, week, month or year. If empty, all subscription ranges are returned.
|
* @param string|null $period (optional) One of day, week, month or year. If empty, all subscription ranges are returned.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
function wcs_get_subscription_period_strings( $number = 1, $period = '' ) {
|
function wcs_get_subscription_period_strings( $number = 1, $period = '' ) {
|
||||||
@@ -46,8 +46,8 @@ function wcs_get_subscription_period_strings( $number = 1, $period = '' ) {
|
|||||||
/**
|
/**
|
||||||
* Return an i18n'ified associative array of all possible subscription trial periods.
|
* Return an i18n'ified associative array of all possible subscription trial periods.
|
||||||
*
|
*
|
||||||
* @param int (optional) An interval in the range 1-6
|
* @param int|null $number (optional) An interval in the range 1-6
|
||||||
* @param string (optional) One of day, week, month or year. If empty, all subscription ranges are returned.
|
* @param string|null $period (optional) One of day, week, month or year. If empty, all subscription ranges are returned.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
function wcs_get_subscription_trial_period_strings( $number = 1, $period = '' ) {
|
function wcs_get_subscription_trial_period_strings( $number = 1, $period = '' ) {
|
||||||
@@ -123,10 +123,10 @@ function wcs_get_non_cached_subscription_ranges() {
|
|||||||
/**
|
/**
|
||||||
* Retaining the API, it makes use of the transient functionality.
|
* Retaining the API, it makes use of the transient functionality.
|
||||||
*
|
*
|
||||||
* @param string $period
|
* @param string $subscription_period
|
||||||
* @return bool|mixed
|
* @return bool|mixed
|
||||||
*/
|
*/
|
||||||
function wcs_get_subscription_ranges( $subscription_period = '' ) {
|
function wcs_get_subscription_ranges( $subscription_period = null ) {
|
||||||
static $subscription_locale_ranges = array();
|
static $subscription_locale_ranges = array();
|
||||||
|
|
||||||
if ( ! is_string( $subscription_period ) ) {
|
if ( ! is_string( $subscription_period ) ) {
|
||||||
@@ -151,10 +151,10 @@ function wcs_get_subscription_ranges( $subscription_period = '' ) {
|
|||||||
/**
|
/**
|
||||||
* Return an i18n'ified associative array of all possible subscription periods.
|
* Return an i18n'ified associative array of all possible subscription periods.
|
||||||
*
|
*
|
||||||
* @param int (optional) An interval in the range 1-6
|
* @param int|null $interval (optional) An interval in the range 1-6
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
function wcs_get_subscription_period_interval_strings( $interval = '' ) {
|
function wcs_get_subscription_period_interval_strings( $interval = null ) {
|
||||||
|
|
||||||
$intervals = array( 1 => _x( 'every', 'period interval (eg "$10 _every_ 2 weeks")', 'woocommerce-subscriptions' ) );
|
$intervals = array( 1 => _x( 'every', 'period interval (eg "$10 _every_ 2 weeks")', 'woocommerce-subscriptions' ) );
|
||||||
|
|
||||||
@@ -175,7 +175,7 @@ function wcs_get_subscription_period_interval_strings( $interval = '' ) {
|
|||||||
/**
|
/**
|
||||||
* Return an i18n'ified associative array of all time periods allowed for subscriptions.
|
* Return an i18n'ified associative array of all time periods allowed for subscriptions.
|
||||||
*
|
*
|
||||||
* @param string (Optional) Either 'singular' for singular trial periods or 'plural'.
|
* @param string|null $form (Optional) Either 'singular' for singular trial periods or 'plural'.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
function wcs_get_available_time_periods( $form = 'singular' ) {
|
function wcs_get_available_time_periods( $form = 'singular' ) {
|
||||||
@@ -199,7 +199,7 @@ function wcs_get_available_time_periods( $form = 'singular' ) {
|
|||||||
/**
|
/**
|
||||||
* Returns an array of allowed trial period lengths.
|
* Returns an array of allowed trial period lengths.
|
||||||
*
|
*
|
||||||
* @param string (optional) One of day, week, month or year. If empty, all subscription trial period lengths are returned.
|
* @param string|null $subscription_period (optional) One of day, week, month or year. If empty, all subscription trial period lengths are returned.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
function wcs_get_subscription_trial_lengths( $subscription_period = '' ) {
|
function wcs_get_subscription_trial_lengths( $subscription_period = '' ) {
|
||||||
@@ -264,6 +264,7 @@ function wcs_add_months( $from_timestamp, $months_to_add, $timezone_behaviour =
|
|||||||
|
|
||||||
$first_day_of_month = gmdate( 'Y-m', $from_timestamp ) . '-1';
|
$first_day_of_month = gmdate( 'Y-m', $from_timestamp ) . '-1';
|
||||||
$days_in_next_month = gmdate( 't', wcs_strtotime_dark_knight( "+ {$months_to_add} month", wcs_date_to_time( $first_day_of_month ) ) );
|
$days_in_next_month = gmdate( 't', wcs_strtotime_dark_knight( "+ {$months_to_add} month", wcs_date_to_time( $first_day_of_month ) ) );
|
||||||
|
$next_timestamp = 0;
|
||||||
|
|
||||||
// Payment is on the last day of the month OR number of days in next billing month is less than the the day of this month (i.e. current billing date is 30th January, next billing date can't be 30th February)
|
// Payment is on the last day of the month OR number of days in next billing month is less than the the day of this month (i.e. current billing date is 30th January, next billing date can't be 30th February)
|
||||||
if ( gmdate( 'd m Y', $from_timestamp ) === gmdate( 't m Y', $from_timestamp ) || gmdate( 'd', $from_timestamp ) > $days_in_next_month ) {
|
if ( gmdate( 'd m Y', $from_timestamp ) === gmdate( 't m Y', $from_timestamp ) || gmdate( 'd', $from_timestamp ) > $days_in_next_month ) {
|
||||||
@@ -316,6 +317,8 @@ function wcs_estimate_periods_between( $start_timestamp, $end_timestamp, $unit_o
|
|||||||
|
|
||||||
$seconds_until_timestamp = $end_timestamp - $start_timestamp;
|
$seconds_until_timestamp = $end_timestamp - $start_timestamp;
|
||||||
|
|
||||||
|
$denominator = 0;
|
||||||
|
|
||||||
switch ( $unit_of_time ) {
|
switch ( $unit_of_time ) {
|
||||||
|
|
||||||
case 'day':
|
case 'day':
|
||||||
@@ -333,6 +336,7 @@ function wcs_estimate_periods_between( $start_timestamp, $end_timestamp, $unit_o
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @phpstan-ignore-next-line
|
||||||
$periods_until = ( 'ceil' == $rounding_method ) ? ceil( $seconds_until_timestamp / $denominator ) : floor( $seconds_until_timestamp / $denominator );
|
$periods_until = ( 'ceil' == $rounding_method ) ? ceil( $seconds_until_timestamp / $denominator ) : floor( $seconds_until_timestamp / $denominator );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -629,7 +633,7 @@ function wcs_is_datetime_mysql_format( $time ) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$format = 'Y-m-d H:i:s';
|
$format = wcs_get_db_datetime_format();
|
||||||
|
|
||||||
$date_object = DateTime::createFromFormat( $format, $time );
|
$date_object = DateTime::createFromFormat( $format, $time );
|
||||||
|
|
||||||
@@ -642,6 +646,26 @@ function wcs_is_datetime_mysql_format( $time ) {
|
|||||||
&& (int) $date_object->format( 'Y' ) >= 1900;
|
&& (int) $date_object->format( 'Y' ) >= 1900;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a value is a valid timestamp.
|
||||||
|
*
|
||||||
|
* @param int|string $timestamp The value to check. Only integers and strings are allowed.
|
||||||
|
* @return bool True if the value is a valid timestamp, false otherwise.
|
||||||
|
*/
|
||||||
|
function wcs_is_timestamp( $timestamp ) {
|
||||||
|
// Only accept integers and strings
|
||||||
|
if ( ! is_int( $timestamp ) && ! is_string( $timestamp ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$str = (string) $timestamp;
|
||||||
|
|
||||||
|
// Match valid timestamp patterns: integers, negative integers, or their string equivalents
|
||||||
|
// Allows: 123, -123, '123', '-123', 0, '0'
|
||||||
|
// Rejects: +123, 0123, 12.34, 1e10, ' 123', '123 ', scientific notation, newlines, etc.
|
||||||
|
return (bool) preg_match( '/\A-?(?:0|[1-9]\d*)\z/', $str );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a date string into a timestamp without ever adding or deducting time.
|
* Convert a date string into a timestamp without ever adding or deducting time.
|
||||||
*
|
*
|
||||||
@@ -656,8 +680,8 @@ function wcs_is_datetime_mysql_format( $time ) {
|
|||||||
*
|
*
|
||||||
* This makes sure the date is never converted.
|
* This makes sure the date is never converted.
|
||||||
*
|
*
|
||||||
* @param string $date_string A date string formatted in MySQl or similar format that will map correctly when instantiating an instance of DateTime()
|
* @param string $date_string A date string acceptable by DateTime() or a timestamp.
|
||||||
* @return int Unix timestamp representation of the timestamp passed in without any changes for timezones
|
* @return int|null Unix timestamp representation of the timestamp passed in without any changes for timezones, or null if the date string is invalid.
|
||||||
*/
|
*/
|
||||||
function wcs_date_to_time( $date_string ) {
|
function wcs_date_to_time( $date_string ) {
|
||||||
|
|
||||||
@@ -665,7 +689,16 @@ function wcs_date_to_time( $date_string ) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
$date_time = new WC_DateTime( $date_string, new DateTimeZone( 'UTC' ) );
|
try {
|
||||||
|
if ( is_numeric( $date_string ) ) {
|
||||||
|
$date_time = new WC_DateTime( 'now', new DateTimeZone( 'UTC' ) );
|
||||||
|
$date_time->setTimestamp( (int) $date_string );
|
||||||
|
} else {
|
||||||
|
$date_time = new WC_DateTime( $date_string, new DateTimeZone( 'UTC' ) );
|
||||||
|
}
|
||||||
|
} catch ( \Throwable $e ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return intval( $date_time->getTimestamp() );
|
return intval( $date_time->getTimestamp() );
|
||||||
}
|
}
|
||||||
@@ -706,6 +739,7 @@ function wcs_strtotime_dark_knight( $time_string, $from_timestamp = null ) {
|
|||||||
* @return int the number of days in that billing cycle
|
* @return int the number of days in that billing cycle
|
||||||
*/
|
*/
|
||||||
function wcs_get_days_in_cycle( $period, $interval ) {
|
function wcs_get_days_in_cycle( $period, $interval ) {
|
||||||
|
$days_in_cycle = 0;
|
||||||
|
|
||||||
switch ( $period ) {
|
switch ( $period ) {
|
||||||
case 'day':
|
case 'day':
|
||||||
@@ -805,7 +839,6 @@ function wcs_get_sites_timezone() {
|
|||||||
* M – for months; allowable range is 1 to 24
|
* M – for months; allowable range is 1 to 24
|
||||||
* Y – for years; allowable range is 1 to 5
|
* Y – for years; allowable range is 1 to 5
|
||||||
*
|
*
|
||||||
* @param string (optional) One of day, week, month or year. If empty, all subscription ranges are returned.
|
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
*/
|
*/
|
||||||
function wcs_get_subscription_ranges_tlc() {
|
function wcs_get_subscription_ranges_tlc() {
|
||||||
@@ -819,7 +852,7 @@ function wcs_get_subscription_ranges_tlc() {
|
|||||||
* a WC_Datetime object when WC > 3.0 is active) and create a WC_DateTime object.
|
* a WC_Datetime object when WC > 3.0 is active) and create a WC_DateTime object.
|
||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0
|
||||||
* @param string|integer|null $date UTC timestamp, or ISO 8601 DateTime. If the DateTime string has no timezone or offset, WordPress site timezone will be assumed. Null if their is no date.
|
* @param string|integer|null $variable_date_type UTC timestamp, or ISO 8601 DateTime. If the DateTime string has no timezone or offset, WordPress site timezone will be assumed. Null if their is no date.
|
||||||
* @return null|WC_DateTime in site's timezone
|
* @return null|WC_DateTime in site's timezone
|
||||||
*/
|
*/
|
||||||
function wcs_get_datetime_from( $variable_date_type ) {
|
function wcs_get_datetime_from( $variable_date_type ) {
|
||||||
@@ -846,13 +879,22 @@ function wcs_get_datetime_from( $variable_date_type ) {
|
|||||||
* Get a MySQL date/time string in UTC timezone from a WC_Datetime object.
|
* Get a MySQL date/time string in UTC timezone from a WC_Datetime object.
|
||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0
|
||||||
* @param WC_DateTime
|
* @param WC_DateTime $datetime
|
||||||
* @return string MySQL date/time string representation of the DateTime object in UTC timezone
|
* @return string MySQL date/time string representation of the DateTime object in UTC timezone
|
||||||
*/
|
*/
|
||||||
function wcs_get_datetime_utc_string( $datetime ) {
|
function wcs_get_datetime_utc_string( $datetime ) {
|
||||||
$date = clone $datetime; // Don't change the original date object's timezone
|
$date = clone $datetime; // Don't change the original date object's timezone
|
||||||
$date->setTimezone( new DateTimeZone( 'UTC' ) );
|
$date->setTimezone( new DateTimeZone( 'UTC' ) );
|
||||||
return $date->format( 'Y-m-d H:i:s' );
|
return $date->format( wcs_get_db_datetime_format() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the datetime format used in the database.
|
||||||
|
*
|
||||||
|
* @return string The datetime format used in the database. Default: Y-m-d H:i:s.
|
||||||
|
*/
|
||||||
|
function wcs_get_db_datetime_format() {
|
||||||
|
return 'Y-m-d H:i:s';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -46,7 +46,7 @@ function wcs_maybe_make_user_inactive( $user_id ) {
|
|||||||
* Handy for hooks that pass a subscription object.
|
* Handy for hooks that pass a subscription object.
|
||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.9
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.9
|
||||||
* @param WC_Subscription|WC_Order
|
* @param WC_Subscription|WC_Order $subscription
|
||||||
*/
|
*/
|
||||||
function wcs_maybe_make_user_inactive_for( $subscription ) {
|
function wcs_maybe_make_user_inactive_for( $subscription ) {
|
||||||
wcs_maybe_make_user_inactive( $subscription->get_user_id() );
|
wcs_maybe_make_user_inactive( $subscription->get_user_id() );
|
||||||
@@ -130,7 +130,7 @@ function wcs_get_new_user_role_names( $role_new ) {
|
|||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
function wcs_user_has_subscription( $user_id = 0, $product_id = '', $status = 'any' ) {
|
function wcs_user_has_subscription( $user_id = 0, $product_id = 0, $status = 'any' ) {
|
||||||
|
|
||||||
$subscriptions = wcs_get_users_subscriptions( $user_id );
|
$subscriptions = wcs_get_users_subscriptions( $user_id );
|
||||||
|
|
||||||
@@ -170,7 +170,7 @@ function wcs_user_has_subscription( $user_id = 0, $product_id = '', $status = 'a
|
|||||||
* @return WC_Subscription[]
|
* @return WC_Subscription[]
|
||||||
*/
|
*/
|
||||||
function wcs_get_users_subscriptions( $user_id = 0 ) {
|
function wcs_get_users_subscriptions( $user_id = 0 ) {
|
||||||
if ( 0 === $user_id || empty( $user_id ) ) {
|
if ( 0 === $user_id ) {
|
||||||
$user_id = get_current_user_id();
|
$user_id = get_current_user_id();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,7 +185,7 @@ function wcs_get_users_subscriptions( $user_id = 0 ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( empty( $subscriptions ) && 0 !== $user_id && ! empty( $user_id ) ) {
|
if ( empty( $subscriptions ) && 0 !== $user_id ) {
|
||||||
$subscription_ids = WCS_Customer_Store::instance()->get_users_subscription_ids( $user_id );
|
$subscription_ids = WCS_Customer_Store::instance()->get_users_subscription_ids( $user_id );
|
||||||
|
|
||||||
foreach ( $subscription_ids as $subscription_id ) {
|
foreach ( $subscription_ids as $subscription_id ) {
|
||||||
|
@@ -36,6 +36,7 @@ class WCS_Retry_Table_Maker extends WCS_Table_Maker {
|
|||||||
*/
|
*/
|
||||||
protected function get_table_definition( $table ) {
|
protected function get_table_definition( $table ) {
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
|
// phpcs:disable QITStandard.DB.DynamicWpdbMethodCall.DynamicMethod
|
||||||
$table_name = $wpdb->$table;
|
$table_name = $wpdb->$table;
|
||||||
$charset_collate = $wpdb->get_charset_collate();
|
$charset_collate = $wpdb->get_charset_collate();
|
||||||
|
|
||||||
|
@@ -112,6 +112,12 @@ class WCS_Switch_Cart_Item {
|
|||||||
*/
|
*/
|
||||||
public $is_switch_after_fully_reduced_prepaid_term;
|
public $is_switch_after_fully_reduced_prepaid_term;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The last switch order for this subscription.
|
||||||
|
* @var WC_Order|null
|
||||||
|
*/
|
||||||
|
private $switch_order = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
@@ -263,12 +269,19 @@ class WCS_Switch_Cart_Item {
|
|||||||
public function get_total_paid_for_current_period() {
|
public function get_total_paid_for_current_period() {
|
||||||
|
|
||||||
if ( ! isset( $this->total_paid_for_current_period ) ) {
|
if ( ! isset( $this->total_paid_for_current_period ) ) {
|
||||||
|
$orders_to_include = array();
|
||||||
|
|
||||||
// If the last order was a switch with a fully reduced pre-paid term, the amount the customer has paid is just the total in that order.
|
// If the last order was a switch with a fully reduced pre-paid term, the amount the customer has paid is just the total in that order.
|
||||||
if ( $this->is_switch_after_fully_reduced_prepaid_term() ) {
|
if ( $this->is_switch_after_fully_reduced_prepaid_term() ) {
|
||||||
$this->total_paid_for_current_period = WC_Subscriptions_Switcher::calculate_total_paid_since_last_order( $this->subscription, $this->existing_item, 'exclude_sign_up_fees', array( $this->get_last_switch_order() ) );
|
$orders_to_include[] = $this->get_last_switch_order();
|
||||||
} else {
|
|
||||||
$this->total_paid_for_current_period = WC_Subscriptions_Switcher::calculate_total_paid_since_last_order( $this->subscription, $this->existing_item, 'exclude_sign_up_fees' );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->total_paid_for_current_period = WC_Subscriptions_Switcher::calculate_total_paid_since_last_order(
|
||||||
|
$this->subscription,
|
||||||
|
$this->existing_item,
|
||||||
|
'exclude_sign_up_fees',
|
||||||
|
$orders_to_include
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return apply_filters( 'wcs_switch_total_paid_for_current_period', $this->total_paid_for_current_period, $this->subscription, $this->existing_item );
|
return apply_filters( 'wcs_switch_total_paid_for_current_period', $this->total_paid_for_current_period, $this->subscription, $this->existing_item );
|
||||||
@@ -443,13 +456,11 @@ class WCS_Switch_Cart_Item {
|
|||||||
* @return WC_Order|Null The last switch order or null if one doesn't exist.
|
* @return WC_Order|Null The last switch order or null if one doesn't exist.
|
||||||
*/
|
*/
|
||||||
protected function get_last_switch_order() {
|
protected function get_last_switch_order() {
|
||||||
static $switch_order = null;
|
if ( ! $this->switch_order ) {
|
||||||
|
$this->switch_order = $this->subscription->get_last_order( 'all', 'switch', array( 'checkout-draft' ) );
|
||||||
if ( ! $switch_order ) {
|
|
||||||
$switch_order = $this->subscription->get_last_order( 'all', 'switch', [ 'checkout-draft' ] );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $switch_order;
|
return $this->switch_order;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -473,34 +484,47 @@ class WCS_Switch_Cart_Item {
|
|||||||
protected function is_switch_after_fully_reduced_prepaid_term() {
|
protected function is_switch_after_fully_reduced_prepaid_term() {
|
||||||
|
|
||||||
if ( ! isset( $this->is_switch_after_fully_reduced_prepaid_term ) ) {
|
if ( ! isset( $this->is_switch_after_fully_reduced_prepaid_term ) ) {
|
||||||
$last_switch_order = $this->get_last_switch_order();
|
$this->is_switch_after_fully_reduced_prepaid_term = $this->calculate_is_switch_after_fully_reduced_prepaid_term();
|
||||||
|
|
||||||
if ( empty( $last_switch_order ) || ! $last_switch_order->get_date_paid() ) {
|
|
||||||
$this->is_switch_after_fully_reduced_prepaid_term = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$switch_paid_date = $last_switch_order->get_date_paid();
|
|
||||||
|
|
||||||
// If the last switch order occurred before the last payment order (parent or renewal), then the last order wasn't a switch.
|
|
||||||
if ( $switch_paid_date->getTimestamp() < $this->get_last_order_paid_time() ) {
|
|
||||||
$this->is_switch_after_fully_reduced_prepaid_term = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the last switch resulted in the customer being charged the pull cost upfront, the customer must have been entitled to fewer days than had already elapsed - see reduce_prepaid_term().
|
|
||||||
* This means the subscription billing term would have started from that switch order's date, not the last order (parent/renewal) date.
|
|
||||||
*/
|
|
||||||
$first_payment_after_switch = WC_Subscriptions_Product::get_first_renewal_payment_time( $this->existing_item->get_product(), gmdate( 'Y-m-d H:i:s', $switch_paid_date->format( 'U' ) ) );
|
|
||||||
|
|
||||||
// If the first payment date after the last switch is roughly equal (+- 1 hour) to the next payment date, then it was a fully reduced pre-paid term switch.
|
|
||||||
$this->is_switch_after_fully_reduced_prepaid_term = ( $this->next_payment_timestamp - HOUR_IN_SECONDS <= $first_payment_after_switch ) && ( $first_payment_after_switch <= $this->next_payment_timestamp + HOUR_IN_SECONDS );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->is_switch_after_fully_reduced_prepaid_term;
|
return $this->is_switch_after_fully_reduced_prepaid_term;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates whether the last order was a switch and it fully reduced the prepaid term.
|
||||||
|
*
|
||||||
|
* @since 7.6.0
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function calculate_is_switch_after_fully_reduced_prepaid_term() {
|
||||||
|
$last_switch_order = $this->get_last_switch_order();
|
||||||
|
|
||||||
|
// If there is no last switch order or it hasn't been paid for, the customer hasn't switched before.
|
||||||
|
// Therefore, this can't be a switch after a fully reduced prepaid term.
|
||||||
|
if ( empty( $last_switch_order ) || ! $last_switch_order->get_date_paid() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$switch_paid_date = $last_switch_order->get_date_paid();
|
||||||
|
|
||||||
|
// If the last switch order occurred before the last payment order (parent or renewal), then the last order wasn't a switch.
|
||||||
|
if ( $switch_paid_date->getTimestamp() < $this->get_last_order_paid_time() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the last switch resulted in the customer being charged the pull cost upfront, the customer must have been entitled to fewer days than had already elapsed - see reduce_prepaid_term().
|
||||||
|
* This means the subscription billing term would have started from that switch order's date, not the last order (parent/renewal) date.
|
||||||
|
*/
|
||||||
|
$first_payment_after_switch = WC_Subscriptions_Product::get_first_renewal_payment_time(
|
||||||
|
$this->existing_item->get_product(),
|
||||||
|
gmdate( 'Y-m-d H:i:s', $switch_paid_date->format( 'U' ) )
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check if the first payment after switch is within 1 hour of the next payment timestamp.
|
||||||
|
return abs( $first_payment_after_switch - $this->next_payment_timestamp ) <= HOUR_IN_SECONDS;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether the customer is switching to a subscription with a length of 1 - one off payment.
|
* Determines whether the customer is switching to a subscription with a length of 1 - one off payment.
|
||||||
*
|
*
|
||||||
|
File diff suppressed because it is too large
Load Diff
41
phpstan.neon
41
phpstan.neon
@@ -2,12 +2,51 @@ parameters:
|
|||||||
excludePaths:
|
excludePaths:
|
||||||
analyse:
|
analyse:
|
||||||
- includes/api/legacy/*
|
- includes/api/legacy/*
|
||||||
|
- includes/core/legacy/*
|
||||||
|
- templates/*
|
||||||
|
- includes/core/upgrades/*
|
||||||
|
- includes/core/emails/*
|
||||||
|
- includes/core/gateways/paypal/*
|
||||||
|
- includes/core/data-stores/*
|
||||||
|
- includes/core/class-wcs-template-loader.php
|
||||||
ignoreErrors:
|
ignoreErrors:
|
||||||
- '#Access to an undefined property WC_Cart::\$recurring_carts#'
|
- '#Access to an undefined property WooCommerce::\$#'
|
||||||
|
- '#Access to an undefined property WC_Cart::\$#'
|
||||||
- '#Access to an undefined property WP_User::\$#'
|
- '#Access to an undefined property WP_User::\$#'
|
||||||
|
- '#Access to an undefined property WC_Checkout::\$#'
|
||||||
|
- '#Access to an undefined property WC_Shipping_Rate::\$#'
|
||||||
|
- '#Access to an undefined property WC_Subscription_Legacy::\$#'
|
||||||
|
- '#Access to an undefined property WC_Product_Variable_Subscription_Legacy::\$#'
|
||||||
|
- '#Access to an undefined property WC_Product_Subscription_Variation_Legacy::\$#'
|
||||||
|
- '#Access to an undefined property WC_Product_Subscription_Legacy::\$#'
|
||||||
|
- '#Access to an undefined property WCS_PayPal_Reference_Transaction_API::\$#'
|
||||||
|
- '#Access to an undefined property WC_Email::\$#'
|
||||||
|
- '#Access to an undefined property WC_Subscriptions_Deprecation_Handler::\$#'
|
||||||
|
- '#Access to an undefined property WC_Session::\$#'
|
||||||
|
- '#Access to an undefined static property WC_Subscriptions_Deprecation_Handler::\$#'
|
||||||
|
- '#Access to an undefined property WooCommerce::\$payment_gateways#'
|
||||||
- '#Call to an undefined method WC_Order_Item::get_product#'
|
- '#Call to an undefined method WC_Order_Item::get_product#'
|
||||||
- '#Call to an undefined method WC_Order_Item::get_variation_id#'
|
- '#Call to an undefined method WC_Order_Item::get_variation_id#'
|
||||||
- '#Call to an undefined method WCS_Retry_Store::#'
|
- '#Call to an undefined method WCS_Retry_Store::#'
|
||||||
- '#Call to an undefined method WC_Data_Store::#'
|
- '#Call to an undefined method WC_Data_Store::#'
|
||||||
|
- '#Call to an undefined method WC_Session::#'
|
||||||
|
- '#Call to an undefined method WC_Order_Data_Store_CPT::delete_all_metadata_by_key#'
|
||||||
|
- '#Call to an undefined method object::get_coupons#'
|
||||||
|
- '#Call to an undefined method object::get_changes#'
|
||||||
|
- '#Call to method .* on an unknown class WC_PayPal_Express_API#'
|
||||||
|
- '#Call to method .* on an unknown class OrdersTableQuery#'
|
||||||
|
- '#Call to method .* on an unknown class ActionScheduler_Action#'
|
||||||
|
- '#Call to static method .* on an unknown class ActionScheduler_.*#'
|
||||||
|
- '#Access to property .* on an unknown class WC_Gateway#'
|
||||||
|
- '#Access to an undefined property object::\$discount_cart#'
|
||||||
|
- '#Access to an undefined property object::\$value#'
|
||||||
- '#Variable \$this might not be defined#'
|
- '#Variable \$this might not be defined#'
|
||||||
- '#Function as_.*_action not found#'
|
- '#Function as_.*_action not found#'
|
||||||
|
- '#Function as_.*_actions not found#'
|
||||||
|
- '#Parameter .* has invalid type WC_Gateway#'
|
||||||
|
- '#Parameter .* has invalid type ActionScheduler_.*#'
|
||||||
|
- '#Class WC_Payments_Subscription_Service not found#'
|
||||||
|
- '#Class .*OrdersTableDataStore not found#'
|
||||||
|
- '#Parameter .* has invalid type OrdersTableQuery.#'
|
||||||
|
- '#Constant WC_VERSION not found#'
|
||||||
|
- '#Method .* has invalid return type ActionScheduler_.*#'
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user