Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@
</parameters>

<services>
<service id="sylius_paypal.form.extension.payment_method" class="Sylius\PayPalPlugin\Form\Extension\PaymentMethodTypeExtension">
<tag name="form.type_extension" />
</service>

<service id="sylius_paypal.form.type.paypal_configuration" class="Sylius\PayPalPlugin\Form\Type\PayPalConfigurationType">
<argument>%sylius_paypal.sandbox%</argument>

Expand All @@ -68,9 +64,6 @@

<service id="sylius_paypal.listener.paypal_payment_method" class="Sylius\PayPalPlugin\Listener\PayPalPaymentMethodListener">
<argument type="service" id="sylius_paypal.onboarding.initiator" />
<argument type="service" id="router" />
<argument type="service" id="request_stack" />
<argument type="service" id="sylius_paypal.provider.paypal_payment_method" />
<argument>%sylius_paypal.sandbox%</argument>
<tag name="kernel.event_listener" event="sylius.payment_method.initialize_create" method="initializeCreate" />
</service>
Expand Down Expand Up @@ -370,5 +363,13 @@
<argument>%sylius_paypal.supported_locales%</argument>
</service>
<service id="Sylius\PayPalPlugin\Resolver\SupportedLocaleResolverInterface" alias="sylius_paypal.resolver.supported_locale" />

<service
id="sylius_paypal.validator.only_one_enabled_paypal_payment_method"
class="Sylius\PayPalPlugin\Validator\Constraints\OnlyOneEnabledPayPalPaymentMethodValidator"
>
<argument type="service" id="sylius.repository.payment_method" />
<tag name="validator.constraint_validator" alias="sylius_paypal.validator.only_one_enabled_paypal_payment_method" />
</service>
</services>
</container>
26 changes: 26 additions & 0 deletions config/validation/PaymentMethod.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>

<!--

This file is part of the Sylius package.

(c) Sylius Sp. z o.o.

For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.

-->

<constraint-mapping
xmlns="http://symfony.com/schema/dic/constraint-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd"
>
<class name="Sylius\Component\Core\Model\PaymentMethod">
<constraint name="Sylius\PayPalPlugin\Validator\Constraints\OnlyOneEnabledPayPalPaymentMethod">
<option name="groups">
<value>sylius</value>
</option>
</constraint>
</class>
</constraint-mapping>
30 changes: 30 additions & 0 deletions features/managing_multiple_paypal_payment_methods.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
@managing_payment_methods
Feature: Managing multiple PayPal payment methods
In order to switch between PayPal configurations
As an Administrator
I want to have multiple PayPal methods but only one enabled at a time

Background:
Given the store operates on a single channel in "United States"
And I am logged in as an administrator

@ui
Scenario: Cannot create and enable a new PayPal method when another is already enabled
Given the store allows paying with "PayPal Sandbox" with "PayPal" factory name
When I create a new PayPal payment method "PayPal Production" and try to save it as enabled
Then I should see a validation error that only one PayPal method can be enabled
And the PayPal payment method "PayPal Production" should not exist

@ui
Scenario: Cannot enable an existing PayPal method when another is already enabled
Given the store allows paying with "PayPal Sandbox" with "PayPal" factory name
And the store has a disabled "PayPal Production" payment method with "PayPal" gateway factory
When I try to enable the PayPal payment method "PayPal Production"
Then I should see a validation error that only one PayPal method can be enabled
And the PayPal payment method "PayPal Production" should still be disabled

@ui
Scenario: Can create and enable a new PayPal method when no other is enabled
Given the store has a disabled "PayPal Sandbox" payment method with "PayPal" gateway factory
When I create a new PayPal payment method "PayPal Production" and save it as enabled
Then the new PayPal payment method should be in the list and enabled
20 changes: 0 additions & 20 deletions features/trying_to_onboard_more_than_one_pay_pal_seller.feature

This file was deleted.

51 changes: 0 additions & 51 deletions src/Form/Extension/PaymentMethodTypeExtension.php

This file was deleted.

31 changes: 1 addition & 30 deletions src/Listener/PayPalPaymentMethodListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,46 +16,28 @@
use Sylius\Bundle\ResourceBundle\Event\ResourceControllerEvent;
use Sylius\Component\Core\Model\PaymentMethodInterface;
use Sylius\PayPalPlugin\DependencyInjection\SyliusPayPalExtension;
use Sylius\PayPalPlugin\Exception\PayPalPaymentMethodNotFoundException;
use Sylius\PayPalPlugin\Onboarding\Initiator\OnboardingInitiatorInterface;
use Sylius\PayPalPlugin\Provider\FlashBagProvider;
use Sylius\PayPalPlugin\Provider\PayPalPaymentMethodProviderInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Webmozart\Assert\Assert;

