mirror of
https://github.com/Sylius/Sylius.git
synced 2026-07-05 20:57:12 +00:00
Merge b08f3d0289 into 9b6799e2b8
This commit is contained in:
commit
2371269ac0
12 changed files with 337 additions and 4 deletions
|
|
@ -71,6 +71,49 @@
|
|||
> and their default parameters include Payment Request-specific values (e.g. `hash: paymentRequest.getHash()`).
|
||||
> Do not use them to configure the Payum after-pay redirect.
|
||||
|
||||
## Installer
|
||||
|
||||
1. The `sylius:install:setup` command now sets up a **country** and a **default zone** during installation.
|
||||
|
||||
Two new setup classes have been introduced:
|
||||
- `Sylius\Bundle\CoreBundle\Installer\Setup\CountrySetup` implementing `CountrySetupInterface`
|
||||
- `Sylius\Bundle\CoreBundle\Installer\Setup\ZoneSetup` implementing `ZoneSetupInterface`
|
||||
|
||||
Both are registered as services and injected into `SetupCommand`. If you have decorated or replaced
|
||||
`SetupCommand`, update your constructor to include the two new dependencies:
|
||||
|
||||
```diff
|
||||
public function __construct(
|
||||
protected readonly EntityManagerInterface $entityManager,
|
||||
protected readonly CommandDirectoryChecker $commandDirectoryChecker,
|
||||
protected readonly CurrencySetupInterface $currencySetup,
|
||||
protected readonly LocaleSetupInterface $localeSetup,
|
||||
protected readonly ChannelSetupInterface $channelSetup,
|
||||
+ protected readonly CountrySetupInterface $countrySetup,
|
||||
+ protected readonly ZoneSetupInterface $zoneSetup,
|
||||
protected readonly FactoryInterface $adminUserFactory,
|
||||
protected readonly UserRepositoryInterface $adminUserRepository,
|
||||
protected readonly ValidatorInterface $validator,
|
||||
)
|
||||
```
|
||||
|
||||
2. The `ChannelSetupInterface::setup()` method signature has been extended to receive the newly created
|
||||
country, zone, and console I/O objects:
|
||||
|
||||
```diff
|
||||
public function setup(
|
||||
LocaleInterface $locale,
|
||||
CurrencyInterface $currency,
|
||||
+ CountryInterface $country,
|
||||
+ ZoneInterface $zone,
|
||||
+ InputInterface $input,
|
||||
+ OutputInterface $output,
|
||||
+ QuestionHelper $questionHelper,
|
||||
): void;
|
||||
```
|
||||
|
||||
If you have a custom implementation of `ChannelSetupInterface`, update its `setup()` signature accordingly.
|
||||
|
||||
## Dependencies
|
||||
|
||||
1. The `behat/transliterator` package has been **deprecated** and will be removed in Sylius 3.0.
|
||||
|
|
|
|||
|
|
@ -22,8 +22,10 @@ use Sylius\Bundle\CoreBundle\Console\Command\InstallSampleDataCommand;
|
|||
use Sylius\Bundle\CoreBundle\Console\Command\SetupCommand;
|
||||
use Sylius\Bundle\CoreBundle\Installer\Checker\CommandDirectoryChecker;
|
||||
use Sylius\Bundle\CoreBundle\Installer\Setup\ChannelSetupInterface;
|
||||
use Sylius\Bundle\CoreBundle\Installer\Setup\CountrySetupInterface;
|
||||
use Sylius\Bundle\CoreBundle\Installer\Setup\CurrencySetupInterface;
|
||||
use Sylius\Bundle\CoreBundle\Installer\Setup\LocaleSetupInterface;
|
||||
use Sylius\Bundle\CoreBundle\Installer\Setup\ZoneSetupInterface;
|
||||
use Sylius\Component\Resource\Factory\FactoryInterface;
|
||||
use Sylius\Component\User\Repository\UserRepositoryInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Console\Application;
|
||||
|
|
@ -44,6 +46,8 @@ final class InstallerContext implements Context
|
|||
private array $inputChoices = [
|
||||
'currency' => 'USD',
|
||||
'locale' => 'en_US',
|
||||
'country' => 'US',
|
||||
'zone' => 'no',
|
||||
'e-mail' => 'test@email.com',
|
||||
'username' => 'test',
|
||||
'firstName' => '',
|
||||
|
|
@ -59,6 +63,8 @@ final class InstallerContext implements Context
|
|||
private readonly CurrencySetupInterface $currencySetup,
|
||||
private readonly LocaleSetupInterface $localeSetup,
|
||||
private readonly ChannelSetupInterface $channelSetup,
|
||||
private readonly CountrySetupInterface $countrySetup,
|
||||
private readonly ZoneSetupInterface $zoneSetup,
|
||||
private readonly FactoryInterface $adminUserFactory,
|
||||
private readonly UserRepositoryInterface $adminUserRepository,
|
||||
private readonly ValidatorInterface $validator,
|
||||
|
|
@ -76,6 +82,8 @@ final class InstallerContext implements Context
|
|||
$this->currencySetup,
|
||||
$this->localeSetup,
|
||||
$this->channelSetup,
|
||||
$this->countrySetup,
|
||||
$this->zoneSetup,
|
||||
$this->adminUserFactory,
|
||||
$this->adminUserRepository,
|
||||
$this->validator,
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ return static function (ContainerConfigurator $container) {
|
|||
service('sylius.setup.installer.currency'),
|
||||
service('sylius.setup.installer.locale'),
|
||||
service('sylius.setup.installer.channel'),
|
||||
service('sylius.setup.installer.country'),
|
||||
service('sylius.setup.installer.zone'),
|
||||
service('sylius.factory.admin_user'),
|
||||
service('sylius.repository.admin_user'),
|
||||
service('validator'),
|
||||
|
|
|
|||
|
|
@ -16,8 +16,10 @@ namespace Sylius\Bundle\CoreBundle\Console\Command;
|
|||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Sylius\Bundle\CoreBundle\Installer\Checker\CommandDirectoryChecker;
|
||||
use Sylius\Bundle\CoreBundle\Installer\Setup\ChannelSetupInterface;
|
||||
use Sylius\Bundle\CoreBundle\Installer\Setup\CountrySetupInterface;
|
||||
use Sylius\Bundle\CoreBundle\Installer\Setup\CurrencySetupInterface;
|
||||
use Sylius\Bundle\CoreBundle\Installer\Setup\LocaleSetupInterface;
|
||||
use Sylius\Bundle\CoreBundle\Installer\Setup\ZoneSetupInterface;
|
||||
use Sylius\Component\Core\Model\AdminUserInterface;
|
||||
use Sylius\Component\User\Repository\UserRepositoryInterface;
|
||||
use Sylius\Resource\Factory\FactoryInterface;
|
||||
|
|
@ -49,6 +51,8 @@ final class SetupCommand extends AbstractInstallCommand
|
|||
protected readonly CurrencySetupInterface $currencySetup,
|
||||
protected readonly LocaleSetupInterface $localeSetup,
|
||||
protected readonly ChannelSetupInterface $channelSetup,
|
||||
protected readonly CountrySetupInterface $countrySetup,
|
||||
protected readonly ZoneSetupInterface $zoneSetup,
|
||||
protected readonly FactoryInterface $adminUserFactory,
|
||||
protected readonly UserRepositoryInterface $adminUserRepository,
|
||||
protected readonly ValidatorInterface $validator,
|
||||
|
|
@ -74,7 +78,9 @@ EOT
|
|||
|
||||
$currency = $this->currencySetup->setup($input, $output, $questionHelper);
|
||||
$locale = $this->localeSetup->setup($input, $output, $questionHelper);
|
||||
$this->channelSetup->setup($locale, $currency);
|
||||
$country = $this->countrySetup->setup($input, $output, $questionHelper);
|
||||
$zone = $this->zoneSetup->setup($country);
|
||||
$this->channelSetup->setup($locale, $currency, $country, $zone, $input, $output, $questionHelper);
|
||||
$this->setupAdministratorUser($input, $output, $locale->getCode());
|
||||
|
||||
return Command::SUCCESS;
|
||||
|
|
|
|||
|
|
@ -14,11 +14,17 @@ declare(strict_types=1);
|
|||
namespace Sylius\Bundle\CoreBundle\Installer\Setup;
|
||||
|
||||
use Doctrine\Persistence\ObjectManager;
|
||||
use Sylius\Component\Addressing\Model\CountryInterface;
|
||||
use Sylius\Component\Addressing\Model\ZoneInterface;
|
||||
use Sylius\Component\Core\Model\ChannelInterface;
|
||||
use Sylius\Component\Currency\Model\CurrencyInterface;
|
||||
use Sylius\Component\Locale\Model\LocaleInterface;
|
||||
use Sylius\Resource\Doctrine\Persistence\RepositoryInterface;
|
||||
use Sylius\Resource\Factory\FactoryInterface;
|
||||
use Symfony\Component\Console\Helper\QuestionHelper;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Question\ConfirmationQuestion;
|
||||
|
||||
final class ChannelSetup implements ChannelSetupInterface
|
||||
{
|
||||
|
|
@ -33,8 +39,15 @@ final class ChannelSetup implements ChannelSetupInterface
|
|||
) {
|
||||
}
|
||||
|
||||
public function setup(LocaleInterface $locale, CurrencyInterface $currency): void
|
||||
{
|
||||
public function setup(
|
||||
LocaleInterface $locale,
|
||||
CurrencyInterface $currency,
|
||||
CountryInterface $country,
|
||||
ZoneInterface $zone,
|
||||
InputInterface $input,
|
||||
OutputInterface $output,
|
||||
QuestionHelper $questionHelper
|
||||
): void {
|
||||
/** @var ChannelInterface|null $channel */
|
||||
$channel = $this->channelRepository->findOneBy([]);
|
||||
|
||||
|
|
@ -52,6 +65,12 @@ final class ChannelSetup implements ChannelSetupInterface
|
|||
$channel->setBaseCurrency($currency);
|
||||
$channel->addLocale($locale);
|
||||
$channel->setDefaultLocale($locale);
|
||||
$channel->addCountry($country);
|
||||
|
||||
$question = new ConfirmationQuestion('Assign created zone as default tax zone? (yes/no) [no]: ', false);
|
||||
if ($questionHelper->ask($input, $output, $question)) {
|
||||
$channel->setDefaultTaxZone($zone);
|
||||
}
|
||||
|
||||
$this->channelManager->flush();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,10 +13,23 @@ declare(strict_types=1);
|
|||
|
||||
namespace Sylius\Bundle\CoreBundle\Installer\Setup;
|
||||
|
||||
use Sylius\Component\Addressing\Model\CountryInterface;
|
||||
use Sylius\Component\Addressing\Model\ZoneInterface;
|
||||
use Sylius\Component\Currency\Model\CurrencyInterface;
|
||||
use Sylius\Component\Locale\Model\LocaleInterface;
|
||||
use Symfony\Component\Console\Helper\QuestionHelper;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
interface ChannelSetupInterface
|
||||
{
|
||||
public function setup(LocaleInterface $locale, CurrencyInterface $currency): void;
|
||||
public function setup(
|
||||
LocaleInterface $locale,
|
||||
CurrencyInterface $currency,
|
||||
CountryInterface $country,
|
||||
ZoneInterface $zone,
|
||||
InputInterface $input,
|
||||
OutputInterface $output,
|
||||
QuestionHelper $questionHelper
|
||||
): void;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,94 @@
|
|||
<?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\Bundle\CoreBundle\Installer\Setup;
|
||||
|
||||
use Sylius\Component\Addressing\Model\CountryInterface;
|
||||
use Sylius\Resource\Doctrine\Persistence\RepositoryInterface;
|
||||
use Sylius\Resource\Factory\FactoryInterface;
|
||||
use Symfony\Component\Console\Helper\QuestionHelper;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Question\Question;
|
||||
use Symfony\Component\Intl\Countries;
|
||||
use Symfony\Component\Intl\Exception\MissingResourceException;
|
||||
|
||||
final class CountrySetup implements CountrySetupInterface
|
||||
{
|
||||
/**
|
||||
* @param RepositoryInterface<CountryInterface> $countryRepository
|
||||
* @param FactoryInterface<CountryInterface> $countryFactory
|
||||
*/
|
||||
public function __construct(
|
||||
private readonly RepositoryInterface $countryRepository,
|
||||
private readonly FactoryInterface $countryFactory,
|
||||
private string $country = 'US',
|
||||
) {
|
||||
$this->country = trim($country);
|
||||
}
|
||||
|
||||
public function setup(InputInterface $input, OutputInterface $output, QuestionHelper $questionHelper): CountryInterface
|
||||
{
|
||||
$code = $this->getCountryCodeFromUser($input, $output, $questionHelper);
|
||||
|
||||
/** @var CountryInterface|null $existingCountry */
|
||||
$existingCountry = $this->countryRepository->findOneBy(['code' => $code]);
|
||||
if (null !== $existingCountry) {
|
||||
return $existingCountry;
|
||||
}
|
||||
|
||||
/** @var CountryInterface $country */
|
||||
$country = $this->countryFactory->createNew();
|
||||
$country->setCode($code);
|
||||
$country->setEnabled(true);
|
||||
|
||||
$this->countryRepository->add($country);
|
||||
|
||||
return $country;
|
||||
}
|
||||
|
||||
private function getCountryCodeFromUser(InputInterface $input, OutputInterface $output, QuestionHelper $questionHelper): string
|
||||
{
|
||||
$code = $this->getNewCountryCode($input, $output, $questionHelper);
|
||||
$name = $this->getCountryName($code);
|
||||
|
||||
while (null === $name) {
|
||||
$output->writeln(
|
||||
sprintf('<comment>Country with code <info>%s</info> could not be resolved.</comment>', $code),
|
||||
);
|
||||
|
||||
$code = $this->getNewCountryCode($input, $output, $questionHelper);
|
||||
$name = $this->getCountryName($code);
|
||||
}
|
||||
|
||||
$output->writeln(sprintf('Adding <info>%s</info> country.', $name));
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
private function getNewCountryCode(InputInterface $input, OutputInterface $output, QuestionHelper $questionHelper): string
|
||||
{
|
||||
$question = new Question(sprintf('Country (press enter to use %s): ', $this->country), $this->country);
|
||||
|
||||
return strtoupper(trim($questionHelper->ask($input, $output, $question)));
|
||||
}
|
||||
|
||||
private function getCountryName(string $code): ?string
|
||||
{
|
||||
try {
|
||||
return Countries::getName($code);
|
||||
} catch (MissingResourceException) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
<?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\Bundle\CoreBundle\Installer\Setup;
|
||||
|
||||
use Sylius\Component\Addressing\Model\CountryInterface;
|
||||
use Symfony\Component\Console\Helper\QuestionHelper;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
interface CountrySetupInterface
|
||||
{
|
||||
public function setup(InputInterface $input, OutputInterface $output, QuestionHelper $questionHelper): CountryInterface;
|
||||
}
|
||||
76
src/Sylius/Bundle/CoreBundle/Installer/Setup/ZoneSetup.php
Normal file
76
src/Sylius/Bundle/CoreBundle/Installer/Setup/ZoneSetup.php
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
<?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\Bundle\CoreBundle\Installer\Setup;
|
||||
|
||||
use Doctrine\Persistence\ObjectManager;
|
||||
use Sylius\Component\Addressing\Model\CountryInterface;
|
||||
use Sylius\Component\Addressing\Model\ZoneInterface;
|
||||
use Sylius\Component\Addressing\Model\ZoneMemberInterface;
|
||||
use Sylius\Resource\Doctrine\Persistence\RepositoryInterface;
|
||||
use Sylius\Resource\Factory\FactoryInterface;
|
||||
|
||||
final readonly class ZoneSetup implements ZoneSetupInterface
|
||||
{
|
||||
/**
|
||||
* @param RepositoryInterface<ZoneInterface> $zoneRepository
|
||||
* @param FactoryInterface<ZoneInterface> $zoneFactory
|
||||
* @param FactoryInterface<ZoneMemberInterface> $zoneMemberFactory
|
||||
*/
|
||||
public function __construct(
|
||||
private RepositoryInterface $zoneRepository,
|
||||
private FactoryInterface $zoneFactory,
|
||||
private FactoryInterface $zoneMemberFactory,
|
||||
private ObjectManager $zoneManager,
|
||||
) {
|
||||
}
|
||||
|
||||
public function setup(CountryInterface $country): ZoneInterface
|
||||
{
|
||||
/** @var ZoneInterface|null $zone */
|
||||
$zone = $this->zoneRepository->findOneBy([]);
|
||||
|
||||
if (null === $zone) {
|
||||
/** @var ZoneInterface $zone */
|
||||
$zone = $this->zoneFactory->createNew();
|
||||
$zone->setCode('default');
|
||||
$zone->setName('Default');
|
||||
$zone->setType(ZoneInterface::TYPE_COUNTRY);
|
||||
|
||||
$this->zoneManager->persist($zone);
|
||||
}
|
||||
|
||||
if (!$this->zoneHasMemberWithCode($zone, (string) $country->getCode())) {
|
||||
/** @var ZoneMemberInterface $zoneMember */
|
||||
$zoneMember = $this->zoneMemberFactory->createNew();
|
||||
$zoneMember->setCode($country->getCode());
|
||||
|
||||
$zone->addMember($zoneMember);
|
||||
}
|
||||
|
||||
$this->zoneManager->flush();
|
||||
|
||||
return $zone;
|
||||
}
|
||||
|
||||
private function zoneHasMemberWithCode(ZoneInterface $zone, string $code): bool
|
||||
{
|
||||
foreach ($zone->getMembers() as $member) {
|
||||
if ($member->getCode() === $code) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<?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\Bundle\CoreBundle\Installer\Setup;
|
||||
|
||||
use Sylius\Component\Addressing\Model\CountryInterface;
|
||||
use Sylius\Component\Addressing\Model\ZoneInterface;
|
||||
|
||||
interface ZoneSetupInterface
|
||||
{
|
||||
public function setup(CountryInterface $country): ZoneInterface;
|
||||
}
|
||||
|
|
@ -92,6 +92,8 @@ return static function (ContainerConfigurator $container) {
|
|||
service('sylius.setup.installer.currency'),
|
||||
service('sylius.setup.installer.locale'),
|
||||
service('sylius.setup.installer.channel'),
|
||||
service('sylius.setup.installer.country'),
|
||||
service('sylius.setup.installer.zone'),
|
||||
service('sylius.factory.admin_user'),
|
||||
service('sylius.repository.admin_user'),
|
||||
service('validator'),
|
||||
|
|
|
|||
|
|
@ -19,10 +19,14 @@ use Sylius\Bundle\CoreBundle\Installer\Provider\DatabaseSetupCommandsProvider;
|
|||
use Sylius\Bundle\CoreBundle\Installer\Provider\DatabaseSetupCommandsProviderInterface;
|
||||
use Sylius\Bundle\CoreBundle\Installer\Setup\ChannelSetup;
|
||||
use Sylius\Bundle\CoreBundle\Installer\Setup\ChannelSetupInterface;
|
||||
use Sylius\Bundle\CoreBundle\Installer\Setup\CountrySetup;
|
||||
use Sylius\Bundle\CoreBundle\Installer\Setup\CountrySetupInterface;
|
||||
use Sylius\Bundle\CoreBundle\Installer\Setup\CurrencySetup;
|
||||
use Sylius\Bundle\CoreBundle\Installer\Setup\CurrencySetupInterface;
|
||||
use Sylius\Bundle\CoreBundle\Installer\Setup\LocaleSetup;
|
||||
use Sylius\Bundle\CoreBundle\Installer\Setup\LocaleSetupInterface;
|
||||
use Sylius\Bundle\CoreBundle\Installer\Setup\ZoneSetup;
|
||||
use Sylius\Bundle\CoreBundle\Installer\Setup\ZoneSetupInterface;
|
||||
|
||||
return static function (ContainerConfigurator $container) {
|
||||
$services = $container->services();
|
||||
|
|
@ -76,4 +80,24 @@ return static function (ContainerConfigurator $container) {
|
|||
])
|
||||
;
|
||||
$services->alias(ChannelSetupInterface::class, 'sylius.setup.installer.channel');
|
||||
|
||||
$services
|
||||
->set('sylius.setup.installer.country', CountrySetup::class)
|
||||
->args([
|
||||
service('sylius.repository.country'),
|
||||
service('sylius.factory.country'),
|
||||
])
|
||||
;
|
||||
$services->alias(CountrySetupInterface::class, 'sylius.setup.installer.country');
|
||||
|
||||
$services
|
||||
->set('sylius.setup.installer.zone', ZoneSetup::class)
|
||||
->args([
|
||||
service('sylius.repository.zone'),
|
||||
service('sylius.factory.zone'),
|
||||
service('sylius.factory.zone_member'),
|
||||
service('sylius.manager.zone'),
|
||||
])
|
||||
;
|
||||
$services->alias(ZoneSetupInterface::class, 'sylius.setup.installer.zone');
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue