Skip to content

Commit

Permalink
[User] Added proper listener to CustomerGuestType
Browse files Browse the repository at this point in the history
  • Loading branch information
Zales0123 committed Sep 29, 2015
1 parent 1408fa6 commit a132cfd
Show file tree
Hide file tree
Showing 6 changed files with 245 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public function load(array $config, ContainerBuilder $container)
;
$container
->getDefinition('sylius.form.type.customer_guest')
->addArgument(new Reference('sylius.repository.customer'))
->addArgument(new Reference('sylius.form.listener.guest_customer'))
;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<?php

/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Sylius\Bundle\UserBundle\Form\EventListener;

use Sylius\Bundle\UserBundle\Context\CustomerContext;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Sylius\Component\User\Context\CustomerContextInterface;
use Sylius\Component\User\Model\CustomerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormInterface;

/**
* @author Mateusz Zalewski <mateusz.zalewski@lakion.com>
*/
class GuestCustomerFormListener implements EventSubscriberInterface
{
/**
* @var RepositoryInterface
*/
private $customerRepository;

/**
* @var CustomerContext
*/
private $customerContext;

/**
* @param RepositoryInterface $customerRepository
* @param CustomerContextInterface $customerContext
*/
public function __construct(RepositoryInterface $customerRepository, CustomerContextInterface $customerContext)
{
$this->customerRepository = $customerRepository;
$this->customerContext = $customerContext;
}

/**
* {@inheritdoc}
*/
public static function getSubscribedEvents()
{
return array(
FormEvents::PRE_SUBMIT => 'preSubmit',
);
}

/**
* {@inheritdoc}
*/
public function preSubmit(FormEvent $event)
{
$rawData = $event->getData();
$form = $event->getForm();

$customer = $this->getCustomerFromProperSource($rawData, $form);

$form->setData($customer);
}

/**
* @param array $rawData
* @param FormInterface $form
*
* @return null|CustomerInterface
*/
protected function getCustomerFromProperSource($rawData, FormInterface $form)
{
if (null !== $customer = $this->customerContext->getCustomer()) {
$form->remove('email');

return $customer;
}

if (!isset($rawData['email']) || empty($rawData['email'])) {
return null;
}

return $this->getCustomer($rawData['email']);
}

/**
* @param string $email
*
* @return CustomerInterface|null
*/
protected function getCustomer($email)
{
$customer = $this->customerRepository->findOneBy(array('email' => $email));

if (null !== $customer && null !== $customer->getUser()) {
return null;
}

if (null === $customer) {
$customer = $this->customerRepository->createNew();
$customer->setEmail($email);
}

return $customer;
}
}
23 changes: 10 additions & 13 deletions src/Sylius/Bundle/UserBundle/Form/Type/CustomerGuestType.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,33 +12,31 @@
namespace Sylius\Bundle\UserBundle\Form\Type;

use Sylius\Bundle\ResourceBundle\Form\Type\AbstractResourceType;
use Sylius\Bundle\UserBundle\Form\EventListener\CustomerRegistrationFormListener;
use Sylius\Bundle\UserBundle\Form\EventListener\UserRegistrationFormListener;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

