Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save geekontheroad/57e524d5f2f6ddf07b2501a15d2a5f15 to your computer and use it in GitHub Desktop.
Save geekontheroad/57e524d5f2f6ddf07b2501a15d2a5f15 to your computer and use it in GitHub Desktop.
<?php
/**
* This class is to import orders/entries made through GF Product Addon into GS Product Configurator.
* Based on the GWiz_Batcher class included with the GS Product Configurator so this class will only work if the GS Product Configurator is also installed.
* The tool will log messages to the GS Product Configurator log file so ensure to enable logging before running this tool.
*
* INSTRUCTIONS
* - Copy the below class to your functions.php or code snippet plugin.
* - Navigate to the GS Product Configurator settings under the forms settings menu and you should see the new panel called 'WCGFPA Orders sync'
* - Press Start Batch to start the migration process.
* - Optional: Remove this class after usage.
*
* @link https://geekontheroad.com
* @link https://gravitywiz.com/documentation/gravity-shop-product-configurator/
* @author Johan d'Hollander
* @version 1.0
*/
if ( class_exists( '\GS_Product_Configurator\GWiz_Batcher' ) && ! class_exists( 'Gotrgs_Orders_Importer_WCGFPA' ) ) {
class Gotrgs_Orders_Importer_WCGFPA {
/**
* @var GWiz_Batcher Batcher instance.
*/
public $batcher = null;
public function __construct() {
// 20 priority since we'll be after 15 at this point
add_action( 'init', array( $this, 'register_batcher' ), 20 );
// Add a new panel to the plugin settings if enabled.
add_filter( 'gspc_plugin_settings_fields', array( $this, 'add_plugin_settings_panel' ) );
}
/**
* Adds a new panel to the GSPC plugin settings if enabled.
*
* @param mixed[] $plugin_settings
*
* @return mixed[]
*/
public function add_plugin_settings_panel( $plugin_settings ) {
/** @phpstan-ignore-next-line */
if ( ! $this->batcher ) {
$this->register_batcher();
}
$plugin_settings['wcgfpa_orders_sync'] = [
'title' => __( 'WCGFPA Orders sync', 'gs-product-configurator' ),
'description' => __( 'Sync order and entry data to GS Product configurator for orders made through WCGFPA.', 'gs-product-configurator' ),
'fields' => array(
'wcgfpa_orders_sync' => array(
'type' => 'html',
'html' => $this->batcher->render(),
),
),
];
return $plugin_settings;
}
/**
* Adds a GWiz Batcher to migrate order and entry data from WCGFPA to GSPC.
*
* This batcher is meant to be idempotent where if you re-run it, you'll get the same result given
* the same WCGFPA data.
*
* @return void
*/
function register_batcher() {
$this->batcher = new \GS_Product_Configurator\GWiz_Batcher( array(
'title' => __( 'WCGFPA to GSPC Order and Entry Migrator', 'gs-product-configurator' ),
'id' => 'wcgfpa-to-gspc-orders-migrator',
'create_admin_page' => false,
'size' => 20,
'get_items' => [ $this, 'get_batcher_items' ],
'process_item' => [ $this, 'batcher_process_item' ],
'on_finish' => function( $count, $total ) {
// Do nothing.
},
) );
}
/**
* Gets the items for the batcher.
*
* @param int $size
* @param int $offset
* @param int|null $form_id
*
* @return array{
* items: \WC_Product[],
* total: int,
* }
*/
public function get_batcher_items( $size, $offset, $form_id = null ) {
// Set up the query arguments for fetching orders
$args = array(
'limit' => $size,
'offset' => $offset,
'return' => 'objects',
);
// Get the orders using wc_get_orders
$orders = wc_get_orders( $args );
gs_product_configurator()->log_debug( __METHOD__ . ' total orders count ' . $total_orders );
// Return the array with items (orders) and total count
return array(
'items' => $orders, // This contains the array of WC_Order objects matching our arguments.
'total' => $this->get_total_order_count(),
);
}
/**
* Processes an order.
* We need to update the item data as well as the GF entry data.
*
* @param \WC_Product $product
*
* @return void
*/
public function batcher_process_item( $order ) {
if ( ! is_a( $order, 'WC_Order' ) ) {
return;
}
if ( count( $order->get_items() ) > 0 ) {
foreach ( $order->get_items() as $item_id => $item ) {
$gravity_forms_history = wc_get_order_item_meta($item_id, '_gravity_forms_history', true);
if (!empty($gravity_forms_history)) {
// Deserialize the serialized data
$history_data = maybe_unserialize($gravity_forms_history);
// Check if the linked entry ID and form ID exist in the data
if (isset($history_data['_gravity_form_linked_entry_id']) && isset($history_data['_gravity_form_lead']['form_id'])) {
$entry_id = $history_data['_gravity_form_linked_entry_id'];
$form_id = $history_data['_gravity_form_lead']['form_id'];
$product_id = $item->get_product_id();
$this->update_item_meta( $item_id, 'gspc_gf_entry_ids', array( $entry_id ) );
$this->update_item_meta( $item_id, 'gspc_gf_form_id', $form_id );
$this->update_entry_data( $entry_id, $order->get_id(), $product_id );
} else {
$this->log_processing_error( $order->get_id(), 'No linked entry ID or form ID found in order item' );
continue;
}
} else {
$this->log_processing_error( $order->get_id(), 'No Gravity Forms history found in order item' );
continue;
}
}
} else {
$this->log_processing_error( $order->get_id(), 'No items found in order' );
}
}
/**
* Update the item meta data.
*
* @param int $item_id
* @param string $meta_key
* @param mixed $meta_value
*
* @return void
*/
private function update_item_meta( $item_id, $meta_key, $meta_value ) {
wc_update_order_item_meta( $item_id, $meta_key, $meta_value );
}
/**
* Update the entry data.
*
* @param int $entry_id
* @param int $order_id
* @param int $product_id
*
* @return void
*/
private function update_entry_data( $entry_id, $order_id, $product_id ) {
$entry = GFAPI::get_entry( $entry_id );
if ( is_wp_error( $entry ) ) {
$this->log_processing_error( $order_id, sprintf( 'Failed to get entry %s: %s', $entry_id, $entry->get_error_message() ) );
return;
}
$entry['transaction_id'] = $order_id;
$entry['gspc_wc_order_item_id'] = $order_id;
$entry['gspc_wc_product_id'] = $product_id;
$updated = GFAPI::update_entry( $entry );
if ( is_wp_error( $updated ) ) {
$this->log_processing_error( $order_id, sprintf( 'Failed to update entry %s: %s', $entry_id, $updated->get_error_message() ) );
}
}
/**
* Log processing error.
*
* @param int $order_id
* @param string $error_message
*
* @return void
*/
private function log_processing_error( $order_id, $error_message ) {
gs_product_configurator()->log_debug( __METHOD__ . '():' . sprintf( 'Failed to process order %s: %s', $order_id, $error_message ) );
}
/**
* Get the total order count.
*
* @return int
*/
private function get_total_order_count() {
$order_statuses = wc_get_order_statuses();
$count = 0;
foreach( array_keys( $order_statuses ) as $status_key ) {
$count += wc_orders_count( str_replace( 'wc-', '', $status_key ) );
}
return $count;
}
}
new Gotrgs_Orders_Importer_WCGFPA();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment