-
Notifications
You must be signed in to change notification settings - Fork 91
gspc-map-order-data-to-entry.php
: Added snippet to map order data to entry.
#1106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
WalkthroughA new PHP class, Changes
Sequence Diagram(s)sequenceDiagram
participant Customer
participant WooCommerce
participant GSPC_Map_Order_Data_to_Entry
participant GS_Product_Configurator
participant Gravity_Forms
Customer->>WooCommerce: Complete checkout
WooCommerce->>GSPC_Map_Order_Data_to_Entry: Trigger woocommerce_checkout_order_processed
GSPC_Map_Order_Data_to_Entry->>GS_Product_Configurator: Get Gravity Forms entries for order items
GSPC_Map_Order_Data_to_Entry->>Gravity_Forms: Retrieve form and field objects
GSPC_Map_Order_Data_to_Entry->>WooCommerce: Fetch mapped order data values
GSPC_Map_Order_Data_to_Entry->>Gravity_Forms: Update entry fields with order data
Gravity_Forms-->>GSPC_Map_Order_Data_to_Entry: Confirm entry update
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (3)
gs-product-configurator/gspc-map-order-data-to-entry.php (3)
52-63
: Consider adding logging for debugging purposes.While the code correctly processes order items and entries, consider adding optional logging capability to help with troubleshooting when entries aren't being updated as expected.
if ( $this->_args['form_id'] && $this->_args['form_id'] != $entry['form_id'] ) { + // Optional debug logging could be added here continue; } $form = GFAPI::get_form( $entry['form_id'] ); $entry_updated = false;
89-102
: Consider extending special case handling with more order properties.The method handles common order properties but could be extended to support more properties directly rather than relying on nested data access. This would make the API more intuitive for users.
private function get_value_from_order( $order, $data_key ) { $order_data = $order->get_data(); switch ( $data_key ) { case 'id': return $order->get_id(); case 'email': return $order->get_billing_email(); case 'status': return $order->get_status(); case 'total': return $order->get_total(); + case 'date_created': + return $order->get_date_created()->format('Y-m-d H:i:s'); + case 'payment_method': + return $order->get_payment_method_title(); + case 'currency': + return $order->get_currency(); }
120-131
: Provide more context around the example configuration.The example configuration is helpful but could benefit from additional context about needing to be customized. Also, it would be beneficial to ensure users understand this code needs to be modified and is currently active.
# Configuration -new GSPC_Map_Order_Data_to_Entry( array( +/** + * Example configuration - IMPORTANT: Modify with your own form ID and field mappings + * Remove or comment out this instantiation if you're not ready to use it yet. + */ +$gspc_order_mapping = new GSPC_Map_Order_Data_to_Entry( array( 'form_id' => 123, // Replace with your form ID 'field_map' => array( '2' => 'id', // Field ID 2 will store the order ID '3.3' => 'billing/first_name', // Field ID 3, input 3 (first name) '3.6' => 'billing/last_name', // Field ID 3, input 6 (last name) '4' => 'email', // Field ID 4 will store the email '5' => 'total', // Field ID 5 will store the order total ), ) );
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
gs-product-configurator/gspc-map-order-data-to-entry.php
(1 hunks)
🔇 Additional comments (5)
gs-product-configurator/gspc-map-order-data-to-entry.php (5)
17-29
: Well-structured class initialization with proper hooks.The class is well-organized with constructor parameters and default values. The use of
wp_parse_args()
for merging defaults with provided arguments is a good practice.
31-40
: Good dependency checking before proceeding with initialization.The code properly verifies the existence of required classes before adding hooks, which prevents potential errors if dependencies are missing.
42-51
: Robust order validation.The method appropriately verifies that we have a valid WC_Order object before proceeding with any operations.
64-80
: Field key parsing logic looks good.The code correctly handles both simple field IDs and complex inputs with dot notation. The null check before updating entries prevents adding empty values.
104-117
: Robust nested data retrieval implementation.The nested data retrieval logic is well-implemented, with proper null checks to prevent PHP notices or warnings when accessing non-existent data paths.
private $_args = array(); | ||
|
||
public function __construct( $args = array() ) { | ||
|
||
$this->_args = wp_parse_args( $args, array( | ||
'form_id' => false, | ||
'field_map' => array(), | ||
) ); | ||
|
||
add_action( 'init', array( $this, 'init' ) ); | ||
} | ||
|
||
public function init() { | ||
|
||
if ( ! property_exists( 'GFCommon', 'version' ) || | ||
! class_exists( '\GS_Product_Configurator\WC_Order_Item' ) || | ||
! class_exists( 'GFAPI' ) ) { | ||
return; | ||
} | ||
|
||
add_action( 'woocommerce_checkout_order_processed', array( $this, 'map_order_data_to_entries' ), 10, 3 ); | ||
} | ||
|
||
public function map_order_data_to_entries( $order_id, $posted_data, $order ) { | ||
|
||
if ( ! $order instanceof WC_Order ) { | ||
$order = wc_get_order( $order_id ); | ||
} | ||
|
||
if ( ! $order ) { | ||
return; | ||
} | ||
|
||
foreach ( $order->get_items() as $item ) { | ||
$gspc_order_item = \GS_Product_Configurator\WC_Order_Item::from( $item ); | ||
|
||
foreach ( $gspc_order_item->get_entries() as $entry ) { | ||
|
||
if ( $this->_args['form_id'] && $this->_args['form_id'] != $entry['form_id'] ) { | ||
continue; | ||
} | ||
|
||
$form = GFAPI::get_form( $entry['form_id'] ); | ||
$entry_updated = false; | ||
|
||
foreach ( $this->_args['field_map'] as $field_key => $data_key ) { | ||
|
||
$field_id = strpos( $field_key, '.' ) !== false ? | ||
explode( '.', $field_key )[0] : | ||
$field_key; | ||
|
||
$field = GFFormsModel::get_field( $form, $field_id ); | ||
if ( ! $field ) { | ||
continue; | ||
} | ||
|
||
$value = $this->get_value_from_order( $order, $data_key ); | ||
if ( $value !== null ) { | ||
$entry[ $field_key ] = $value; | ||
$entry_updated = true; | ||
} | ||
} | ||
|
||
if ( $entry_updated ) { | ||
GFAPI::update_entry( $entry ); | ||
} | ||
} | ||
} | ||
} | ||
|
||
private function get_value_from_order( $order, $data_key ) { | ||
$order_data = $order->get_data(); | ||
|
||
|
||
switch ( $data_key ) { | ||
case 'id': | ||
return $order->get_id(); | ||
case 'email': | ||
return $order->get_billing_email(); | ||
case 'status': | ||
return $order->get_status(); | ||
case 'total': | ||
return $order->get_total(); | ||
} | ||
|
||
// Nested data (e.g., billing/first_name) | ||
$parts = explode( '/', $data_key ); | ||
$current = $order_data; | ||
|
||
foreach ( $parts as $part ) { | ||
if ( isset( $current[ $part ] ) ) { | ||
$current = $current[ $part ]; | ||
} else { | ||
return null; | ||
} | ||
} | ||
|
||
return $current; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider adding error handling for GFAPI::update_entry failures.
The code currently doesn't handle potential errors when updating Gravity Forms entries. Consider adding error handling to catch and log any failures during the update process.
if ( $entry_updated ) {
- GFAPI::update_entry( $entry );
+ $update_result = GFAPI::update_entry( $entry );
+ if ( is_wp_error( $update_result ) ) {
+ // Handle or log the error
+ error_log( sprintf( 'Failed to update entry %d: %s', $entry['id'], $update_result->get_error_message() ) );
+ }
}
🤖 Prompt for AI Agents
In gs-product-configurator/gspc-map-order-data-to-entry.php around lines 80 to
110, the call to GFAPI::update_entry does not handle potential errors. Modify
the code to check the return value of GFAPI::update_entry, which returns a
WP_Error on failure, and if an error occurs, log the error details using an
appropriate logging mechanism or error_log. This will ensure that any failures
during entry updates are captured and can be diagnosed.
Context
⛑️ Ticket(s): https://secure.helpscout.net/conversation/2936045784/83304
Summary
Inspired from https://gravitywiz.com/snippet-library/gspc-populate-field-with-order-id/ to support capturing different types of WooCommerce order data (order ID, name, email) with a config instead of class-based. Example:
Setup and Walkthrough Loom:
https://www.loom.com/share/423b1e3835dc4757aae26a3efe9351b0