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/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..289889290 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. + * @param string $string Item string. * @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(); diff --git a/modules/ppcp-wc-gateway/src/Gateway/CreditCardGateway.php b/modules/ppcp-wc-gateway/src/Gateway/CreditCardGateway.php index abee0c304..848f1aba0 100644 --- a/modules/ppcp-wc-gateway/src/Gateway/CreditCardGateway.php +++ b/modules/ppcp-wc-gateway/src/Gateway/CreditCardGateway.php @@ -313,8 +313,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' ); } /** @@ -334,6 +336,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. * diff --git a/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php b/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php index 20ab81fb6..d4ca29121 100644 --- a/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php +++ b/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php @@ -198,25 +198,41 @@ 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.', 'woocommerce-paypal-payments' ), + '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}', + 'autocomplete' => 'off', + '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' => '.+', + 'autocomplete' => 'off', + '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' => '.+', + 'autocomplete' => 'off', + 'required' => '', + ), ), ); } 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 diff --git a/src/FilePathPluginFactory.php b/src/FilePathPluginFactory.php index 69d118fbb..15f4f761d 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( 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() 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 ) {