From f3da7a31624e0c7d8b5641388a8aecae004a5c40 Mon Sep 17 00:00:00 2001 From: Daniel Dudzic Date: Mon, 11 Mar 2024 15:25:00 +0100 Subject: [PATCH 01/10] Card Fields: Add a filter for the CVC field, adjust the CVC string to match the field label CVV and make it translatable (2658) --- modules/ppcp-card-fields/src/CardFieldsModule.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/modules/ppcp-card-fields/src/CardFieldsModule.php b/modules/ppcp-card-fields/src/CardFieldsModule.php index 213134857..faa36a3bc 100644 --- a/modules/ppcp-card-fields/src/CardFieldsModule.php +++ b/modules/ppcp-card-fields/src/CardFieldsModule.php @@ -97,6 +97,17 @@ class CardFieldsModule implements ModuleInterface { } } + if ( apply_filters( 'woocommerce_paypal_payments_card_fields_translate_card_cvv', true ) ) { + if ( isset( $default_fields['card-cvc-field'] ) ) { + // Replaces the default card cvc placeholder with a translatable one (which also matches the CVV field label). + $default_fields['card-cvc-field'] = str_replace( + 'CVC', + esc_attr__( 'CVV', 'woocommerce-paypal-payments' ), + $default_fields['card-cvc-field'] + ); + } + } + return $default_fields; }, 10, From fd4a21a356869f82072c3f4e49bae4b2f59e293c Mon Sep 17 00:00:00 2001 From: Daniel Dudzic Date: Mon, 11 Mar 2024 18:18:06 +0100 Subject: [PATCH 02/10] Remove the str_replace CVC placeholder adjusting in favor of using the existing translation --- .../ppcp-card-fields/src/CardFieldsModule.php | 11 ----------- .../src/Gateway/CreditCardGateway.php | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/modules/ppcp-card-fields/src/CardFieldsModule.php b/modules/ppcp-card-fields/src/CardFieldsModule.php index faa36a3bc..213134857 100644 --- a/modules/ppcp-card-fields/src/CardFieldsModule.php +++ b/modules/ppcp-card-fields/src/CardFieldsModule.php @@ -97,17 +97,6 @@ class CardFieldsModule implements ModuleInterface { } } - if ( apply_filters( 'woocommerce_paypal_payments_card_fields_translate_card_cvv', true ) ) { - if ( isset( $default_fields['card-cvc-field'] ) ) { - // Replaces the default card cvc placeholder with a translatable one (which also matches the CVV field label). - $default_fields['card-cvc-field'] = str_replace( - 'CVC', - esc_attr__( 'CVV', 'woocommerce-paypal-payments' ), - $default_fields['card-cvc-field'] - ); - } - } - return $default_fields; }, 10, diff --git a/modules/ppcp-wc-gateway/src/Gateway/CreditCardGateway.php b/modules/ppcp-wc-gateway/src/Gateway/CreditCardGateway.php index f2903d239..a1a3b8f06 100644 --- a/modules/ppcp-wc-gateway/src/Gateway/CreditCardGateway.php +++ b/modules/ppcp-wc-gateway/src/Gateway/CreditCardGateway.php @@ -291,8 +291,10 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC { */ public function form() { add_action( 'gettext', array( $this, 'replace_credit_card_cvv_label' ), 10, 3 ); + add_action( 'gettext', array( $this, 'replace_credit_card_cvv_placeholder' ), 10, 3 ); parent::form(); remove_action( 'gettext', 'replace_credit_card_cvv_label' ); + remove_action( 'gettext', 'replace_credit_card_cvv_placeholder' ); } /** @@ -312,6 +314,23 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC { return __( 'CVV', 'woocommerce-paypal-payments' ); } + /** + * Replace WooCommerce credit card CVV field placeholder. + * + * @param string $translation Translated text. + * @param string $text Original text to translate. + * @param string $domain Text domain. + * + * @return string Translated field. + */ + public function replace_credit_card_cvv_placeholder( string $translation, string $text, string $domain ): string { + if ( 'woocommerce' !== $domain || 'CVC' !== $text || ! apply_filters( 'woocommerce_paypal_payments_card_fields_translate_card_cvv', true ) ) { + return $translation; + } + + return __( 'CVV', 'woocommerce-paypal-payments' ); + } + /** * Returns the icons of the gateway. * From 27b8155766e45e37c1fa28dd38c0638a398833cb Mon Sep 17 00:00:00 2001 From: Daniel Dudzic Date: Mon, 11 Mar 2024 19:12:24 +0100 Subject: [PATCH 03/10] Product Title: Ensure the product title in addition to the product description gets correctly sanitized and trimmed before getting sent to PayPal --- modules/ppcp-api-client/src/Factory/ItemFactory.php | 10 +++++----- modules/ppcp-api-client/src/Helper/ItemTrait.php | 8 ++++---- modules/ppcp-order-tracking/src/Shipment/Shipment.php | 4 ++-- .../src/SubscriptionsApiHandler.php | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/modules/ppcp-api-client/src/Factory/ItemFactory.php b/modules/ppcp-api-client/src/Factory/ItemFactory.php index e8fc98c86..c2b14d0e1 100644 --- a/modules/ppcp-api-client/src/Factory/ItemFactory.php +++ b/modules/ppcp-api-client/src/Factory/ItemFactory.php @@ -61,10 +61,10 @@ class ItemFactory { $price = (float) $item['line_subtotal'] / (float) $item['quantity']; return new Item( - mb_substr( $product->get_name(), 0, 127 ), + $this->prepare_item_string( $product->get_name() ), new Money( $price, $this->currency ), $quantity, - $this->prepare_description( $product->get_description() ), + $this->prepare_item_string( $product->get_description() ), null, $this->prepare_sku( $product->get_sku() ), ( $product->is_virtual() ) ? Item::DIGITAL_GOODS : Item::PHYSICAL_GOODS, @@ -138,10 +138,10 @@ class ItemFactory { $image = $product instanceof WC_Product ? wp_get_attachment_image_src( (int) $product->get_image_id(), 'full' ) : ''; return new Item( - mb_substr( $item->get_name(), 0, 127 ), + $this->prepare_item_string( $item->get_name() ), new Money( $price_without_tax_rounded, $currency ), $quantity, - $product instanceof WC_Product ? $this->prepare_description( $product->get_description() ) : '', + $product instanceof WC_Product ? $this->prepare_item_string( $product->get_description() ) : '', null, $product instanceof WC_Product ? $this->prepare_sku( $product->get_sku() ) : '', ( $product instanceof WC_Product && $product->is_virtual() ) ? Item::DIGITAL_GOODS : Item::PHYSICAL_GOODS, @@ -160,7 +160,7 @@ class ItemFactory { */ private function from_wc_order_fee( \WC_Order_Item_Fee $item, \WC_Order $order ): Item { return new Item( - $item->get_name(), + $this->prepare_item_string( $item->get_name() ), new Money( (float) $item->get_amount(), $order->get_currency() ), $item->get_quantity(), '', diff --git a/modules/ppcp-api-client/src/Helper/ItemTrait.php b/modules/ppcp-api-client/src/Helper/ItemTrait.php index 3b1e05bd0..4a93e3914 100644 --- a/modules/ppcp-api-client/src/Helper/ItemTrait.php +++ b/modules/ppcp-api-client/src/Helper/ItemTrait.php @@ -12,14 +12,14 @@ namespace WooCommerce\PayPalCommerce\ApiClient\Helper; trait ItemTrait { /** - * Cleanups the description and prepares it for sending to PayPal. + * Cleans up item strings (title and description for example) and prepares them for sending to PayPal. * * @param string $description Item description. * @return string */ - protected function prepare_description( string $description ): string { - $description = strip_shortcodes( wp_strip_all_tags( $description ) ); - return substr( $description, 0, 127 ) ?: ''; + protected function prepare_item_string( string $string ): string { + $string = strip_shortcodes( wp_strip_all_tags( $string ) ); + return substr( $string, 0, 127 ) ?: ''; } /** diff --git a/modules/ppcp-order-tracking/src/Shipment/Shipment.php b/modules/ppcp-order-tracking/src/Shipment/Shipment.php index 099801874..9661d574c 100644 --- a/modules/ppcp-order-tracking/src/Shipment/Shipment.php +++ b/modules/ppcp-order-tracking/src/Shipment/Shipment.php @@ -169,10 +169,10 @@ class Shipment implements ShipmentInterface { $image = wp_get_attachment_image_src( (int) $product->get_image_id(), 'full' ); $ppcp_order_item = new Item( - mb_substr( $item->get_name(), 0, 127 ), + $this->prepare_item_string( $item->get_name() ), new Money( $price_without_tax_rounded, $currency ), $quantity, - $this->prepare_description( $product->get_description() ), + $this->prepare_item_string( $product->get_description() ), null, $this->prepare_sku( $product->get_sku() ), $product->is_virtual() ? Item::DIGITAL_GOODS : Item::PHYSICAL_GOODS, diff --git a/modules/ppcp-paypal-subscriptions/src/SubscriptionsApiHandler.php b/modules/ppcp-paypal-subscriptions/src/SubscriptionsApiHandler.php index 4d56558ab..2109f13d2 100644 --- a/modules/ppcp-paypal-subscriptions/src/SubscriptionsApiHandler.php +++ b/modules/ppcp-paypal-subscriptions/src/SubscriptionsApiHandler.php @@ -114,7 +114,7 @@ class SubscriptionsApiHandler { */ public function create_product( WC_Product $product ) { try { - $subscription_product = $this->products_endpoint->create( $product->get_title(), $this->prepare_description( $product->get_description() ) ); + $subscription_product = $this->products_endpoint->create( $this->prepare_item_string( $product->get_title() ), $this->prepare_item_string( $product->get_description() ) ); $product->update_meta_data( 'ppcp_subscription_product', $subscription_product->to_array() ); $product->save(); } catch ( RuntimeException $exception ) { @@ -169,7 +169,7 @@ class SubscriptionsApiHandler { $catalog_product_name = $catalog_product->name() ?: ''; $catalog_product_description = $catalog_product->description() ?: ''; - $wc_product_description = $this->prepare_description( $product->get_description() ) ?: $product->get_title(); + $wc_product_description = $this->prepare_item_string( $product->get_description() ) ?: $this->prepare_item_string( $product->get_title() ); if ( $catalog_product_name !== $product->get_title() || $catalog_product_description !== $wc_product_description ) { $data = array(); From beb14ea95ad5964bed49e4d96b7afc287f27b1c7 Mon Sep 17 00:00:00 2001 From: Daniel Dudzic Date: Mon, 11 Mar 2024 20:04:40 +0100 Subject: [PATCH 04/10] Update the prepare_item_string() comments --- modules/ppcp-api-client/src/Helper/ItemTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ppcp-api-client/src/Helper/ItemTrait.php b/modules/ppcp-api-client/src/Helper/ItemTrait.php index 4a93e3914..289889290 100644 --- a/modules/ppcp-api-client/src/Helper/ItemTrait.php +++ b/modules/ppcp-api-client/src/Helper/ItemTrait.php @@ -14,7 +14,7 @@ trait ItemTrait { /** * Cleans up item strings (title and description for example) and prepares them for sending to PayPal. * - * @param string $description Item description. + * @param string $string Item string. * @return string */ protected function prepare_item_string( string $string ): string { From 811c921b41e3667958713dc2094a877610628c11 Mon Sep 17 00:00:00 2001 From: Daniel Dudzic Date: Mon, 11 Mar 2024 20:54:07 +0100 Subject: [PATCH 05/10] Update the testFromWcOrderMaxStringLength() test to match the new title sanitization and trimming --- tests/PHPUnit/ApiClient/Factory/ItemFactoryTest.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/PHPUnit/ApiClient/Factory/ItemFactoryTest.php b/tests/PHPUnit/ApiClient/Factory/ItemFactoryTest.php index f8eedb3bb..65d41e881 100644 --- a/tests/PHPUnit/ApiClient/Factory/ItemFactoryTest.php +++ b/tests/PHPUnit/ApiClient/Factory/ItemFactoryTest.php @@ -312,11 +312,12 @@ class ItemFactoryTest extends TestCase $result = $testee->from_wc_order($order); $item = current($result); + /** * @var Item $item */ - $this->assertEquals(mb_substr($name, 0, 127), $item->name()); - $this->assertEquals(substr($description, 0, 127), $item->description()); + $this->assertEquals(substr( strip_shortcodes( wp_strip_all_tags( $name ) ), 0, 127 ), $item->name()); + $this->assertEquals(substr( strip_shortcodes( wp_strip_all_tags( $description ) ), 0, 127 ), $item->description()); } public function testFromPayPalResponse() From ef9a4d9cdfb4dab86288ba5cc30c25c52a4881cc Mon Sep 17 00:00:00 2001 From: Daniel Dudzic Date: Tue, 12 Mar 2024 15:32:15 +0100 Subject: [PATCH 06/10] Pay upon Invoice: Add input validation via pattern and required attributes to the Experience Context setting fields (667) --- .../PayUponInvoice/PayUponInvoiceGateway.php | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php b/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php index 20ab81fb6..73967dbc6 100644 --- a/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php +++ b/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php @@ -202,7 +202,13 @@ class PayUponInvoiceGateway extends WC_Payment_Gateway { 'type' => 'text', 'default' => get_bloginfo( 'name' ) ?? '', 'desc_tip' => true, - 'description' => __( 'Merchant name displayed in Ratepay\'s payment instructions.', 'woocommerce-paypal-payments' ), + 'description' => __( 'Merchant name displayed in Ratepay\'s payment instructions. Should not exceed 127 characters.', 'woocommerce-paypal-payments' ), + 'maxlength' => 127, + 'custom_attributes' => array( + 'pattern' => '.{1,127}', + 'autocomplete' => 'off', + 'required' => '' + ), ), 'logo_url' => array( 'title' => __( 'Logo URL', 'woocommerce-paypal-payments' ), @@ -210,6 +216,11 @@ class PayUponInvoiceGateway extends WC_Payment_Gateway { 'default' => '', 'desc_tip' => true, 'description' => __( 'Logo to be presented on Ratepay\'s payment instructions.', 'woocommerce-paypal-payments' ), + 'custom_attributes' => array( + 'pattern' => '.+', + 'autocomplete' => 'off', + 'required' => '' + ), ), 'customer_service_instructions' => array( 'title' => __( 'Customer service instructions', 'woocommerce-paypal-payments' ), @@ -217,6 +228,11 @@ class PayUponInvoiceGateway extends WC_Payment_Gateway { 'default' => '', 'desc_tip' => true, 'description' => __( 'Customer service instructions to be presented on Ratepay\'s payment instructions.', 'woocommerce-paypal-payments' ), + 'custom_attributes' => array( + 'pattern' => '.+', + 'autocomplete' => 'off', + 'required' => '' + ), ), ); } From 8e86b242a5c96a76b005a9b3b2ccba95ba24dd8a Mon Sep 17 00:00:00 2001 From: Daniel Dudzic Date: Tue, 12 Mar 2024 21:03:03 +0100 Subject: [PATCH 07/10] Add PHPCS fixes to PayUponInvoiceGateway --- .../PayUponInvoice/PayUponInvoiceGateway.php | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php b/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php index 73967dbc6..d4ca29121 100644 --- a/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php +++ b/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php @@ -198,40 +198,40 @@ class PayUponInvoiceGateway extends WC_Payment_Gateway { 'description' => __( "Specify brand name, logo and customer service instructions to be presented on Ratepay's payment instructions.", 'woocommerce-paypal-payments' ), ), 'brand_name' => array( - 'title' => __( 'Brand name', 'woocommerce-paypal-payments' ), - 'type' => 'text', - 'default' => get_bloginfo( 'name' ) ?? '', - 'desc_tip' => true, - 'description' => __( 'Merchant name displayed in Ratepay\'s payment instructions. Should not exceed 127 characters.', 'woocommerce-paypal-payments' ), - 'maxlength' => 127, + 'title' => __( 'Brand name', 'woocommerce-paypal-payments' ), + 'type' => 'text', + 'default' => get_bloginfo( 'name' ) ?? '', + 'desc_tip' => true, + 'description' => __( 'Merchant name displayed in Ratepay\'s payment instructions. Should not exceed 127 characters.', 'woocommerce-paypal-payments' ), + 'maxlength' => 127, 'custom_attributes' => array( - 'pattern' => '.{1,127}', + 'pattern' => '.{1,127}', 'autocomplete' => 'off', - 'required' => '' + 'required' => '', ), ), 'logo_url' => array( - 'title' => __( 'Logo URL', 'woocommerce-paypal-payments' ), - 'type' => 'url', - 'default' => '', - 'desc_tip' => true, - 'description' => __( 'Logo to be presented on Ratepay\'s payment instructions.', 'woocommerce-paypal-payments' ), + 'title' => __( 'Logo URL', 'woocommerce-paypal-payments' ), + 'type' => 'url', + 'default' => '', + 'desc_tip' => true, + 'description' => __( 'Logo to be presented on Ratepay\'s payment instructions.', 'woocommerce-paypal-payments' ), 'custom_attributes' => array( - 'pattern' => '.+', + 'pattern' => '.+', 'autocomplete' => 'off', - 'required' => '' + 'required' => '', ), ), 'customer_service_instructions' => array( - 'title' => __( 'Customer service instructions', 'woocommerce-paypal-payments' ), - 'type' => 'text', - 'default' => '', - 'desc_tip' => true, - 'description' => __( 'Customer service instructions to be presented on Ratepay\'s payment instructions.', 'woocommerce-paypal-payments' ), + 'title' => __( 'Customer service instructions', 'woocommerce-paypal-payments' ), + 'type' => 'text', + 'default' => '', + 'desc_tip' => true, + 'description' => __( 'Customer service instructions to be presented on Ratepay\'s payment instructions.', 'woocommerce-paypal-payments' ), 'custom_attributes' => array( - 'pattern' => '.+', + 'pattern' => '.+', 'autocomplete' => 'off', - 'required' => '' + 'required' => '', ), ), ); From 89e56b9e720cad37763b15706fdf3bbf9586f466 Mon Sep 17 00:00:00 2001 From: Daniel Dudzic Date: Wed, 13 Mar 2024 12:01:36 +0100 Subject: [PATCH 08/10] Disable markup in the get_plugin_data() return in order to fix the issue with incorrect early initialization of wptexturize() (652) --- src/FilePathPluginFactory.php | 4 ++-- woocommerce-paypal-payments.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/FilePathPluginFactory.php b/src/FilePathPluginFactory.php index 69d118fbb..4be6ff768 100644 --- a/src/FilePathPluginFactory.php +++ b/src/FilePathPluginFactory.php @@ -65,7 +65,7 @@ class FilePathPluginFactory implements FilePathPluginFactoryInterface { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } - $plugin_data = get_plugin_data( $filePath ); + $plugin_data = get_plugin_data( $filePath, false ); if ( empty( $plugin_data ) ) { throw new UnexpectedValueException( sprintf( @@ -98,7 +98,7 @@ class FilePathPluginFactory implements FilePathPluginFactoryInterface { $this->create_version( $plugin_data['Version'] ), $base_dir, $base_name, - $plugin_data['Title'], + 'blah', $plugin_data['Description'], $text_domain, $this->create_version( $plugin_data['RequiresPHP'] ), diff --git a/woocommerce-paypal-payments.php b/woocommerce-paypal-payments.php index a1a51d883..35da8f5e3 100644 --- a/woocommerce-paypal-payments.php +++ b/woocommerce-paypal-payments.php @@ -97,7 +97,7 @@ define( 'PAYPAL_INTEGRATION_DATE', '2024-03-12' ); */ require_once ABSPATH . 'wp-admin/includes/plugin.php'; } - $plugin_data = get_plugin_data( __DIR__ . '/woocommerce-paypal-payments.php' ); + $plugin_data = get_plugin_data( __DIR__ . '/woocommerce-paypal-payments.php', false ); $plugin_version = $plugin_data['Version'] ?? null; $installed_plugin_version = get_option( 'woocommerce-ppcp-version' ); if ( $installed_plugin_version !== $plugin_version ) { From 6797bed4060d9971f5375e9076394573af9710e7 Mon Sep 17 00:00:00 2001 From: Daniel Dudzic Date: Wed, 13 Mar 2024 12:16:35 +0100 Subject: [PATCH 09/10] Fix erroneous code change --- src/FilePathPluginFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FilePathPluginFactory.php b/src/FilePathPluginFactory.php index 4be6ff768..15f4f761d 100644 --- a/src/FilePathPluginFactory.php +++ b/src/FilePathPluginFactory.php @@ -98,7 +98,7 @@ class FilePathPluginFactory implements FilePathPluginFactoryInterface { $this->create_version( $plugin_data['Version'] ), $base_dir, $base_name, - 'blah', + $plugin_data['Title'], $plugin_data['Description'], $text_domain, $this->create_version( $plugin_data['RequiresPHP'] ), From 9c9aa96b8cd5fceb8a56a6e1b885a5d14c64ab24 Mon Sep 17 00:00:00 2001 From: mattallan Date: Wed, 20 Mar 2024 10:51:20 +1000 Subject: [PATCH 10/10] woorelease: Product version bump update --- changelog.txt | 2 +- readme.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/changelog.txt b/changelog.txt index a6b728429..bd4294893 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,6 +1,6 @@ *** Changelog *** -= 2.6.0 - xxxx-xx-xx = += 2.6.0 - 2024-03-20 = * Fix - invoice_id not included in API call when creating payment with saved card #2086 * Fix - Typo in SCA indicators for ACDC Vault transactions #2083 * Fix - Payments with saved card tokens use Capture intent when Authorize is configured #2069 diff --git a/readme.txt b/readme.txt index d7d3aa924..d4b1f1b07 100644 --- a/readme.txt +++ b/readme.txt @@ -179,7 +179,7 @@ If you encounter issues with the PayPal buttons not appearing after an update, p == Changelog == -= 2.6.0 - xxxx-xx-xx = += 2.6.0 - 2024-03-20 = * Fix - invoice_id not included in API call when creating payment with saved card #2086 * Fix - Typo in SCA indicators for ACDC Vault transactions #2083 * Fix - Payments with saved card tokens use Capture intent when Authorize is configured #2069