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; } }