Merge branch 'trunk' into pcp-370-onboarding

This commit is contained in:
Alex P 2022-01-21 15:06:16 +02:00
commit 8b3f6cb613
26 changed files with 231 additions and 109 deletions

View file

@ -43,6 +43,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
use WooCommerce\PayPalCommerce\ApiClient\Repository\ApplicationContextRepository;
use WooCommerce\PayPalCommerce\ApiClient\Repository\CartRepository;
use WooCommerce\PayPalCommerce\ApiClient\Repository\CustomerRepository;
use WooCommerce\PayPalCommerce\ApiClient\Repository\PartnerReferralsData;
use WooCommerce\PayPalCommerce\ApiClient\Repository\PayeeRepository;
use WooCommerce\PayPalCommerce\ApiClient\Repository\PayPalRequestIdRepository;
@ -108,7 +109,7 @@ return array(
$container->get( 'api.bearer' ),
$container->get( 'api.factory.payment-token' ),
$container->get( 'woocommerce.logger.woocommerce' ),
$container->get( 'api.prefix' )
$container->get( 'api.repository.customer' )
);
},
'api.endpoint.webhook' => static function ( ContainerInterface $container ) : WebhookEndpoint {
@ -131,14 +132,14 @@ return array(
},
'api.endpoint.identity-token' => static function ( ContainerInterface $container ) : IdentityToken {
$logger = $container->get( 'woocommerce.logger.woocommerce' );
$prefix = $container->get( 'api.prefix' );
$settings = $container->get( 'wcgateway.settings' );
$customer_repository = $container->get( 'api.repository.customer' );
return new IdentityToken(
$container->get( 'api.host' ),
$container->get( 'api.bearer' ),
$logger,
$prefix,
$settings
$settings,
$customer_repository
);
},
'api.endpoint.payments' => static function ( ContainerInterface $container ): PaymentsEndpoint {
@ -219,6 +220,10 @@ return array(
$merchant_id = $container->get( 'api.merchant_id' );
return new PayeeRepository( $merchant_email, $merchant_id );
},
'api.repository.customer' => static function( ContainerInterface $container ): CustomerRepository {
$prefix = $container->get( 'api.prefix' );
return new CustomerRepository( $prefix );
},
'api.factory.application-context' => static function ( ContainerInterface $container ) : ApplicationContextFactory {
return new ApplicationContextFactory();
},

View file

@ -14,6 +14,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Entity\Token;
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
use Psr\Log\LoggerInterface;
use WooCommerce\PayPalCommerce\ApiClient\Repository\CustomerRepository;
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
/**
@ -44,13 +45,6 @@ class IdentityToken {
*/
private $logger;
/**
* The prefix.
*
* @var string
*/
private $prefix;
/**
* The settings
*
@ -58,32 +52,45 @@ class IdentityToken {
*/
private $settings;
/**
* The customer repository.
*
* @var CustomerRepository
*/
protected $customer_repository;
/**
* IdentityToken constructor.
*
* @param string $host The host.
* @param Bearer $bearer The bearer.
* @param LoggerInterface $logger The logger.
* @param string $prefix The prefix.
* @param Settings $settings The settings.
* @param string $host The host.
* @param Bearer $bearer The bearer.
* @param LoggerInterface $logger The logger.
* @param Settings $settings The settings.
* @param CustomerRepository $customer_repository The customer repository.
*/
public function __construct( string $host, Bearer $bearer, LoggerInterface $logger, string $prefix, Settings $settings ) {
$this->host = $host;
$this->bearer = $bearer;
$this->logger = $logger;
$this->prefix = $prefix;
$this->settings = $settings;
public function __construct(
string $host,
Bearer $bearer,
LoggerInterface $logger,
Settings $settings,
CustomerRepository $customer_repository
) {
$this->host = $host;
$this->bearer = $bearer;
$this->logger = $logger;
$this->settings = $settings;
$this->customer_repository = $customer_repository;
}
/**
* Generates a token for a specific customer.
* Generates a token for a specific user.
*
* @param int $customer_id The id of the customer.
* @param int $user_id The id of the user.
*
* @return Token
* @throws RuntimeException If the request fails.
*/
public function generate_for_customer( int $customer_id ): Token {
public function generate_for_user( int $user_id ): Token {
$bearer = $this->bearer->bearer();
$url = trailingslashit( $this->host ) . 'v1/identity/generate-token';
@ -95,11 +102,16 @@ class IdentityToken {
),
);
if (
$customer_id
&& ( $this->settings->has( 'vault_enabled' ) && $this->settings->get( 'vault_enabled' ) )
( $this->settings->has( 'vault_enabled' ) && $this->settings->get( 'vault_enabled' ) )
&& defined( 'PPCP_FLAG_SUBSCRIPTION' ) && PPCP_FLAG_SUBSCRIPTION
) {
$args['body'] = wp_json_encode( array( 'customer_id' => $this->prefix . $customer_id ) );
$customer_id = $this->customer_repository->customer_id_for_user( ( $user_id ) );
$args['body'] = wp_json_encode(
array(
'customer_id' => $customer_id,
)
);
}
$response = $this->request( $url, $args );

View file

@ -15,6 +15,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
use WooCommerce\PayPalCommerce\ApiClient\Factory\PaymentTokenFactory;
use Psr\Log\LoggerInterface;
use WooCommerce\PayPalCommerce\ApiClient\Repository\CustomerRepository;
/**
* Class PaymentTokenEndpoint
@ -50,12 +51,13 @@ class PaymentTokenEndpoint {
* @var LoggerInterface
*/
private $logger;
/**
* The prefix.
* The customer repository.
*
* @var string
* @var CustomerRepository
*/
private $prefix;
protected $customer_repository;
/**
* PaymentTokenEndpoint constructor.
@ -64,21 +66,21 @@ class PaymentTokenEndpoint {
* @param Bearer $bearer The bearer.
* @param PaymentTokenFactory $factory The payment token factory.
* @param LoggerInterface $logger The logger.
* @param string $prefix The prefix.
* @param CustomerRepository $customer_repository The customer repository.
*/
public function __construct(
string $host,
Bearer $bearer,
PaymentTokenFactory $factory,
LoggerInterface $logger,
string $prefix
CustomerRepository $customer_repository
) {
$this->host = $host;
$this->bearer = $bearer;
$this->factory = $factory;
$this->logger = $logger;
$this->prefix = $prefix;
$this->host = $host;
$this->bearer = $bearer;
$this->factory = $factory;
$this->logger = $logger;
$this->customer_repository = $customer_repository;
}
/**
@ -91,10 +93,8 @@ class PaymentTokenEndpoint {
*/
public function for_user( int $id ): array {
$bearer = $this->bearer->bearer();
$customer_id = $this->prefix . $id;
$url = trailingslashit( $this->host ) . 'v2/vault/payment-tokens/?customer_id=' . $customer_id;
$args = array(
$url = trailingslashit( $this->host ) . 'v2/vault/payment-tokens/?customer_id=' . $this->customer_repository->customer_id_for_user( $id );
$args = array(
'method' => 'GET',
'headers' => array(
'Authorization' => 'Bearer ' . $bearer->token(),

View file

@ -0,0 +1,59 @@
<?php
/**
* The customer repository.
*
* @package WooCommerce\PayPalCommerce\ApiClient\Repository
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\ApiClient\Repository;
/**
* Class CustomerRepository
*/
class CustomerRepository {
/**
* The prefix.
*
* @var string
*/
protected $prefix;
/**
* CustomerRepository constructor.
*
* @param string $prefix The prefix.
*/
public function __construct( string $prefix ) {
$this->prefix = $prefix;
}
/**
* Returns the customer ID for the given user ID.
*
* @param int $user_id The user ID.
* @return string
*/
public function customer_id_for_user( int $user_id ): string {
if ( 0 === $user_id ) {
$guest_customer_id = WC()->session->get( 'ppcp_guest_customer_id' );
if ( is_string( $guest_customer_id ) && $guest_customer_id ) {
return $guest_customer_id;
}
$unique_id = $this->prefix . uniqid();
WC()->session->set( 'ppcp_guest_customer_id', $unique_id );
return $unique_id;
}
$guest_customer_id = get_user_meta( $user_id, 'ppcp_guest_customer_id', true );
if ( $guest_customer_id ) {
return $guest_customer_id;
}
return $this->prefix . (string) $user_id;
}
}

View file

@ -82,8 +82,16 @@ document.addEventListener(
console.error('PayPal button could not be configured.');
return;
}
const script = document.createElement('script');
if (
PayPalCommerceGateway.context !== 'checkout'
&& PayPalCommerceGateway.data_client_id.user === 0
&& PayPalCommerceGateway.data_client_id.has_subscriptions
) {
return;
}
const script = document.createElement('script');
script.addEventListener('load', (event) => {
bootstrap();
});

View file

@ -90,7 +90,7 @@ return array(
'button.url' => static function ( ContainerInterface $container ): string {
return plugins_url(
'/modules/ppcp-button/',
dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
dirname( realpath( __FILE__ ), 3 ) . '/woocommerce-paypal-payments.php'
);
},
'button.request-data' => static function ( ContainerInterface $container ): RequestData {

View file

@ -392,9 +392,6 @@ class SmartButton implements SmartButtonInterface {
if ( ! is_checkout() && ! $buttons_enabled ) {
return false;
}
if ( ! $this->can_save_vault_token() && $this->has_subscriptions() ) {
return false;
}
$load_script = false;
if ( is_checkout() && $this->settings->has( 'dcc_enabled' ) && $this->settings->get( 'dcc_enabled' ) ) {
@ -407,7 +404,7 @@ class SmartButton implements SmartButtonInterface {
if ( in_array( $this->context(), array( 'pay-now', 'checkout' ), true ) && $this->can_render_dcc() ) {
wp_enqueue_style(
'ppcp-hosted-fields',
$this->module_url . '/assets/css/hosted-fields.css',
untrailingslashit( $this->module_url ) . '/assets/css/hosted-fields.css',
array(),
1
);
@ -415,7 +412,7 @@ class SmartButton implements SmartButtonInterface {
if ( $load_script ) {
wp_enqueue_script(
'ppcp-smart-button',
$this->module_url . '/assets/js/button.js',
untrailingslashit( $this->module_url ) . '/assets/js/button.js',
array( 'jquery' ),
'1.3.2',
true
@ -599,7 +596,7 @@ class SmartButton implements SmartButtonInterface {
return false;
}
return is_user_logged_in();
return true;
}
/**
@ -650,10 +647,11 @@ class SmartButton implements SmartButtonInterface {
$localize = array(
'script_attributes' => $this->attributes(),
'data_client_id' => array(
'set_attribute' => ( is_checkout() && $this->dcc_is_enabled() ) || $this->can_save_vault_token(),
'endpoint' => home_url( \WC_AJAX::get_endpoint( DataClientIdEndpoint::ENDPOINT ) ),
'nonce' => wp_create_nonce( DataClientIdEndpoint::nonce() ),
'user' => get_current_user_id(),
'set_attribute' => $this->can_save_vault_token(),
'endpoint' => home_url( \WC_AJAX::get_endpoint( DataClientIdEndpoint::ENDPOINT ) ),
'nonce' => wp_create_nonce( DataClientIdEndpoint::nonce() ),
'user' => get_current_user_id(),
'has_subscriptions' => $this->has_subscriptions(),
),
'redirect' => wc_get_checkout_url(),
'context' => $this->context(),

View file

@ -80,7 +80,7 @@ class DataClientIdEndpoint implements EndpointInterface {
try {
$this->request_data->read_request( $this->nonce() );
$user_id = get_current_user_id();
$token = $this->identity_token->generate_for_customer( $user_id );
$token = $this->identity_token->generate_for_user( $user_id );
wp_send_json(
array(
'token' => $token->token(),

View file

@ -140,7 +140,7 @@ return array(
'onboarding.url' => static function ( ContainerInterface $container ): string {
return plugins_url(
'/modules/ppcp-onboarding/',
dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
dirname( realpath( __FILE__ ), 3 ) . '/woocommerce-paypal-payments.php'
);
},

View file

@ -63,14 +63,14 @@ class OnboardingAssets {
*/
public function register(): bool {
$url = $this->module_url . '/assets/css/onboarding.css';
$url = untrailingslashit( $this->module_url ) . '/assets/css/onboarding.css';
wp_register_style(
'ppcp-onboarding',
$url,
array(),
1
);
$url = $this->module_url . '/assets/js/settings.js';
$url = untrailingslashit( $this->module_url ) . '/assets/js/settings.js';
wp_register_script(
'ppcp-settings',
$url,
@ -79,7 +79,7 @@ class OnboardingAssets {
true
);
$url = $this->module_url . '/assets/js/onboarding.js';
$url = untrailingslashit( $this->module_url ) . '/assets/js/onboarding.js';
wp_register_script(
'ppcp-onboarding',
$url,

View file

@ -17,7 +17,7 @@ return array(
'vaulting.module-url' => static function ( ContainerInterface $container ): string {
return plugins_url(
'/modules/ppcp-vaulting/',
dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
dirname( realpath( __FILE__ ), 3 ) . '/woocommerce-paypal-payments.php'
);
},
'vaulting.assets.myaccount-payments' => function( ContainerInterface $container ) : MyAccountPaymentsAssets {

View file

@ -42,7 +42,7 @@ class MyAccountPaymentsAssets {
public function enqueue(): void {
wp_enqueue_script(
'ppcp-vaulting-myaccount-payments',
$this->module_url . '/assets/js/myaccount-payments.js',
untrailingslashit( $this->module_url ) . '/assets/js/myaccount-payments.js',
array( 'jquery' ),
'1',
true

View file

@ -98,6 +98,17 @@ class VaultingModule implements ModuleInterface {
}
);
$subscription_helper = $container->get( 'subscription.helper' );
add_action(
'woocommerce_created_customer',
function( int $customer_id ) use ( $subscription_helper ) {
$guest_customer_id = WC()->session->get( 'ppcp_guest_customer_id' );
if ( $guest_customer_id && $subscription_helper->cart_contains_subscription() ) {
update_user_meta( $customer_id, 'ppcp_guest_customer_id', $guest_customer_id );
}
}
);
$asset_loader = $container->get( 'vaulting.assets.myaccount-payments' );
add_action(
'wp_enqueue_scripts',

View file

@ -121,8 +121,7 @@ return array(
'wcgateway.disabler' => static function ( ContainerInterface $container ): DisableGateways {
$session_handler = $container->get( 'session.handler' );
$settings = $container->get( 'wcgateway.settings' );
$subscription_helper = $container->get( 'subscription.helper' );
return new DisableGateways( $session_handler, $settings, $subscription_helper );
return new DisableGateways( $session_handler, $settings );
},
'wcgateway.is-wc-payments-page' => static function ( ContainerInterface $container ): bool {
$page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
@ -2035,7 +2034,7 @@ return array(
'wcgateway.url' => static function ( ContainerInterface $container ): string {
return plugins_url(
$container->get( 'wcgateway.relative-path' ),
dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
dirname( realpath( __FILE__ ), 3 ) . '/woocommerce-paypal-payments.php'
);
},
'wcgateway.relative-path' => static function( ContainerInterface $container ): string {
@ -2043,7 +2042,7 @@ return array(
},
'wcgateway.absolute-path' => static function( ContainerInterface $container ): string {
return plugin_dir_path(
dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
dirname( realpath( __FILE__ ), 3 ) . '/woocommerce-paypal-payments.php'
) .
$container->get( 'wcgateway.relative-path' );
},

View file

@ -59,7 +59,7 @@ class SettingsPageAssets {
add_action(
'admin_enqueue_scripts',
function() use ( $bearer ) {
if ( ! is_admin() || is_ajax() ) {
if ( ! is_admin() || wp_doing_ajax() ) {
return;
}

View file

@ -10,7 +10,6 @@ declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\WcGateway\Checkout;
use WooCommerce\PayPalCommerce\Session\SessionHandler;
use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
use Psr\Container\ContainerInterface;
@ -34,29 +33,19 @@ class DisableGateways {
*/
private $settings;
/**
* The subscription helper
*
* @var SubscriptionHelper
*/
private $subscription_helper;
/**
* DisableGateways constructor.
*
* @param SessionHandler $session_handler The Session Handler.
* @param ContainerInterface $settings The Settings.
* @param SubscriptionHelper $subscription_helper The subscription helper.
*/
public function __construct(
SessionHandler $session_handler,
ContainerInterface $settings,
SubscriptionHelper $subscription_helper
ContainerInterface $settings
) {
$this->session_handler = $session_handler;
$this->settings = $settings;
$this->subscription_helper = $subscription_helper;
$this->session_handler = $session_handler;
$this->settings = $settings;
}
/**
@ -110,10 +99,6 @@ class DisableGateways {
return true;
}
if ( $this->subscription_helper->cart_contains_subscription() && ! is_user_logged_in() ) {
return true;
}
return false;
}

View file

@ -197,7 +197,7 @@ return array(
'webhook.module-url' => static function ( ContainerInterface $container ): string {
return plugins_url(
'/modules/ppcp-webhooks/',
dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
dirname( realpath( __FILE__ ), 3 ) . '/woocommerce-paypal-payments.php'
);
},
);

View file

@ -45,14 +45,14 @@ class WebhooksStatusPageAssets {
public function register(): void {
wp_register_style(
'ppcp-webhooks-status-page-style',
$this->module_url . '/assets/css/status-page.css',
untrailingslashit( $this->module_url ) . '/assets/css/status-page.css',
array(),
'1'
);
wp_register_script(
'ppcp-webhooks-status-page',
$this->module_url . '/assets/js/status-page.js',
untrailingslashit( $this->module_url ) . '/assets/js/status-page.js',
array(),
'1',
true