mirror of
https://github.com/Sylius/Sylius.git
synced 2026-07-14 17:10:53 +00:00
[Locales] Create ADR for locales exposing
This commit is contained in:
parent
d516bf1233
commit
90ceff637e
5 changed files with 55 additions and 17 deletions
|
|
@ -0,0 +1,26 @@
|
|||
# Using data provider for getting available locales in active channel for shop user
|
||||
|
||||
* Status: proposed
|
||||
* Date: 2021-07-05
|
||||
|
||||
## Context and Problem Statement
|
||||
Customer should have access only to locales available in their channel
|
||||
|
||||
## Considered Options
|
||||
|
||||
### Using Doctrine Collection extension
|
||||
|
||||
* Good, because consistent with actual approach to modifying responses content
|
||||
* Good, because works with rest of API extension like pagination
|
||||
* Bad, because locales don't have relation to channel, so using Doctrine Collection extension is extremely hard.
|
||||
|
||||
### Using Data Provider
|
||||
|
||||
* Good, because we already have this approach for older resources
|
||||
* Good, because easy to implement
|
||||
* Bad, because using data providers omits extra Doctrine extensions like pagination
|
||||
|
||||
## Decision Outcome
|
||||
|
||||
Chosen option: Using Data Provider
|
||||
Shops shouldn't have many locales for each channel, so lack of a pagination is smaller problem than creating overcomplicated query in Doctrine Collection extension
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
@locales
|
||||
Feature: Getting a available locales in current channel
|
||||
Feature: Getting available locales in the current channel
|
||||
In order to use a shop in chosen locale
|
||||
As a Customer
|
||||
I want to be able to get available locales
|
||||
|
|
|
|||
|
|
@ -56,9 +56,11 @@ final class LocaleContext implements Context
|
|||
*/
|
||||
public function theLocaleWithCodeShouldBeAvailable(string $name, string $code): void
|
||||
{
|
||||
Assert::true(
|
||||
$this->isLocaleWithName($name, $this->responseChecker->getCollection($this->client->getLastResponse()))
|
||||
);
|
||||
Assert::true($this->isLocaleWithNameAndCode(
|
||||
$this->responseChecker->getCollection($this->client->getLastResponse()),
|
||||
$name,
|
||||
$code
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -66,15 +68,17 @@ final class LocaleContext implements Context
|
|||
*/
|
||||
public function theLocaleWithCodeShouldNotBeAvailable(string $name, string $code): void
|
||||
{
|
||||
Assert::false(
|
||||
$this->isLocaleWithName($name, $this->responseChecker->getCollection($this->client->getLastResponse()))
|
||||
);
|
||||
Assert::false($this->isLocaleWithNameAndCode(
|
||||
$this->responseChecker->getCollection($this->client->getLastResponse()),
|
||||
$name,
|
||||
$code
|
||||
));
|
||||
}
|
||||
|
||||
private function isLocaleWithName(string $name, array $locales): bool
|
||||
private function isLocaleWithNameAndCode(array $locales, string $name, string $code): bool
|
||||
{
|
||||
foreach ($locales as $locale) {
|
||||
if ($locale['name'] === $name) {
|
||||
if ($locale['name'] === $name && $locale['code'] === $code) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,8 +15,10 @@ namespace Sylius\Bundle\ApiBundle\DataProvider;
|
|||
|
||||
use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface;
|
||||
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Sylius\Bundle\ApiBundle\Context\UserContextInterface;
|
||||
use Sylius\Bundle\ApiBundle\Serializer\ContextKeys;
|
||||
use Sylius\Component\Core\Model\AdminUserInterface;
|
||||
use Sylius\Component\Core\Model\ChannelInterface;
|
||||
use Sylius\Component\Locale\Model\LocaleInterface;
|
||||
use Sylius\Component\Resource\Repository\RepositoryInterface;
|
||||
|
|
@ -31,8 +33,10 @@ final class LocaleCollectionDataProvider implements CollectionDataProviderInterf
|
|||
/** @var UserContextInterface */
|
||||
private $userContext;
|
||||
|
||||
public function __construct(RepositoryInterface $localeRepository, UserContextInterface $userContext)
|
||||
{
|
||||
public function __construct(
|
||||
RepositoryInterface $localeRepository,
|
||||
UserContextInterface $userContext
|
||||
) {
|
||||
$this->localeRepository = $localeRepository;
|
||||
$this->userContext = $userContext;
|
||||
}
|
||||
|
|
@ -44,12 +48,14 @@ final class LocaleCollectionDataProvider implements CollectionDataProviderInterf
|
|||
|
||||
public function getCollection(string $resourceClass, string $operationName = null, array $context = [])
|
||||
{
|
||||
Assert::keyExists($context, ContextKeys::CHANNEL);
|
||||
|
||||
$user = $this->userContext->getUser();
|
||||
if ($user !== null && in_array('ROLE_API_ACCESS', $user->getRoles())) {
|
||||
|
||||
if ($user instanceof AdminUserInterface && in_array('ROLE_API_ACCESS', $user->getRoles())) {
|
||||
return $this->localeRepository->findAll();
|
||||
}
|
||||
|
||||
Assert::keyExists($context, ContextKeys::CHANNEL);
|
||||
|
||||
/** @var ChannelInterface $channel */
|
||||
$channel = $context[ContextKeys::CHANNEL];
|
||||
|
||||
|
|
|
|||
|
|
@ -14,9 +14,11 @@ declare(strict_types=1);
|
|||
namespace spec\Sylius\Bundle\ApiBundle\DataProvider;
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Sylius\Bundle\ApiBundle\Context\UserContextInterface;
|
||||
use Sylius\Bundle\ApiBundle\Serializer\ContextKeys;
|
||||
use Sylius\Component\Core\Model\AdminUserInterface;
|
||||
use Sylius\Component\Core\Model\ChannelInterface;
|
||||
use Sylius\Component\Core\Model\ProductInterface;
|
||||
use Sylius\Component\Locale\Model\LocaleInterface;
|
||||
|
|
@ -57,17 +59,17 @@ final class LocaleCollectionDataProviderSpec extends ObjectBehavior
|
|||
$channel->addLocale($firstLocale);
|
||||
$channel->addLocale($secondLocale);
|
||||
|
||||
$channel->getLocales()->willReturn([$firstLocale, $secondLocale]);
|
||||
$channel->getLocales()->willReturn(new ArrayCollection([$firstLocale->getWrappedObject(), $secondLocale->getWrappedObject()]));
|
||||
|
||||
$this
|
||||
->getCollection(LocaleInterface::class, 'get', [ContextKeys::CHANNEL => $channel])
|
||||
->shouldReturn(new ArrayCollection([$firstLocale, $secondLocale]))
|
||||
->shouldBeLike(new ArrayCollection([$firstLocale->getWrappedObject(), $secondLocale->getWrappedObject()]))
|
||||
;
|
||||
}
|
||||
|
||||
function it_provides_all_locales_if_user_is_admin(
|
||||
UserContextInterface $userContext,
|
||||
UserInterface $user,
|
||||
AdminUserInterface $user,
|
||||
ChannelInterface $channel,
|
||||
LocaleInterface $firstLocale,
|
||||
LocaleInterface $secondLocale,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue