diff --git a/modules/ppcp-paylater-configurator/extensions.php b/modules/ppcp-paylater-configurator/extensions.php index 7d0a2749f..9217fa8a3 100644 --- a/modules/ppcp-paylater-configurator/extensions.php +++ b/modules/ppcp-paylater-configurator/extensions.php @@ -9,4 +9,65 @@ declare(strict_types=1); namespace WooCommerce\PayPalCommerce\PayLaterConfigurator; -return array(); +use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface; + +return array( + 'wcgateway.settings.fields' => function ( ContainerInterface $container, array $fields ): array { + $old_fields = array( + 'pay_later_messaging_locations', + 'pay_later_enable_styling_per_messaging_location', + 'pay_later_general_message_layout', + 'pay_later_general_message_logo', + 'pay_later_general_message_position', + 'pay_later_general_message_color', + 'pay_later_general_message_flex_color', + 'pay_later_general_message_flex_ratio', + 'pay_later_general_message_preview', + 'pay_later_product_messaging_heading', + 'pay_later_product_message_layout', + 'pay_later_product_message_logo', + 'pay_later_product_message_position', + 'pay_later_product_message_color', + 'pay_later_product_message_flex_color', + 'pay_later_product_message_flex_ratio', + 'pay_later_product_message_preview', + 'pay_later_cart_messaging_heading', + 'pay_later_cart_message_layout', + 'pay_later_cart_message_logo', + 'pay_later_cart_message_position', + 'pay_later_cart_message_color', + 'pay_later_cart_message_flex_color', + 'pay_later_cart_message_flex_ratio', + 'pay_later_cart_message_preview', + 'pay_later_checkout_messaging_heading', + 'pay_later_checkout_message_layout', + 'pay_later_checkout_message_logo', + 'pay_later_checkout_message_position', + 'pay_later_checkout_message_color', + 'pay_later_checkout_message_flex_color', + 'pay_later_checkout_message_flex_ratio', + 'pay_later_checkout_message_preview', + 'pay_later_shop_messaging_heading', + 'pay_later_shop_message_layout', + 'pay_later_shop_message_logo', + 'pay_later_shop_message_position', + 'pay_later_shop_message_color', + 'pay_later_shop_message_flex_color', + 'pay_later_shop_message_flex_ratio', + 'pay_later_shop_message_preview', + 'pay_later_home_messaging_heading', + 'pay_later_home_message_layout', + 'pay_later_home_message_logo', + 'pay_later_home_message_position', + 'pay_later_home_message_color', + 'pay_later_home_message_flex_color', + 'pay_later_home_message_flex_ratio', + 'pay_later_home_message_preview', + ); + foreach ( $old_fields as $old_field ) { + unset( $fields[ $old_field ] ); + } + + return $fields; + }, +); diff --git a/modules/ppcp-paylater-configurator/resources/css/paylater-configurator.scss b/modules/ppcp-paylater-configurator/resources/css/paylater-configurator.scss new file mode 100644 index 000000000..e69de29bb diff --git a/modules/ppcp-paylater-configurator/resources/js/paylater-configurator.js b/modules/ppcp-paylater-configurator/resources/js/paylater-configurator.js new file mode 100644 index 000000000..34ad5d818 --- /dev/null +++ b/modules/ppcp-paylater-configurator/resources/js/paylater-configurator.js @@ -0,0 +1,26 @@ +document.addEventListener( 'DOMContentLoaded', () => { + const form = document.querySelector('#mainform'); + form.insertAdjacentHTML('afterend', '
'); + + merchantConfigurators.Messaging({ + config: PcpPayLaterConfigurator.config, + merchantClientId: PcpPayLaterConfigurator.merchantClientId, + partnerClientId: PcpPayLaterConfigurator.partnerClientId, + partnerName: 'WooCommerce', + bnCode: 'Woo_PPCP', + placements: ['cart', 'checkout', 'product', 'category', 'homepage'], + onSave: data => { + fetch(PcpPayLaterConfigurator.ajax.save_config.endpoint, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + credentials: 'same-origin', + body: JSON.stringify({ + nonce: PcpPayLaterConfigurator.ajax.save_config.nonce, + config: data, + }), + }); + } + }) +} ); diff --git a/modules/ppcp-paylater-configurator/services.php b/modules/ppcp-paylater-configurator/services.php index 87db3b963..7b668aba7 100644 --- a/modules/ppcp-paylater-configurator/services.php +++ b/modules/ppcp-paylater-configurator/services.php @@ -9,10 +9,12 @@ declare(strict_types=1); namespace WooCommerce\PayPalCommerce\PayLaterConfigurator; +use WooCommerce\PayPalCommerce\PayLaterConfigurator\Endpoint\SaveConfig; +use WooCommerce\PayPalCommerce\PayLaterConfigurator\Factory\ConfigFactory; use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface; return array( - 'paylater-configurator.url' => static function ( ContainerInterface $container ): string { + 'paylater-configurator.url' => static function ( ContainerInterface $container ): string { /** * Cannot return false for this path. * @@ -23,4 +25,14 @@ return array( dirname( realpath( __FILE__ ), 3 ) . '/woocommerce-paypal-payments.php' ); }, + 'paylater-configurator.factory.config' => static function ( ContainerInterface $container ): ConfigFactory { + return new ConfigFactory(); + }, + 'paylater-configurator.endpoint.save-config' => static function ( ContainerInterface $container ): SaveConfig { + return new SaveConfig( + $container->get( 'wcgateway.settings' ), + $container->get( 'button.request-data' ), + $container->get( 'woocommerce.logger.woocommerce' ) + ); + }, ); diff --git a/modules/ppcp-paylater-configurator/src/Endpoint/SaveConfig.php b/modules/ppcp-paylater-configurator/src/Endpoint/SaveConfig.php new file mode 100644 index 000000000..0b4f2eda3 --- /dev/null +++ b/modules/ppcp-paylater-configurator/src/Endpoint/SaveConfig.php @@ -0,0 +1,144 @@ +settings = $settings; + $this->request_data = $request_data; + $this->logger = $logger; + } + + /** + * Returns the nonce. + */ + public static function nonce(): string { + return self::ENDPOINT; + } + + /** + * Handles the request. + */ + public function handle_request(): bool { + if ( ! current_user_can( 'manage_woocommerce' ) ) { + wp_send_json_error( 'Not admin.', 403 ); + return false; + } + + try { + $data = $this->request_data->read_request( $this->nonce() ); + + $this->save_config( $data['config']['config'] ); + + wp_send_json_success(); + return true; + } catch ( Throwable $error ) { + $this->logger->error( "SaveConfig execution failed. {$error->getMessage()} {$error->getFile()}:{$error->getLine()}" ); + + wp_send_json_error(); + return false; + } + } + + private function save_config( array $config ): void { + $this->settings->set( 'pay_later_enable_styling_per_messaging_location', true ); + + $enabled_locations = array(); + + foreach ( $config as $placement => $data ) { + $location = $this->configurator_placement_to_location( $placement ); + + $this->save_config_for_location( $data, $location ); + + if ( $data['status'] === 'enabled' ) { + $enabled_locations[] = $location; + } + } + + $this->settings->set( 'pay_later_messaging_locations', $enabled_locations ); + + $this->settings->persist(); + } + + private function save_config_for_location( array $config, string $location ): void { + $this->set_value_if_present( $config, 'layout', "pay_later_{$location}_message_layout" ); + + $this->set_value_if_present( $config, 'color', "pay_later_{$location}_message_flex_color" ); + $this->set_value_if_present( $config, 'ratio', "pay_later_{$location}_message_flex_ratio" ); + + $this->set_value_if_present( $config, 'logo-position', "pay_later_{$location}_message_position" ); + $this->set_value_if_present( $config, 'logo-type', "pay_later_{$location}_message_logo" ); + $this->set_value_if_present( $config, 'logo-color', "pay_later_{$location}_message_color" ); + $this->set_value_if_present( $config, 'text-size', "pay_later_{$location}_message_text_size" ); + } + + private function set_value_if_present( array $config, string $key, string $settings_key ): void { + if ( isset( $config[ $key ] ) ) { + $this->settings->set( $settings_key, $config[ $key ] ); + } + } + + private function configurator_placement_to_location( string $placement ): string { + switch ( $placement ) { + case 'cart': + case 'checkout': + case 'product': + return $placement; + case 'category': + return 'shop'; + case 'homepage': + return 'home'; + default: + return ''; + } + } +} diff --git a/modules/ppcp-paylater-configurator/src/Factory/ConfigFactory.php b/modules/ppcp-paylater-configurator/src/Factory/ConfigFactory.php new file mode 100644 index 000000000..0d8e70dfd --- /dev/null +++ b/modules/ppcp-paylater-configurator/src/Factory/ConfigFactory.php @@ -0,0 +1,76 @@ +location_to_configurator_placement( 'cart' ) => $this->for_location( $settings, 'cart' ), + $this->location_to_configurator_placement( 'checkout' ) => $this->for_location( $settings, 'checkout' ), + $this->location_to_configurator_placement( 'product' ) => $this->for_location( $settings, 'product' ), + $this->location_to_configurator_placement( 'shop' ) => $this->for_location( $settings, 'shop' ), + $this->location_to_configurator_placement( 'home' ) => $this->for_location( $settings, 'home' ), + ); + } + + private function for_location( Settings $settings, string $location ): array { + $selected_locations = $settings->has( 'pay_later_messaging_locations' ) ? $settings->get( 'pay_later_messaging_locations' ) : array(); + + $placement = $this->location_to_configurator_placement( $location ); + if ( in_array( $placement, array( 'category', 'homepage' ) ) ) { + $config = array( + 'layout' => 'flex', + 'color' => $this->get_or_default( $settings, "pay_later_{$location}_message_flex_color", 'black' ), + 'ratio' => $this->get_or_default( $settings, "pay_later_{$location}_message_flex_ratio", '8x1' ), + ); + } else { + $config = array( + 'layout' => 'text', + 'logo-position' => $this->get_or_default( $settings, "pay_later_{$location}_message_position", 'left' ), + 'logo-type' => $this->get_or_default( $settings, "pay_later_{$location}_message_logo", 'inline' ), + 'text-color' => $this->get_or_default( $settings, "pay_later_{$location}_message_color", 'black' ), + 'text-size' => $this->get_or_default( $settings, "pay_later_{$location}_message_text_size", '12' ), + + ); + } + + return array_merge( + array( + 'status' => in_array( $location, $selected_locations ) ? 'enabled' : 'disabled', + 'placement' => $placement, + ), + $config + ); + } + + private function location_to_configurator_placement( string $location ): string { + switch ( $location ) { + case 'cart': + case 'checkout': + case 'product': + return $location; + case 'shop': + return 'category'; + case 'home': + return 'homepage'; + default: + return ''; + } + } + + private function get_or_default( Settings $settings, string $key, $default ) { + return $settings->has( $key ) ? $settings->get( $key ) : $default; + } +} diff --git a/modules/ppcp-paylater-configurator/src/PayLaterConfiguratorModule.php b/modules/ppcp-paylater-configurator/src/PayLaterConfiguratorModule.php index 8a73f5bb2..1a2c5a30c 100644 --- a/modules/ppcp-paylater-configurator/src/PayLaterConfiguratorModule.php +++ b/modules/ppcp-paylater-configurator/src/PayLaterConfiguratorModule.php @@ -9,8 +9,9 @@ declare(strict_types=1); namespace WooCommerce\PayPalCommerce\PayLaterConfigurator; -use WooCommerce\PayPalCommerce\Button\Endpoint\CartScriptParamsEndpoint; use WooCommerce\PayPalCommerce\Button\Helper\MessagesApply; +use WooCommerce\PayPalCommerce\PayLaterConfigurator\Endpoint\SaveConfig; +use WooCommerce\PayPalCommerce\PayLaterConfigurator\Factory\ConfigFactory; use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\ServiceProvider; use WooCommerce\PayPalCommerce\Vendor\Dhii\Modular\Module\ModuleInterface; use WooCommerce\PayPalCommerce\Vendor\Interop\Container\ServiceProviderInterface; @@ -46,6 +47,77 @@ class PayLaterConfiguratorModule implements ModuleInterface { * {@inheritDoc} */ public function run( ContainerInterface $c ): void { + $messages_apply = $c->get( 'button.helper.messages-apply' ); + assert( $messages_apply instanceof MessagesApply ); + + if ( ! $messages_apply->for_country() ) { + return; + } + + add_action( + 'wc_ajax_' . SaveConfig::ENDPOINT, + static function () use ( $c ) { + $endpoint = $c->get( 'paylater-configurator.endpoint.save-config' ); + assert( $endpoint instanceof SaveConfig ); + $endpoint->handle_request(); + } + ); + + $current_page_id = $c->get( 'wcgateway.current-ppcp-settings-page-id' ); + + if ( $current_page_id !== Settings::PAY_LATER_TAB_ID ) { + return; + } + + $settings = $c->get( 'wcgateway.settings' ); + assert( $settings instanceof Settings ); + + add_action( + 'init', + static function () use ( $c, $settings ) { + wp_enqueue_script( + 'ppcp-paylater-configurator-lib', + 'https://www.paypalobjects.com/merchant-library/merchant-configurator.js', + array(), + $c->get( 'ppcp.asset-version' ), + true + ); + + wp_enqueue_script( + 'ppcp-paylater-configurator', + $c->get( 'paylater-configurator.url' ) . '/assets/js/paylater-configurator.js', + array(), + $c->get( 'ppcp.asset-version' ), + true + ); + + wp_enqueue_style( + 'ppcp-paylater-configurator-style', + $c->get( 'paylater-configurator.url' ) . '/assets/css/paylater-configurator.css', + array(), + $c->get( 'ppcp.asset-version' ) + ); + + $config_factory = $c->get( 'paylater-configurator.factory.config' ); + assert( $config_factory instanceof ConfigFactory ); + + wp_localize_script( + 'ppcp-paylater-configurator', + 'PcpPayLaterConfigurator', + array( + 'ajax' => array( + 'save_config' => array( + 'endpoint' => \WC_AJAX::get_endpoint( SaveConfig::ENDPOINT ), + 'nonce' => wp_create_nonce( SaveConfig::nonce() ), + ), + ), + 'config' => $config_factory->from_settings( $settings ), + 'merchantClientId' => $settings->get( 'client_id' ), + 'partnerClientId' => $c->get( 'api.partner_merchant_id' ), + ) + ); + } + ); } /**