-
Notifications
You must be signed in to change notification settings - Fork 5
Logic to support admin refunds. #4
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: dev
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -113,6 +113,165 @@ function pmproga4_show_setup_notice() { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| add_action( 'admin_notices', 'pmproga4_show_setup_notice' ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Load the Google Analytics script on the admin pages. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @since TBD | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function pmproga4_load_admin_script() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Only run this if PMPro is installed. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ( ! defined( 'PMPRO_VERSION' ) ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Only show on PMPro admin pages. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ( empty( $_REQUEST['page'] ) || strpos( $_REQUEST['page'], 'pmpro' ) === false ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+129
to
+131
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| extract( $pmproga4_settings = get_option( 'pmproga4_settings', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| array( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'measurement_id' => '', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'track_levels' => array() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+133
to
+139
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| extract( $pmproga4_settings = get_option( 'pmproga4_settings', | |
| array( | |
| 'measurement_id' => '', | |
| 'track_levels' => array() | |
| ) | |
| ) ); | |
| $pmproga4_settings = get_option( | |
| 'pmproga4_settings', | |
| array( | |
| 'measurement_id' => '', | |
| 'track_levels' => array(), | |
| ) | |
| ); | |
| $measurement_id = isset( $pmproga4_settings['measurement_id'] ) ? $pmproga4_settings['measurement_id'] : ''; | |
| $track_levels = isset( $pmproga4_settings['track_levels'] ) ? $pmproga4_settings['track_levels'] : array(); |
Copilot
AI
Jan 20, 2026
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.
Missing space before the opening brace on the script tag attribute. For consistency with WordPress coding standards, there should be a space before the PHP echo statement: <script >
| <script <?php echo esc_attr($script_atts); ?>> | |
| <script <?php echo esc_attr( $script_atts ); ?>> |
Copilot
AI
Jan 20, 2026
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.
The currency value from get_option() is output directly into JavaScript without proper escaping. Use esc_js() to prevent potential XSS vulnerabilities: 'currency': ''
| 'currency': '<?php echo get_option( "pmpro_currency" ); ?>', | |
| 'currency': '<?php echo esc_js( get_option( "pmpro_currency" ) ); ?>', |
Copilot
AI
Jan 20, 2026
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.
Inconsistent indentation: this line uses a tab while the surrounding code uses spaces. For consistency with WordPress coding standards and the rest of the file, use a tab for indentation.
| </script> | |
| </script> |
Copilot
AI
Jan 20, 2026
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.
Use Yoda condition style for consistency with WordPress coding standards. The comparison should be: if ( 'refunded' !== $original_status ). Also use strict comparison (!==) instead of loose comparison (!=) to avoid type coercion issues.
| if ( 'refunded' != $original_status ) { | |
| if ( 'refunded' !== $original_status ) { |
Copilot
AI
Jan 20, 2026
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.
The function pmproga4_load_admin_order_refunded_script is defined but never used or hooked into WordPress. This appears to be dead code that should either be removed or properly integrated with an action hook.
| * Enqueue the Google Analytics script for a refunded order. | |
| * | |
| * @since TBD | |
| */ | |
| function pmproga4_load_admin_order_refunded_script( $pmpro_invoice ) { | |
| pmproga4_refund_event( $pmpro_invoice ); | |
| } | |
| /** |
Copilot
AI
Jan 20, 2026
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.
The function documentation is incomplete. It should include a proper description of what the function does, document the @param tag for $pmpro_invoice parameter, and specify the @return type (which appears to be void).
| * Function for refund event. | |
| * Build and enqueue the Google Analytics 4 refund event for a given order. | |
| * | |
| * @param object $pmpro_invoice Paid Memberships Pro invoice/order object used to populate refund data. | |
| * | |
| * @return void |
Copilot
AI
Jan 20, 2026
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.
The comment mentions checking if the order ID matches a session variable, but no session variable is being checked in this code. The comment should be updated to accurately reflect what the code does: checking if the invoice object and its ID are not empty.
| // Set the ecommerce dataLayer script if the order ID matches the session variable. | |
| // Set the ecommerce dataLayer script if the invoice and its ID are not empty. |
Copilot
AI
Jan 20, 2026
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.
Numeric values should be explicitly cast to ensure they are numeric types before output into JavaScript. Use floatval() for value and tax: value: and tax: . This prevents potential issues if the database values are unexpectedly non-numeric.
| value: <?php echo $gtag_config_ecommerce_data['value']; ?>, | |
| <?php if ( ! empty( $gtag_config_ecommerce_data['tax'] ) ) { ?> | |
| tax: <?php echo $gtag_config_ecommerce_data['tax']; ?>, | |
| value: <?php echo floatval( $gtag_config_ecommerce_data['value'] ); ?>, | |
| <?php if ( ! empty( $gtag_config_ecommerce_data['tax'] ) ) { ?> | |
| tax: <?php echo floatval( $gtag_config_ecommerce_data['tax'] ); ?>, |
Copilot
AI
Jan 20, 2026
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.
Missing space after 'if' keyword. WordPress coding standards require a space after control structure keywords: if ( ! empty( ... ) )
| <?php if( ! empty( $gtag_config_ecommerce_data['coupon'] ) ) { ?> | |
| <?php if ( ! empty( $gtag_config_ecommerce_data['coupon'] ) ) { ?> |
Copilot
AI
Jan 20, 2026
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.
The transaction_id should be escaped with esc_js() for proper JavaScript string escaping, and the coupon value on line 265 should also use esc_js() instead of being output directly. While these values come from the database, they should still be properly escaped for JavaScript context.
| transaction_id: '<?php echo $gtag_config_ecommerce_data['transaction_id']; ?>', | |
| value: <?php echo $gtag_config_ecommerce_data['value']; ?>, | |
| <?php if ( ! empty( $gtag_config_ecommerce_data['tax'] ) ) { ?> | |
| tax: <?php echo $gtag_config_ecommerce_data['tax']; ?>, | |
| <?php } ?> | |
| <?php if( ! empty( $gtag_config_ecommerce_data['coupon'] ) ) { ?> | |
| coupon: '<?php echo $gtag_config_ecommerce_data['coupon']; ?>', | |
| transaction_id: '<?php echo esc_js( $gtag_config_ecommerce_data['transaction_id'] ); ?>', | |
| value: <?php echo $gtag_config_ecommerce_data['value']; ?>, | |
| <?php if ( ! empty( $gtag_config_ecommerce_data['tax'] ) ) { ?> | |
| tax: <?php echo $gtag_config_ecommerce_data['tax']; ?>, | |
| <?php } ?> | |
| <?php if( ! empty( $gtag_config_ecommerce_data['coupon'] ) ) { ?> | |
| coupon: '<?php echo esc_js( $gtag_config_ecommerce_data['coupon'] ); ?>', |
Copilot
AI
Jan 20, 2026
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.
After calling getMembershipLevel(), there's no verification that the membership_level property was successfully populated. Add a check to ensure $pmpro_invoice->membership_level is not empty before accessing its properties like initial_payment, id, and name to prevent potential PHP warnings or errors.
| // Set the ecommerce dataLayer script. | |
| $gtag_config_ecommerce_data = array(); | |
| $gtag_config_ecommerce_data['transaction_id'] = $pmpro_invoice->code; | |
| $gtag_config_ecommerce_data['value'] = $pmpro_invoice->membership_level->initial_payment; | |
| if ( ! empty( $pmpro_invoice->tax ) ) { | |
| $gtag_config_ecommerce_data['tax'] = $pmpro_invoice->tax; | |
| } else { | |
| $gtag_config_ecommerce_data['tax'] = 0; | |
| } | |
| if ( $pmpro_invoice->getDiscountCode() ) { | |
| $gtag_config_ecommerce_data['coupon'] = $pmpro_invoice->discount_code->code; | |
| } else { | |
| $gtag_config_ecommerce_data['coupon'] = ''; | |
| } | |
| // Build an array of product data. | |
| $gtag_config_ecommerce_products = array(); | |
| $gtag_config_ecommerce_products['item_id'] = $pmpro_invoice->membership_level->id; | |
| $gtag_config_ecommerce_products['item_name'] = $pmpro_invoice->membership_level->name; | |
| $gtag_config_ecommerce_products['affiliation'] = get_bloginfo( 'name' ); | |
| if ( $pmpro_invoice->getDiscountCode() ) { | |
| $gtag_config_ecommerce_products['coupon'] = $pmpro_invoice->discount_code->code; | |
| } | |
| $gtag_config_ecommerce_products['index'] = 0; | |
| $gtag_config_ecommerce_products['price'] = $pmpro_invoice->membership_level->initial_payment; | |
| $gtag_config_ecommerce_products['quantity'] = 1; | |
| ?> | |
| <script> | |
| jQuery(document).ready(function() { | |
| gtag( 'event', 'refund', { | |
| transaction_id: '<?php echo $gtag_config_ecommerce_data['transaction_id']; ?>', | |
| value: <?php echo $gtag_config_ecommerce_data['value']; ?>, | |
| <?php if ( ! empty( $gtag_config_ecommerce_data['tax'] ) ) { ?> | |
| tax: <?php echo $gtag_config_ecommerce_data['tax']; ?>, | |
| <?php } ?> | |
| <?php if( ! empty( $gtag_config_ecommerce_data['coupon'] ) ) { ?> | |
| coupon: '<?php echo $gtag_config_ecommerce_data['coupon']; ?>', | |
| <?php } ?> | |
| items: [ <?php echo json_encode( $gtag_config_ecommerce_products ); ?> ] | |
| }); | |
| }); | |
| </script> | |
| <?php | |
| if ( ! empty( $pmpro_invoice->membership_level ) ) { | |
| // Set the ecommerce dataLayer script. | |
| $gtag_config_ecommerce_data = array(); | |
| $gtag_config_ecommerce_data['transaction_id'] = $pmpro_invoice->code; | |
| $gtag_config_ecommerce_data['value'] = $pmpro_invoice->membership_level->initial_payment; | |
| if ( ! empty( $pmpro_invoice->tax ) ) { | |
| $gtag_config_ecommerce_data['tax'] = $pmpro_invoice->tax; | |
| } else { | |
| $gtag_config_ecommerce_data['tax'] = 0; | |
| } | |
| if ( $pmpro_invoice->getDiscountCode() ) { | |
| $gtag_config_ecommerce_data['coupon'] = $pmpro_invoice->discount_code->code; | |
| } else { | |
| $gtag_config_ecommerce_data['coupon'] = ''; | |
| } | |
| // Build an array of product data. | |
| $gtag_config_ecommerce_products = array(); | |
| $gtag_config_ecommerce_products['item_id'] = $pmpro_invoice->membership_level->id; | |
| $gtag_config_ecommerce_products['item_name'] = $pmpro_invoice->membership_level->name; | |
| $gtag_config_ecommerce_products['affiliation'] = get_bloginfo( 'name' ); | |
| if ( $pmpro_invoice->getDiscountCode() ) { | |
| $gtag_config_ecommerce_products['coupon'] = $pmpro_invoice->discount_code->code; | |
| } | |
| $gtag_config_ecommerce_products['index'] = 0; | |
| $gtag_config_ecommerce_products['price'] = $pmpro_invoice->membership_level->initial_payment; | |
| $gtag_config_ecommerce_products['quantity'] = 1; | |
| ?> | |
| <script> | |
| jQuery(document).ready(function() { | |
| gtag( 'event', 'refund', { | |
| transaction_id: '<?php echo $gtag_config_ecommerce_data['transaction_id']; ?>', | |
| value: <?php echo $gtag_config_ecommerce_data['value']; ?>, | |
| <?php if ( ! empty( $gtag_config_ecommerce_data['tax'] ) ) { ?> | |
| tax: <?php echo $gtag_config_ecommerce_data['tax']; ?>, | |
| <?php } ?> | |
| <?php if( ! empty( $gtag_config_ecommerce_data['coupon'] ) ) { ?> | |
| coupon: '<?php echo $gtag_config_ecommerce_data['coupon']; ?>', | |
| <?php } ?> | |
| items: [ <?php echo json_encode( $gtag_config_ecommerce_products ); ?> ] | |
| }); | |
| }); | |
| </script> | |
| <?php | |
| } |
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.
Direct access to $_REQUEST['page'] without sanitization poses a security risk. The value should be sanitized before use in strpos(). Consider using sanitize_text_field($_REQUEST['page']) to prevent potential XSS vulnerabilities.