final readonly class PayPalPaymentMethodListener
{
public function __construct(
private OnboardingInitiatorInterface $onboardingInitiator,
private UrlGeneratorInterface $urlGenerator,
private RequestStack $flashBagOrRequestStack,
private PayPalPaymentMethodProviderInterface $payPalPaymentMethodProvider,
private bool $isSandbox = false,
) {
}

public function initializeCreate(ResourceControllerEvent $event): void
{
/** @var object $paymentMethod */
/** @var PaymentMethodInterface|mixed $paymentMethod */
$paymentMethod = $event->getSubject();
Assert::isInstanceOf($paymentMethod, PaymentMethodInterface::class);

if (!$this->isNewPaymentMethodPayPal($paymentMethod)) {
return;
}

if ($this->isTherePayPalPaymentMethod()) {
FlashBagProvider::getFlashBag($this->flashBagOrRequestStack)
->add('error', 'sylius_paypal.more_than_one_seller_not_allowed')
;

$event->setResponse(new RedirectResponse($this->urlGenerator->generate('sylius_admin_payment_method_index')));

return;
}

if ($this->isSandbox || !$this->onboardingInitiator->supports($paymentMethod)) {
return;
}
Expand All @@ -69,15 +51,4 @@ private function isNewPaymentMethodPayPal(PaymentMethodInterface $paymentMethod)

return $gatewayConfig->getFactoryName() === SyliusPayPalExtension::PAYPAL_FACTORY_NAME;
}

private function isTherePayPalPaymentMethod(): bool
{
try {
$this->payPalPaymentMethodProvider->provide();
} catch (PayPalPaymentMethodNotFoundException $exception) {
return false;
}

return true;
}
}
2 changes: 1 addition & 1 deletion src/Provider/PayPalPaymentMethodProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public function __construct(private PaymentMethodRepositoryInterface $paymentMet

public function provide(): PaymentMethodInterface
{
$paymentMethods = $this->paymentMethodRepository->findAll();
$paymentMethods = $this->paymentMethodRepository->findBy(['enabled' => true]);

/** @var PaymentMethodInterface $paymentMethod */
foreach ($paymentMethods as $paymentMethod) {
Expand Down
31 changes: 31 additions & 0 deletions src/Validator/Constraints/OnlyOneEnabledPayPalPaymentMethod.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

/*
* This file is part of the Sylius package.
*
* (c) Sylius Sp. z o.o.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Sylius\PayPalPlugin\Validator\Constraints;

use Symfony\Component\Validator\Constraint;

final class OnlyOneEnabledPayPalPaymentMethod extends Constraint
{
public string $message = 'sylius_paypal.only_one_paypal_enabled';

public function getTargets(): string
{
return self::CLASS_CONSTRAINT;
}

public function validatedBy(): string
{
return 'sylius_paypal.validator.only_one_enabled_paypal_payment_method';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

/*
* This file is part of the Sylius package.
*
* (c) Sylius Sp. z o.o.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Sylius\PayPalPlugin\Validator\Constraints;

use Sylius\Component\Core\Model\PaymentMethodInterface;
use Sylius\Component\Core\Repository\PaymentMethodRepositoryInterface;
use Sylius\PayPalPlugin\DependencyInjection\SyliusPayPalExtension;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
use Symfony\Component\Validator\Exception\UnexpectedValueException;

final class OnlyOneEnabledPayPalPaymentMethodValidator extends ConstraintValidator
{
/** @param PaymentMethodRepositoryInterface<PaymentMethodInterface> $paymentMethodRepository */
public function __construct(
private readonly PaymentMethodRepositoryInterface $paymentMethodRepository,
) {
}

public function validate(mixed $value, Constraint $constraint): void
{
if (!$constraint instanceof OnlyOneEnabledPayPalPaymentMethod) {
throw new UnexpectedTypeException($constraint, OnlyOneEnabledPayPalPaymentMethod::class);
}

if (!$value instanceof PaymentMethodInterface) {
throw new UnexpectedValueException($value, PaymentMethodInterface::class);
}

if (!$this->isPayPalMethod($value) || !$value->isEnabled()) {
return;
}

$allMethods = $this->paymentMethodRepository->findBy(['enabled' => true]);
foreach ($allMethods as $method) {
if ($method->getId() === $value->getId()) {
continue;
}
if (!$this->isPayPalMethod($method)) {
continue;
}

$this->context
->buildViolation($constraint->message)
->atPath('enabled')
->addViolation()
;

return;
}
}

private function isPayPalMethod(PaymentMethodInterface $paymentMethod): bool
{
$gatewayConfig = $paymentMethod->getGatewayConfig();

return $gatewayConfig?->getFactoryName() === SyliusPayPalExtension::PAYPAL_FACTORY_NAME;
}
}
Loading