Skip to content

Commit

Permalink
[API] Refactoring of lazy customer loader
Browse files Browse the repository at this point in the history
  • Loading branch information
lchrusciel committed Dec 18, 2019
1 parent f9567d6 commit 7e8d1fe
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 84 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?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.
*/

declare(strict_types=1);

namespace Sylius\Bundle\AdminApiBundle\Form\ChoiceList\Loader;

use Sylius\Component\Core\Repository\CustomerRepositoryInterface;
use Symfony\Component\Form\ChoiceList\ArrayChoiceList;
use Symfony\Component\Form\ChoiceList\ChoiceListInterface;
use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface;

final class LazyCustomerLoader implements ChoiceLoaderInterface
{
/** @var CustomerRepositoryInterface */
private $customerRepository;

public function __construct(CustomerRepositoryInterface $customerRepository)
{
$this->customerRepository = $customerRepository;
}

public function loadChoiceList($value = null): ChoiceListInterface
{
return new ArrayChoiceList([], $value);
}

public function loadChoicesForValues(array $values, $value = null): array
{
return $this->customerRepository->findBy(['email' => $values]);
}

public function loadValuesForChoices(array $choices, $value = null): array
{
/** Intentionally left blank, as in the only usage of this loader is in the context of api, where we don't need to load choices */
return [];
}
}
27 changes: 17 additions & 10 deletions src/Sylius/Bundle/AdminApiBundle/Form/Type/OrderType.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

namespace Sylius\Bundle\AdminApiBundle\Form\Type;

use Sylius\Bundle\AdminApiBundle\Form\ChoiceList\LazyCustomerLoader;
use Sylius\Bundle\ChannelBundle\Form\Type\ChannelChoiceType;
use Sylius\Bundle\CustomerBundle\Form\Type\CustomerChoiceType;
use Sylius\Bundle\LocaleBundle\Form\Type\LocaleChoiceType;
Expand All @@ -22,6 +21,7 @@
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
Expand All @@ -33,20 +33,27 @@ final class OrderType extends AbstractResourceType
/** @var RepositoryInterface */
private $localeRepository;

/**
* @var RepositoryInterface
*/
private $customerRepository;
/** @var ?ChoiceLoaderInterface */
private $customerChoiceLoader;

/**
* {@inheritdoc}
*/
public function __construct(string $dataClass, array $validationGroups = [], RepositoryInterface $localeRepository, RepositoryInterface $customerRepository)
{
public function __construct(
string $dataClass,
array $validationGroups = [],
RepositoryInterface $localeRepository,
?ChoiceLoaderInterface $customerChoiceLoader = null
) {
parent::__construct($dataClass, $validationGroups);

$this->localeRepository = $localeRepository;
$this->customerRepository = $customerRepository;

if ($customerChoiceLoader === null) {
@trigger_error(sprintf('Not passing a $customerChoiceLoader to %s constructor is deprecated since Sylius 1.5 and will be removed in Sylius 2.0.', self::class), \E_USER_DEPRECATED);
}

$this->customerChoiceLoader = $customerChoiceLoader;
}

/**
Expand All @@ -59,8 +66,8 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
'constraints' => [
new NotBlank(['groups' => ['sylius']]),
],
'choices' => [],
'choice_loader' => new LazyCustomerLoader($this->customerRepository),
'choices' => [], /** Intentionally left blank, as in the only usage of this loader is in the context of api, where we don't need to load choices */
'choice_loader' => $this->customerChoiceLoader,
])
->add('localeCode', LocaleChoiceType::class, [
'constraints' => [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
<argument>%sylius.model.order.class%</argument>
<argument>%sylius.form.type.api_order.validation_groups%</argument>
<argument type="service" id="sylius.repository.locale" />
<argument type="service" id="sylius.repository.customer" />
<argument type="service" id="sylius.form.choice_list.loader.lazy_customer_loader" />
<tag name="form.type" />
</service>

Expand Down Expand Up @@ -74,5 +74,9 @@
<argument type="service" id="sylius.repository.product_variant" />
<tag name="form.type" />
</service>

<service id="sylius.form.choice_list.loader.lazy_customer_loader" class="Sylius\Bundle\AdminApiBundle\Form\ChoiceList\Loader\LazyCustomerLoader">
<argument id="sylius.repository.customer" type="service"/>
</service>
</services>
</container>
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?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.
*/

declare(strict_types=1);

namespace spec\Sylius\Bundle\AdminApiBundle\Form\ChoiceList\Loader;

use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Sylius\Component\Core\Model\CustomerInterface;
use Sylius\Component\Core\Repository\CustomerRepositoryInterface;
use Sylius\Component\User\Model\UserAwareInterface;
use Sylius\Component\User\Model\UserInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\ChoiceList\ArrayChoiceList;
use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormEvent;

final class LazyCustomerLoaderSpec extends ObjectBehavior
{
function let(CustomerRepositoryInterface $customerRepository): void
{
$this->beConstructedWith($customerRepository);
}

function it_is_choice_loader(): void
{
$this->shouldImplement(ChoiceLoaderInterface::class);
}

function it_loads_customers_by_email(
CustomerRepositoryInterface $customerRepository,
CustomerInterface $firstCustomer,
CustomerInterface $secondCustomer
): void {
$customerRepository
->findBy(['email' => ['first@example.com', 'second@example.com']])
->willReturn([$firstCustomer, $secondCustomer])
;

$this
->loadChoicesForValues(['first@example.com', 'second@example.com'])
->shouldReturn([$firstCustomer, $secondCustomer])
;
}

function it_does_not_load_any_choices_available(): void {
$this->loadValuesForChoices([])->shouldReturn([]);
}

function it_provides_empty_array_choice_list(): void {
$this->loadChoiceList()->shouldBeAnInstanceOf(ArrayChoiceList::class);
}
}

0 comments on commit 7e8d1fe

Please sign in to comment.