/**
* @author Michał Marcinkowski <michal.marcinkowski@lakion.com>
* @author Dmitrijs Balabka <dmitry.balabka@gmail.com>
* @author Mateusz Zalewski <mateusz.zalewski@lakion.com>
*/
class CustomerGuestType extends AbstractResourceType
{
/**
* @var RepositoryInterface
* @var EventSubscriberInterface
*/
private $customerRepository;
private $eventSubscriber;

/**
* @param string $dataClass
* @param array $validationGroups
* @param RepositoryInterface $customerRepository
* @param string $dataClass
* @param array $validationGroups
* @param EventSubscriberInterface $eventSubscriber
*/
public function __construct($dataClass, array $validationGroups, RepositoryInterface $customerRepository)
public function __construct($dataClass, array $validationGroups, EventSubscriberInterface $eventSubscriber)
{
parent::__construct($dataClass, $validationGroups);

$this->customerRepository = $customerRepository;
$this->eventSubscriber = $eventSubscriber;
}

/**
Expand All @@ -50,8 +48,7 @@ public function buildForm(FormBuilderInterface $builder, array $options = array(
->add('email', 'email', array(
'label' => 'sylius.form.customer.email',
))
->addEventSubscriber(new CustomerRegistrationFormListener($this->customerRepository))
->setDataLocked(false)
->addEventSubscriber($this->eventSubscriber)
;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,7 @@

namespace Sylius\Bundle\UserBundle\Form\Type;

use Sylius\Bundle\ResourceBundle\Form\Type\AbstractResourceType;
use Sylius\Bundle\UserBundle\Form\EventListener\CustomerRegistrationFormListener;
use Sylius\Bundle\UserBundle\Form\EventListener\UserRegistrationFormListener;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

/**
* @author Michał Marcinkowski <michal.marcinkowski@lakion.com>
Expand Down
8 changes: 8 additions & 0 deletions src/Sylius/Bundle/UserBundle/Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
<parameter key="sylius.form.type.user_reset_password.class">Sylius\Bundle\UserBundle\Form\Type\UserResetPasswordType</parameter>
<parameter key="sylius.form.type.user_change_password.class">Sylius\Bundle\UserBundle\Form\Type\UserChangePasswordType</parameter>

<parameter key="sylius.form.listener.guest_customer.class">Sylius\Bundle\UserBundle\Form\EventListener\GuestCustomerFormListener</parameter>

<parameter key="sylius.listener.default_username.class">Sylius\Bundle\UserBundle\EventListener\DefaultUsernameORMListener</parameter>
<parameter key="sylius.listener.customer_aware.class">Sylius\Bundle\UserBundle\EventListener\CustomerAwareListener</parameter>
<parameter key="sylius.listener.user_delete.class">Sylius\Bundle\UserBundle\EventListener\UserDeleteListener</parameter>
Expand Down Expand Up @@ -183,6 +185,12 @@
<tag name="form.type" alias="sylius_gender" />
</service>

<!-- Form listener -->
<service id="sylius.form.listener.guest_customer" class="%sylius.form.listener.guest_customer.class%">
<argument type="service" id="sylius.repository.customer" />
<argument type="service" id="sylius.context.customer" />
</service>

<!-- Validators -->
<service id="validator.unique.registered_user" class="Sylius\Bundle\UserBundle\Validator\Constraints\RegisteredUserValidator">
<argument type="service" id="sylius.repository.customer" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
<?php

/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace spec\Sylius\Bundle\UserBundle\Form\EventListener;

use PhpSpec\ObjectBehavior;
use Sylius\Component\Core\Model\UserInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Sylius\Component\User\Context\CustomerContextInterface;
use Sylius\Component\User\Model\CustomerInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormInterface;

/**
* @author Mateusz Zalewski <mateusz.zalewski@lakion.com>
*/
class GuestCustomerFormListenerSpec extends ObjectBehavior
{
function let(RepositoryInterface $customerRepository, CustomerContextInterface $customerContext)
{
$this->beConstructedWith($customerRepository, $customerContext);
}

function it_is_initializable()
{
$this->shouldHaveType('Sylius\Bundle\UserBundle\Form\EventListener\GuestCustomerFormListener');
}

function it_implements_event_subscriber_interface()
{
$this->shouldImplement('Symfony\Component\EventDispatcher\EventSubscriberInterface');
}

function it_sets_currently_logged_user_as_form_data(
$customerContext,
CustomerInterface $customer,
FormEvent $event,
FormInterface $form
) {
$event->getData()->willReturn(array('email' => null))->shouldBeCalled();
$event->getForm()->willReturn($form)->shouldBeCalled();

$customerContext->getCustomer()->willReturn($customer)->shouldBeCalled();

$form->remove('email')->shouldBeCalled();
$form->setData($customer)->shouldBeCalled();

$this->preSubmit($event);
}

function it_sets_new_customer_with_passed_email_as_form_data_if_customer_with_such_email_does_not_exist(
$customerContext,
$customerRepository,
CustomerInterface $customer,
FormEvent $event,
FormInterface $form
) {
$event->getData()->willReturn(array('email' => 'john.doe@example.com'))->shouldBeCalled();
$event->getForm()->willReturn($form)->shouldBeCalled();

$customerContext->getCustomer()->willReturn(null)->shouldBeCalled();
$customerRepository->findOneBy(array('email' => 'john.doe@example.com'))->willReturn(null)->shouldBeCalled();

$customerRepository->createNew()->willReturn($customer)->shouldBeCalled();
$customer->setEmail('john.doe@example.com')->shouldBeCalled();

$form->setData($customer)->shouldBeCalled();

$this->preSubmit($event);
}

function it_sets_null_as_form_data_if_no_customer_is_logged_in_and_email_was_not_passed(
$customerContext,
FormEvent $event,
FormInterface $form
) {
$event->getData()->willReturn(array())->shouldBeCalled();
$event->getForm()->willReturn($form)->shouldBeCalled();

$customerContext->getCustomer()->willReturn(null)->shouldBeCalled();

$form->setData(null)->shouldBeCalled();

$this->preSubmit($event);
}

function it_sets_null_as_form_data_if_customer_with_passed_email_already_exist(
$customerContext,
$customerRepository,
CustomerInterface $customer,
FormEvent $event,
FormInterface $form,
UserInterface $user
) {
$event->getData()->willReturn(array('email' => 'john.doe@example.com'))->shouldBeCalled();
$event->getForm()->willReturn($form)->shouldBeCalled();

$customerContext->getCustomer()->willReturn(null)->shouldBeCalled();
$customerRepository->findOneBy(array('email' => 'john.doe@example.com'))->willReturn($customer)->shouldBeCalled();
$customer->getUser()->willReturn($user)->shouldBeCalled();

$form->setData(null)->shouldBeCalled();

$this->preSubmit($event);
}
}

0 comments on commit a132cfd

Please sign in to comment.