posts_to_cot_migrator->migrate_orders( array( $order_id ) );
}
}
/**
* Handles deletion of auto-draft orders in sync with WP's own auto-draft deletion.
*
* @since 7.7.0
*
* @return void
*/
private function delete_auto_draft_orders() {
if ( ! $this->custom_orders_table_is_authoritative() ) {
return;
}
// Fetch auto-draft orders older than 1 week.
$to_delete = wc_get_orders(
array(
'date_query' => array(
array(
'column' => 'date_created',
'before' => '-1 week',
),
),
'orderby' => 'date',
'order' => 'ASC',
'status' => 'auto-draft',
)
);
foreach ( $to_delete as $order ) {
$order->delete( true );
}
/**
* Fires after schedueld deletion of auto-draft orders has been completed.
*
* @since 7.7.0
*/
do_action( 'woocommerce_scheduled_auto_draft_delete' );
}
/**
* Handles deletion of trashed orders after `EMPTY_TRASH_DAYS` as defined by WordPress.
*
* @since 8.5.0
*
* @return void
*/
private function delete_trashed_orders() {
if ( ! $this->custom_orders_table_is_authoritative() ) {
return;
}
$delete_timestamp = $this->legacy_proxy->call_function( 'time' ) - ( DAY_IN_SECONDS * EMPTY_TRASH_DAYS );
$args = array(
'status' => 'trash',
'limit' => self::ORDERS_SYNC_BATCH_SIZE,
'date_modified' => '<' . $delete_timestamp,
);
$orders = wc_get_orders( $args );
if ( ! $orders || ! is_array( $orders ) ) {
return;
}
foreach ( $orders as $order ) {
if ( $order->get_status() !== 'trash' ) {
continue;
}
if ( $order->get_date_modified()->getTimestamp() >= $delete_timestamp ) {
continue;
}
$order->delete( true );
}
}
/**
* Handle the 'woocommerce_feature_description_tip' filter.
*
* When the COT feature is enabled and there are orders pending sync (in either direction),
* show a "you should ync before disabling" warning under the feature in the features page.
* Skip this if the UI prevents changing the feature enable status.
*
* @param string $desc_tip The original description tip for the feature.
* @param string $feature_id The feature id.
* @param bool $ui_disabled True if the UI doesn't allow to enable or disable the feature.
* @return string The new description tip for the feature.
*/
private function handle_feature_description_tip( $desc_tip, $feature_id, $ui_disabled ): string {
if ( 'custom_order_tables' !== $feature_id || $ui_disabled ) {
return $desc_tip;
}
$features_controller = wc_get_container()->get( FeaturesController::class );
$feature_is_enabled = $features_controller->feature_is_enabled( 'custom_order_tables' );
if ( ! $feature_is_enabled ) {
return $desc_tip;
}
$pending_sync_count = $this->get_current_orders_pending_sync_count();
if ( ! $pending_sync_count ) {
return $desc_tip;
}
if ( $this->custom_orders_table_is_authoritative() ) {
$extra_tip = sprintf(
_n(
"⚠ There's one order pending sync from the orders table to the posts table. The feature shouldn't be disabled until this order is synchronized.",
"⚠ There are %1\$d orders pending sync from the orders table to the posts table. The feature shouldn't be disabled until these orders are synchronized.",
$pending_sync_count,
'woocommerce'
),
$pending_sync_count
);
} else {
$extra_tip = sprintf(
_n(
"⚠ There's one order pending sync from the posts table to the orders table. The feature shouldn't be disabled until this order is synchronized.",
"⚠ There are %1\$d orders pending sync from the posts table to the orders table. The feature shouldn't be disabled until these orders are synchronized.",
$pending_sync_count,
'woocommerce'
),
$pending_sync_count
);
}
$cot_settings_url = add_query_arg(
array(
'page' => 'wc-settings',
'tab' => 'advanced',
'section' => 'custom_data_stores',
),
admin_url( 'admin.php' )
);
/* translators: %s = URL of the custom data stores settings page */
$manage_cot_settings_link = sprintf( __( "Manage orders synchronization", 'woocommerce' ), $cot_settings_url );
return $desc_tip ? "{$desc_tip}
{$extra_tip} {$manage_cot_settings_link}" : "{$extra_tip} {$manage_cot_settings_link}";
}
}
=> false,
'filterable' => false,
'max' => '',
'min' => '',
);
}
public function get_defaults() {
return $this->get_default_fields();
}
public function get_default_fields() {
$fields = array();
/**
* Exclude from form actions to fix issue in myaccount edit billing and shipping form save
*/
$form_action = Helpers::get_form_action();
if ( 'account' !== $form_action && 'additional' !== $this->prefix ) {
$prefix = sprintf( '%s_', $this->prefix );
/**
* Fix nesting level
*/
remove_all_filters( 'woocommerce_' . $prefix . 'fields' );
$i = 0;
foreach ( WC()->countries->get_address_fields( '', $prefix ) as $key => $field ) {
$field['id'] = $i;
$field['key'] = $key;
$field['name'] = str_replace( $prefix, '', $key );
$fields[ $i ] = $field;
$i++;
}
}
return $fields;
}
public function get_fields() {
// (is_array($fields = $this->get_items())) {
$fields = $this->get_items();
if ( count( $fields ) ) {
foreach ( $fields as $field_id => $field ) {
$fields[ $field_id ] = apply_filters( 'wooccm_checkout_field_filter', $this->sanitize_field( $field_id, $field, $fields ), $field_id );
}
uasort( $fields, array( __CLASS__, 'order_fields' ) );
$fields = apply_filters( 'wooccm_' . $this->prefix . '_fields', $fields );
}
// }
return $fields;
}
public function update_fields( $fields ) {
if ( is_array( $fields ) ) {
foreach ( $fields as $field_id => $field ) {
if ( ! array_key_exists( 'name', $field ) ) {
return false;
}
}
// reorder array based on ids
ksort( $fields );
if ( $this->save_items( $fields ) ) {
return $fields;
}
}
return false;
}
public function delete_fields() {
$this->delete_checkout_field();
$this->delete();
$this->save_items( $this->get_default_fields() );
}
protected function delete_checkout_field( $field_id = null ) {
$fields_data = $this->get_fields();
if ( null !== $field_id ) {
foreach ( $fields_data as $field ) {
if ( $field['id'] == $field_id ) {
$fields_data = array( $field );
continue;
}
}
}
$users = get_users( array( 'fields' => array( 'ID' ) ) );
foreach ( $users as $user ) {
foreach ( $fields_data as $field ) {
delete_user_meta( $user->ID, $field['key'] );
}
}
}
// Field
// ---------------------------------------------------------------------------
public function add_field( $field_data ) {
return $this->add_item( $field_data );
}
public function get_field( $field_id ) {
return $this->get_item( $field_id );
}
public function update_field( $field_data ) {
return $this->update_item( $field_data );
}
public function delete_field( $field_id ) {
$this->delete_checkout_field( $field_id );
return $this->delete_item( $field_id );
}
// Sanitize
public function sanitize_field( $field_id, $field, $fields ) {
$field['id'] = $field_id;
if ( empty( $field['name'] ) ) {
$field['name'] = $this->get_name( $field_id );
if ( $this->duplicated_name( $field['name'], $fields ) ) {
$field['name'] .= 'b';
}
}
$field['key'] = $this->get_key( $this->prefix, $field['name'] );
if ( empty( $field['position'] ) && is_array( $field['class'] ) ) {
$position = array_intersect( (array) $field['class'], array( 'form-row-wide', 'form-row-first', 'form-row-last' ) );
if ( isset( $position[0] ) ) {
$field['position'] = $position[0];
} else {
$field['position'] = 'form-row-wide';
}
}
if ( empty( $field['order'] ) ) {
$field['order'] = $field_id + 1;
}
if ( ! empty( $field['conditional_parent_key'] ) ) {
if ( strpos( $field['conditional_parent_key'], $this->prefix ) === false ) {
$field['conditional_parent_key'] = sprintf( '%s_%s', $this->prefix, $field['conditional_parent_key'] );
}
if ( $field['conditional_parent_key'] == $field['key'] ) {
$field['conditional_parent_key'] = '';
}
}
if ( is_array( $field['options'] ) && count( $field['options'] ) > 1 ) {
uasort( $field['options'], array( __CLASS__, 'order_fields' ) );
}
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
$regex = $field['validate_regex'];
wp_unslash( $field );
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
$field['validate_regex'] = $regex;
return $field;
}
}