[CoreBundle] Move classes from Command to Console/Command

This commit is contained in:
Wojdylak 2024-01-17 15:21:04 +01:00
parent f0446fe5d2
commit f4d9a86e0b
No known key found for this signature in database
GPG key ID: 7509E560A6821ABE
33 changed files with 1284 additions and 892 deletions

View file

@ -185,26 +185,6 @@ parameters:
count: 1
path: src/Sylius/Bundle/AdminBundle/Menu/PromotionUpdateMenuBuilder.php
-
message: "#^Method Sylius\\\\Bundle\\\\AdminBundle\\\\MessageHandler\\\\CreateAdminUserHandler\\:\\:__construct\\(\\) has parameter \\$adminUserFactory with generic interface Sylius\\\\Component\\\\Resource\\\\Factory\\\\FactoryInterface but does not specify its types\\: T$#"
count: 1
path: src/Sylius/Bundle/AdminBundle/MessageHandler/CreateAdminUserHandler.php
-
message: "#^Method Sylius\\\\Bundle\\\\AdminBundle\\\\MessageHandler\\\\CreateAdminUserHandler\\:\\:__construct\\(\\) has parameter \\$adminUserRepository with generic interface Sylius\\\\Component\\\\User\\\\Repository\\\\UserRepositoryInterface but does not specify its types\\: T$#"
count: 1
path: src/Sylius/Bundle/AdminBundle/MessageHandler/CreateAdminUserHandler.php
-
message: "#^Method Sylius\\\\Bundle\\\\AdminBundle\\\\MessageHandler\\\\CreateAdminUserHandler\\:\\:__construct\\(\\) has parameter \\$validationGroups with no value type specified in iterable type array\\.$#"
count: 1
path: src/Sylius/Bundle/AdminBundle/MessageHandler/CreateAdminUserHandler.php
-
message: "#^Method Sylius\\\\Bundle\\\\AdminBundle\\\\MessageHandler\\\\CreateAdminUserHandler\\:\\:getViolationMessages\\(\\) return type has no value type specified in iterable type iterable\\.$#"
count: 1
path: src/Sylius/Bundle/AdminBundle/MessageHandler/CreateAdminUserHandler.php
-
message: "#^Method Sylius\\\\Bundle\\\\AdminBundle\\\\Twig\\\\ChannelNameExtension\\:\\:__construct\\(\\) has parameter \\$channelRepository with generic interface Sylius\\\\Component\\\\Channel\\\\Repository\\\\ChannelRepositoryInterface but does not specify its types\\: T$#"
count: 1
@ -2300,46 +2280,6 @@ parameters:
count: 1
path: src/Sylius/Bundle/CoreBundle/Collector/SyliusCollector.php
-
message: "#^Method Sylius\\\\Bundle\\\\CoreBundle\\\\Command\\\\AbstractInstallCommand\\:\\:initialize\\(\\) has no return type specified\\.$#"
count: 1
path: src/Sylius/Bundle/CoreBundle/Command/AbstractInstallCommand.php
-
message: "#^Method Sylius\\\\Bundle\\\\CoreBundle\\\\Command\\\\AbstractInstallCommand\\:\\:renderTable\\(\\) has parameter \\$headers with no value type specified in iterable type array\\.$#"
count: 1
path: src/Sylius/Bundle/CoreBundle/Command/AbstractInstallCommand.php
-
message: "#^Method Sylius\\\\Bundle\\\\CoreBundle\\\\Command\\\\AbstractInstallCommand\\:\\:renderTable\\(\\) has parameter \\$rows with no value type specified in iterable type array\\.$#"
count: 1
path: src/Sylius/Bundle/CoreBundle/Command/AbstractInstallCommand.php
-
message: "#^Method Sylius\\\\Bundle\\\\CoreBundle\\\\Command\\\\AbstractInstallCommand\\:\\:runCommands\\(\\) has parameter \\$commands with no value type specified in iterable type array\\.$#"
count: 1
path: src/Sylius/Bundle/CoreBundle/Command/AbstractInstallCommand.php
-
message: "#^PHPDoc tag @var for variable \\$command has no value type specified in iterable type array\\.$#"
count: 1
path: src/Sylius/Bundle/CoreBundle/Command/InstallCommand.php
-
message: "#^Property Sylius\\\\Bundle\\\\CoreBundle\\\\Command\\\\InstallCommand\\:\\:\\$commands type has no value type specified in iterable type array\\.$#"
count: 1
path: src/Sylius/Bundle/CoreBundle/Command/InstallCommand.php
-
message: "#^Method Sylius\\\\Bundle\\\\CoreBundle\\\\Command\\\\SetupCommand\\:\\:getAdminUserRepository\\(\\) return type with generic interface Sylius\\\\Component\\\\User\\\\Repository\\\\UserRepositoryInterface does not specify its types\\: T$#"
count: 1
path: src/Sylius/Bundle/CoreBundle/Command/SetupCommand.php
-
message: "#^PHPDoc tag @var for variable \\$userRepository contains generic interface Sylius\\\\Component\\\\User\\\\Repository\\\\UserRepositoryInterface but does not specify its types\\: T$#"
count: 3
path: src/Sylius/Bundle/CoreBundle/Command/SetupCommand.php
-
message: "#^Method Sylius\\\\Bundle\\\\CoreBundle\\\\Context\\\\CustomerAndChannelBasedCartContext\\:\\:__construct\\(\\) has parameter \\$orderRepository with generic interface Sylius\\\\Component\\\\Core\\\\Repository\\\\OrderRepositoryInterface but does not specify its types\\: T$#"
count: 1
@ -4150,11 +4090,6 @@ parameters:
count: 1
path: src/Sylius/Bundle/LocaleBundle/SyliusLocaleBundle.php
-
message: "#^Method Sylius\\\\Bundle\\\\OrderBundle\\\\Command\\\\RemoveExpiredCartsCommand\\:\\:__construct\\(\\) has parameter \\$expirationTime with no type specified\\.$#"
count: 1
path: src/Sylius/Bundle/OrderBundle/Command/RemoveExpiredCartsCommand.php
-
message: "#^Method Sylius\\\\Bundle\\\\OrderBundle\\\\Context\\\\SessionBasedCartContext\\:\\:__construct\\(\\) has parameter \\$orderRepository with generic interface Sylius\\\\Component\\\\Order\\\\Repository\\\\OrderRepositoryInterface but does not specify its types\\: T$#"
count: 1
@ -4495,11 +4430,6 @@ parameters:
count: 1
path: src/Sylius/Bundle/ProductBundle/Validator/UniqueSimpleProductCodeValidator.php
-
message: "#^Method Sylius\\\\Bundle\\\\PromotionBundle\\\\Command\\\\GenerateCouponsCommand\\:\\:__construct\\(\\) has parameter \\$promotionRepository with generic interface Sylius\\\\Component\\\\Promotion\\\\Repository\\\\PromotionRepositoryInterface but does not specify its types\\: T$#"
count: 1
path: src/Sylius/Bundle/PromotionBundle/Command/GenerateCouponsCommand.php
-
message: "#^Method Sylius\\\\Bundle\\\\PromotionBundle\\\\DiscountApplicationCriteria\\\\DiscountApplicationCriteriaInterface\\:\\:isApplicable\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
count: 1
@ -5061,24 +4991,14 @@ parameters:
path: src/Sylius/Bundle/UiBundle/Twig/TemplateEventExtension.php
-
message: "#^Method Sylius\\\\Bundle\\\\UserBundle\\\\Command\\\\AbstractRoleCommand\\:\\:executeRoleCommand\\(\\) has parameter \\$securityRoles with no value type specified in iterable type array\\.$#"
message: "#^Method Sylius\\\\Bundle\\\\UserBundle\\\\Console\\\\Command\\\\AbstractRoleCommand\\:\\:getUserRepository\\(\\) return type with generic interface Sylius\\\\Component\\\\User\\\\Repository\\\\UserRepositoryInterface does not specify its types\\: T$#"
count: 1
path: src/Sylius/Bundle/UserBundle/Command/AbstractRoleCommand.php
-
message: "#^Method Sylius\\\\Bundle\\\\UserBundle\\\\Command\\\\AbstractRoleCommand\\:\\:getAvailableUserTypes\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: src/Sylius/Bundle/UserBundle/Command/AbstractRoleCommand.php
-
message: "#^Method Sylius\\\\Bundle\\\\UserBundle\\\\Command\\\\AbstractRoleCommand\\:\\:getUserRepository\\(\\) return type with generic interface Sylius\\\\Component\\\\User\\\\Repository\\\\UserRepositoryInterface does not specify its types\\: T$#"
count: 1
path: src/Sylius/Bundle/UserBundle/Command/AbstractRoleCommand.php
path: src/Sylius/Bundle/UserBundle/Console/Command/AbstractRoleCommand.php
-
message: "#^Unable to resolve the template type T in call to method Doctrine\\\\Persistence\\\\ObjectManager\\:\\:getRepository\\(\\)$#"
count: 1
path: src/Sylius/Bundle/UserBundle/Command/AbstractRoleCommand.php
path: src/Sylius/Bundle/UserBundle/Console/Command/AbstractRoleCommand.php
-
message: "#^Method Sylius\\\\Bundle\\\\UserBundle\\\\Command\\\\DemoteUserCommand\\:\\:executeRoleCommand\\(\\) has parameter \\$securityRoles with no value type specified in iterable type array\\.$#"
@ -6984,3 +6904,93 @@ parameters:
message: "#^Method Sylius\\\\Component\\\\User\\\\Security\\\\Checker\\\\TokenUniquenessChecker\\:\\:__construct\\(\\) has parameter \\$repository with generic interface Sylius\\\\Component\\\\Resource\\\\Repository\\\\RepositoryInterface but does not specify its types\\: T$#"
count: 1
path: src/Sylius/Component/User/Security/Checker/TokenUniquenessChecker.php
-
message: "#^If condition is always false.$#"
count: 1
path: src/Sylius/Bundle/CoreBundle/Command/AbstractInstallCommand.php
-
message: "#^If condition is always false.$#"
count: 1
path: src/Sylius/Bundle/CoreBundle/Command/CancelUnpaidOrdersCommand.php
-
message: "#^If condition is always false.$#"
count: 1
path: src/Sylius/Bundle/CoreBundle/Command/CheckRequirementsCommand.php
-
message: "#^If condition is always false.$#"
count: 1
path: src/Sylius/Bundle/CoreBundle/Command/InformAboutGUSCommand.php
-
message: "#^If condition is always false.$#"
count: 1
path: src/Sylius/Bundle/CoreBundle/Command/InstallAssetsCommand.php
-
message: "#^If condition is always false.$#"
count: 1
path: src/Sylius/Bundle/CoreBundle/Command/InstallCommand.php
-
message: "#^If condition is always false.$#"
count: 1
path: src/Sylius/Bundle/CoreBundle/Command/InstallDatabaseCommand.php
-
message: "#^If condition is always false.$#"
count: 1
path: src/Sylius/Bundle/CoreBundle/Command/InstallSampleDataCommand.php
-
message: "#^If condition is always false.$#"
count: 1
path: src/Sylius/Bundle/CoreBundle/Command/JwtConfigurationCommand.php
-
message: "#^If condition is always false.$#"
count: 1
path: src/Sylius/Bundle/CoreBundle/Command/SetupCommand.php
-
message: "#^If condition is always false.$#"
count: 1
path: src/Sylius/Bundle/CoreBundle/Command/ShowAvailablePluginsCommand.php
-
message: "#^If condition is always false.$#"
count: 1
path: src/Sylius/Bundle/CoreBundle/Command/Model/PluginInfo.php
-
message: "#^If condition is always false.$#"
count: 1
path: src/Sylius/Bundle/OrderBundle/Command/RemoveExpiredCartsCommand.php
-
message: "#^If condition is always false.$#"
count: 1
path: src/Sylius/Bundle/PromotionBundle/Command/GenerateCouponsCommand.php
-
message: "#^If condition is always false.$#"
count: 1
path: src/Sylius/Bundle/UiBundle/Command/DebugTemplateEventCommand.php
-
message: "#^If condition is always false.$#"
count: 1
path: src/Sylius/Bundle/UserBundle/Command/AbstractRoleCommand.php
-
message: "#^If condition is always false.$#"
count: 1
path: src/Sylius/Bundle/UserBundle/Command/DemoteUserCommand.php
-
message: "#^If condition is always false.$#"
count: 1
path: src/Sylius/Bundle/UserBundle/Command/PromoteUserCommand.php

View file

@ -30,6 +30,7 @@ parameters:
# Deprecated classes
- 'src/Sylius/Bundle/CoreBundle/Application/Kernel.php'
- 'src/Sylius/Bundle/UserBundle/Security/UserPasswordEncoder.php'
- 'src/Sylius/Bundle/CoreBundle/Console/Command/ShowAvailablePluginsCommand.php'
# To investigate, occurs after release of doctrine/orm 2.14, the processing of these classes ends with exit code 143
- 'src/Sylius/Bundle/CoreBundle/Doctrine/DQL/**.php'

View file

@ -14,7 +14,7 @@ declare(strict_types=1);
namespace Sylius\Bundle\AdminBundle\Console\Command;
use Sylius\Bundle\AdminBundle\Console\Command\Factory\QuestionFactoryInterface;
use Sylius\Bundle\AdminBundle\Command\CreateAdminUser;
use Sylius\Bundle\AdminBundle\Message\CreateAdminUser;
use Sylius\Bundle\AdminBundle\Exception\CreateAdminUserFailedException;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;

View file

@ -25,6 +25,11 @@ use Symfony\Component\Validator\Validator\ValidatorInterface;
final class CreateAdminUserHandler implements MessageHandlerInterface
{
/**
* @param UserRepositoryInterface<AdminUserInterface> $adminUserRepository
* @param FactoryInterface<AdminUserInterface> $adminUserFactory
* @param array<array-key, string> $validationGroups
*/
public function __construct(
private UserRepositoryInterface $adminUserRepository,
private FactoryInterface $adminUserFactory,
@ -65,6 +70,7 @@ final class CreateAdminUserHandler implements MessageHandlerInterface
return $adminUser;
}
/** @return iterable<string> */
private function getViolationMessages(ConstraintViolationListInterface $constraintViolationList): iterable
{
foreach ($constraintViolationList as $violation) {

View file

@ -13,114 +13,18 @@ declare(strict_types=1);
namespace Sylius\Bundle\CoreBundle\Command;
use Doctrine\ORM\EntityManagerInterface;
use Sylius\Bundle\CoreBundle\Installer\Executor\CommandExecutor;
use SyliusLabs\Polyfill\Symfony\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\Console\Output\OutputInterface;
trigger_deprecation(
'sylius/core-bundle',
'1.13',
'The "%s" class is deprecated and will be removed in Sylius 2.0. Use "%s" instead.',
AbstractInstallCommand::class,
\Sylius\Bundle\CoreBundle\Console\Command\AbstractInstallCommand::class,
);
abstract class AbstractInstallCommand extends ContainerAwareCommand
{
/** @deprecated */
public const WEB_ASSETS_DIRECTORY = 'web/assets/';
class_exists(\Sylius\Bundle\CoreBundle\Console\Command\AbstractInstallCommand::class);
/** @deprecated */
public const WEB_BUNDLES_DIRECTORY = 'web/bundles/';
/** @deprecated */
public const WEB_MEDIA_DIRECTORY = 'web/media/';
/** @deprecated */
public const WEB_MEDIA_IMAGE_DIRECTORY = 'web/media/image/';
/** @var CommandExecutor|null */
protected $commandExecutor;
protected function initialize(InputInterface $input, OutputInterface $output)
if (false) {
abstract class AbstractInstallCommand
{
$application = $this->getApplication();
$application->setCatchExceptions(false);
$this->commandExecutor = new CommandExecutor($input, $output, $application);
}
/**
* @return object
*/
protected function get(string $id)
{
return $this->getContainer()->get($id);
}
protected function getEnvironment(): string
{
return (string) $this->getContainer()->getParameter('kernel.environment');
}
protected function isDebug(): bool
{
return (bool) $this->getContainer()->getParameter('kernel.debug');
}
protected function renderTable(array $headers, array $rows, OutputInterface $output): void
{
$table = new Table($output);
$table
->setHeaders($headers)
->setRows($rows)
->render()
;
}
protected function createProgressBar(OutputInterface $output, int $length = 10): ProgressBar
{
$progress = new ProgressBar($output);
$progress->setBarCharacter('<info>░</info>');
$progress->setEmptyBarCharacter(' ');
$progress->setProgressCharacter('<comment>░</comment>');
$progress->start($length);
return $progress;
}
protected function runCommands(array $commands, OutputInterface $output, bool $displayProgress = true): void
{
$progress = $this->createProgressBar($displayProgress ? $output : new NullOutput(), count($commands));
foreach ($commands as $key => $value) {
if (is_string($key)) {
$command = $key;
$parameters = $value;
} else {
$command = $value;
$parameters = [];
}
$this->commandExecutor->runCommand($command, $parameters);
// PDO does not always close the connection after Doctrine commands.
// See https://github.com/symfony/symfony/issues/11750.
/** @var EntityManagerInterface $entityManager */
$entityManager = $this->getContainer()->get('doctrine')->getManager();
$entityManager->getConnection()->close();
$progress->advance();
}
$progress->finish();
}
protected function ensureDirectoryExistsAndIsWritable(string $directory, OutputInterface $output): void
{
$checker = $this->getContainer()->get('sylius.installer.checker.command_directory');
$checker->setCommandName($this->getName());
$checker->ensureDirectoryExists($directory, $output);
$checker->ensureDirectoryIsWritable($directory, $output);
}
}

View file

@ -13,41 +13,18 @@ declare(strict_types=1);
namespace Sylius\Bundle\CoreBundle\Command;
use SyliusLabs\Polyfill\Symfony\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
trigger_deprecation(
'sylius/core-bundle',
'1.13',
'The "%s" class is deprecated and will be removed in Sylius 2.0. Use "%s" instead.',
CancelUnpaidOrdersCommand::class,
\Sylius\Bundle\CoreBundle\Console\Command\CancelUnpaidOrdersCommand::class,
);
/**
* @final
*/
class CancelUnpaidOrdersCommand extends ContainerAwareCommand
{
protected static $defaultName = 'sylius:cancel-unpaid-orders';
class_exists(\Sylius\Bundle\CoreBundle\Console\Command\CancelUnpaidOrdersCommand::class);
protected function configure(): void
if (false) {
final class CancelUnpaidOrdersCommand
{
$this
->setDescription(
'Removes order that have been unpaid for a configured period. Configuration parameter - sylius_order.order_expiration_period.',
)
;
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$expirationTime = $this->getContainer()->getParameter('sylius_order.order_expiration_period');
$output->writeln(sprintf(
'Command will cancel orders that have been unpaid for <info>%s</info>.',
(string) $expirationTime,
));
$unpaidCartsStateUpdater = $this->getContainer()->get('sylius.unpaid_orders_state_updater');
$unpaidCartsStateUpdater->cancel();
$this->getContainer()->get('sylius.manager.order')->flush();
$output->writeln('<info>Unpaid orders have been canceled</info>');
return 0;
}
}

View file

@ -13,38 +13,18 @@ declare(strict_types=1);
namespace Sylius\Bundle\CoreBundle\Command;
use RuntimeException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
trigger_deprecation(
'sylius/core-bundle',
'1.13',
'The "%s" class is deprecated and will be removed in Sylius 2.0. Use "%s" instead.',
CheckRequirementsCommand::class,
\Sylius\Bundle\CoreBundle\Console\Command\CheckRequirementsCommand::class,
);
final class CheckRequirementsCommand extends AbstractInstallCommand
{
protected static $defaultName = 'sylius:install:check-requirements';
class_exists(\Sylius\Bundle\CoreBundle\Console\Command\CheckRequirementsCommand::class);
protected function configure(): void
if (false) {
final class CheckRequirementsCommand
{
$this
->setDescription('Checks if all Sylius requirements are satisfied.')
->setHelp(
<<<EOT
The <info>%command.name%</info> command checks system requirements.
EOT
)
;
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$fulfilled = $this->getContainer()->get('sylius.installer.checker.sylius_requirements')->check($input, $output);
if (!$fulfilled) {
throw new RuntimeException(
'Some system requirements are not fulfilled. Please check output messages and fix them.',
);
}
$output->writeln('<info>Success! Your system can run Sylius properly.</info>');
return 0;
}
}

View file

@ -13,39 +13,18 @@ declare(strict_types=1);
namespace Sylius\Bundle\CoreBundle\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
trigger_deprecation(
'sylius/core-bundle',
'1.13',
'The "%s" class is deprecated and will be removed in Sylius 2.0. Use "%s" instead.',
InformAboutGUSCommand::class,
\Sylius\Bundle\CoreBundle\Console\Command\InformAboutGUSCommand::class,
);
final class InformAboutGUSCommand extends Command
{
protected static $defaultName = 'sylius:inform-about-gus';
class_exists(\Sylius\Bundle\CoreBundle\Console\Command\InformAboutGUSCommand::class);
protected function configure(): void
if (false) {
final class InformAboutGUSCommand
{
$this->setDescription('Informs about Sylius internal statistical service');
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$style = new SymfonyStyle($input, $output);
$style->note(
[
'For purely statistical purposes and in order to inform you about important updates and security patches, Sylius might send non-sensitive data to our servers. We send:',
'* Hostname',
'* User-agent',
'* Locale',
'* Environment (test, dev or prod)',
'* Currently used Sylius version',
'* Date of the last contact',
'If you do not consent please follow this cookbook article:',
'https://docs.sylius.com/en/latest/cookbook/configuration/disabling-admin-notifications.html',
'That being said, every time we get a notification about a new site deployed with Sylius, it brings a huge smile to our face and motivates us to continue our Open Source work.',
],
);
return 0;
}
}

View file

@ -13,49 +13,18 @@ declare(strict_types=1);
namespace Sylius\Bundle\CoreBundle\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
trigger_deprecation(
'sylius/core-bundle',
'1.13',
'The "%s" class is deprecated and will be removed in Sylius 2.0. Use "%s" instead.',
InstallAssetsCommand::class,
\Sylius\Bundle\CoreBundle\Console\Command\InstallAssetsCommand::class,
);
final class InstallAssetsCommand extends AbstractInstallCommand
{
protected static $defaultName = 'sylius:install:assets';
class_exists(\Sylius\Bundle\CoreBundle\Console\Command\InstallAssetsCommand::class);
protected function configure(): void
if (false) {
final class InstallAssetsCommand
{
$this
->setDescription('Installs all Sylius assets.')
->setHelp(
<<<EOT
The <info>%command.name%</info> command downloads and installs all Sylius media assets.
EOT
)
;
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$output->writeln(sprintf(
'Installing Sylius assets for environment <info>%s</info>.',
$this->getEnvironment(),
));
try {
$publicDir = $this->getContainer()->getParameter('sylius_core.public_dir');
$this->ensureDirectoryExistsAndIsWritable($publicDir . '/assets/', $output);
$this->ensureDirectoryExistsAndIsWritable($publicDir . '/bundles/', $output);
} catch (\RuntimeException $exception) {
$output->writeln($exception->getMessage());
return 1;
}
$commands = [
'assets:install' => ['target' => $publicDir],
];
$this->runCommands($commands, $output);
return 0;
}
}

View file

@ -13,124 +13,18 @@ declare(strict_types=1);
namespace Sylius\Bundle\CoreBundle\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Process\Exception\RuntimeException;
trigger_deprecation(
'sylius/core-bundle',
'1.13',
'The "%s" class is deprecated and will be removed in Sylius 2.0. Use "%s" instead.',
InstallCommand::class,
\Sylius\Bundle\CoreBundle\Console\Command\InstallCommand::class,
);
final class InstallCommand extends AbstractInstallCommand
{
protected static $defaultName = 'sylius:install';
class_exists(\Sylius\Bundle\CoreBundle\Console\Command\InstallCommand::class);
private array $commands = [
[
'command' => 'check-requirements',
'message' => 'Checking system requirements.',
],
[
'command' => 'database',
'message' => 'Setting up the database.',
],
[
'command' => 'setup',
'message' => 'Shop configuration.',
],
[
'command' => 'jwt-setup',
'message' => 'Configuring JWT token.',
],
[
'command' => 'assets',
'message' => 'Installing assets.',
],
];
protected function configure(): void
if (false) {
final class InstallCommand
{
$this
->setDescription('Installs Sylius in your preferred environment.')
->setHelp(
<<<EOT
The <info>%command.name%</info> command installs Sylius.
EOT
)
->addOption('fixture-suite', 's', InputOption::VALUE_OPTIONAL, 'Load specified fixture suite during install', null)
;
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$suite = $input->getOption('fixture-suite');
$outputStyle = new SymfonyStyle($input, $output);
$outputStyle->writeln('<info>Installing Sylius...</info>');
$outputStyle->writeln($this->getSyliusLogo());
$this->ensureDirectoryExistsAndIsWritable((string) $this->getContainer()->getParameter('kernel.cache_dir'), $output);
$errored = false;
/**
* @var int $step
* @var array $command
*/
foreach ($this->commands as $step => $command) {
try {
$outputStyle->newLine();
$outputStyle->section(sprintf(
'Step %d of %d. <info>%s</info>',
$step + 1,
count($this->commands),
$command['message'],
));
$parameters = [];
if ('database' === $command['command'] && null !== $suite) {
$parameters['--fixture-suite'] = $suite;
}
$this->commandExecutor->runCommand('sylius:install:' . $command['command'], $parameters, $output);
} catch (RuntimeException) {
$errored = true;
}
}
$outputStyle->newLine(2);
$outputStyle->success($this->getProperFinalMessage($errored));
$outputStyle->writeln('You can now open your store at the following path under the website root: /');
return $errored ? 1 : 0;
}
private function getProperFinalMessage(bool $errored): string
{
if ($errored) {
return 'Sylius has been installed, but some error occurred.';
}
return 'Sylius has been successfully installed.';
}
private function getSyliusLogo(): string
{
return '
<info>,</info>
<info>,;:,</info>
<info>`;;;.:`</info>
<info>`::;` :`</info>
<info>:::` `</info> .\'++: \'\'. \'.
<info>`:::</info> :+\',;+\' :+; `+.
<info>::::</info> +\' :\' `+;
<info>`:::,</info> \'+` ++ :+.`+; `++. ;+\' \'\' ,++++.
<info>,:::`</info> `++\'. .+: `+\' `+; .+, ;+ +\' +; \'\'
<info>::::`</info> ,+++. \'+` :+. `+; `+, ;+ +\' \'+.
<info>,. .::::</info> .++` `+: +\' `+; `+, ;+ +\' `;++;
<info>`;;.:::` :::::</info> :+. \'+,+. `+; `+, ;+ `+\' .++
<info>.;;;;;;::`.::::,</info> +\'` `++ `++\' `+; `+: :+. `++\' \'. ;+
<info>,;;;;;;;;;:::::</info> .+++++` ;+, ++; ++, `\'+++,\'+\' :++++,
<info>,;;;;;;;;;:::</info>` ;\'
<info>:;;;;;;;;;:,</info> :.:+,
<info>;;;;;;;;;:</info> ;++,'
;
}
}

View file

@ -13,53 +13,18 @@ declare(strict_types=1);
namespace Sylius\Bundle\CoreBundle\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
trigger_deprecation(
'sylius/core-bundle',
'1.13',
'The "%s" class is deprecated and will be removed in Sylius 2.0. Use "%s" instead.',
InstallDatabaseCommand::class,
\Sylius\Bundle\CoreBundle\Console\Command\InstallDatabaseCommand::class,
);
final class InstallDatabaseCommand extends AbstractInstallCommand
{
protected static $defaultName = 'sylius:install:database';
class_exists(\Sylius\Bundle\CoreBundle\Console\Command\InstallDatabaseCommand::class);
protected function configure(): void
if (false) {
final class InstallDatabaseCommand
{
$this
->setDescription('Install Sylius database.')
->setHelp(
<<<EOT
The <info>%command.name%</info> command creates Sylius database.
EOT
)
->addOption('fixture-suite', 's', InputOption::VALUE_OPTIONAL, 'Load specified fixture suite during install', null)
;
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$suite = $input->getOption('fixture-suite');
$outputStyle = new SymfonyStyle($input, $output);
$outputStyle->writeln(sprintf(
'Creating Sylius database for environment <info>%s</info>.',
$this->getEnvironment(),
));
$commands = $this
->getContainer()
->get('sylius.commands_provider.database_setup')
->getCommands($input, $output, $this->getHelper('question'))
;
$this->runCommands($commands, $output);
$outputStyle->newLine();
$parameters = [];
if (null !== $suite) {
$parameters['--fixture-suite'] = $suite;
}
$this->commandExecutor->runCommand('sylius:install:sample-data', $parameters, $output);
return 0;
}
}

View file

@ -13,75 +13,18 @@ declare(strict_types=1);
namespace Sylius\Bundle\CoreBundle\Command;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Style\SymfonyStyle;
trigger_deprecation(
'sylius/core-bundle',
'1.13',
'The "%s" class is deprecated and will be removed in Sylius 2.0. Use "%s" instead.',
InstallSampleDataCommand::class,
\Sylius\Bundle\CoreBundle\Console\Command\InstallSampleDataCommand::class,
);
final class InstallSampleDataCommand extends AbstractInstallCommand
{
protected static $defaultName = 'sylius:install:sample-data';
class_exists(\Sylius\Bundle\CoreBundle\Console\Command\InstallSampleDataCommand::class);
protected function configure(): void
if (false) {
final class InstallSampleDataCommand
{
$this
->setDescription('Install sample data into Sylius.')
->setHelp(
<<<EOT
The <info>%command.name%</info> command loads the sample data for Sylius.
EOT
)
->addOption('fixture-suite', 's', InputOption::VALUE_OPTIONAL, 'Load specified fixture suite during install', null)
;
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
/** @var QuestionHelper $questionHelper */
$questionHelper = $this->getHelper('question');
$suite = $input->getOption('fixture-suite');
$outputStyle = new SymfonyStyle($input, $output);
$outputStyle->newLine();
$outputStyle->writeln(sprintf(
'Loading sample data for environment <info>%s</info> from suite <info>%s</info>.',
$this->getEnvironment(),
$suite ?? 'default',
));
$outputStyle->writeln('<error>Warning! This action will erase your database.</error>');
if (!$questionHelper->ask($input, $output, new ConfirmationQuestion('Continue? (y/N) ', null !== $suite))) {
$outputStyle->writeln('Cancelled loading sample data.');
return 0;
}
try {
$publicDir = $this->getContainer()->getParameter('sylius_core.public_dir');
$this->ensureDirectoryExistsAndIsWritable($publicDir . '/media/', $output);
$this->ensureDirectoryExistsAndIsWritable($publicDir . '/media/image/', $output);
} catch (\RuntimeException $exception) {
$outputStyle->writeln($exception->getMessage());
return 1;
}
$parameters = ['--no-interaction' => true];
if (null !== $suite) {
$parameters['suite'] = $suite;
}
$commands = [
'sylius:fixtures:load' => $parameters,
];
$this->runCommands($commands, $output);
$outputStyle->newLine(2);
return 0;
}
}

View file

@ -13,48 +13,18 @@ declare(strict_types=1);
namespace Sylius\Bundle\CoreBundle\Command;
use Symfony\Component\Console\Helper\HelperInterface;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Webmozart\Assert\Assert;
trigger_deprecation(
'sylius/core-bundle',
'1.13',
'The "%s" class is deprecated and will be removed in Sylius 2.0. Use "%s" instead.',
JwtConfigurationCommand::class,
\Sylius\Bundle\CoreBundle\Console\Command\JwtConfigurationCommand::class,
);
final class JwtConfigurationCommand extends AbstractInstallCommand
{
protected static $defaultName = 'sylius:install:jwt-setup';
class_exists(\Sylius\Bundle\CoreBundle\Console\Command\JwtConfigurationCommand::class);
protected function configure(): void
if (false) {
final class JwtConfigurationCommand
{
$this
->setDescription('Setup JWT token')
->setHelp(
<<<EOT
The <info>%command.name%</info> command generates JWT token.
EOT
)
;
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
/** @var HelperInterface $helper */
$helper = $this->getHelper('question');
$output->writeln('Generating JWT token for Sylius API');
$question = new ConfirmationQuestion('Do you want to generate JWT token? (y/N)', false);
Assert::isInstanceOf($helper, QuestionHelper::class);
if (!$helper->ask($input, $output, $question)) {
return 0;
}
$this->commandExecutor->runCommand('lexik:jwt:generate-keypair', ['--overwrite' => true], $output);
$output->writeln('Please, remember to enable Sylius API');
$output->writeln('https://docs.sylius.com/en/1.10/book/api/introduction.html');
return 0;
}
}

View file

@ -13,24 +13,18 @@ declare(strict_types=1);
namespace Sylius\Bundle\CoreBundle\Command\Model;
final class PluginInfo
{
public function __construct(private string $name, private string $description, private string $url)
{
}
trigger_deprecation(
'sylius/core-bundle',
'1.13',
'The "%s" class is deprecated and will be removed in Sylius 2.0. Use "%s" instead.',
PluginInfo::class,
\Sylius\Bundle\CoreBundle\Console\Command\Model\PluginInfo::class,
);
public function name(): string
{
return $this->name;
}
class_exists(\Sylius\Bundle\CoreBundle\Console\Command\Model\PluginInfo::class);
public function description(): string
if (false) {
final class PluginInfo
{
return $this->description;
}
public function url(): string
{
return $this->url;
}
}

View file

@ -13,204 +13,18 @@ declare(strict_types=1);
namespace Sylius\Bundle\CoreBundle\Command;
use Sylius\Component\Core\Model\AdminUserInterface;
use Sylius\Component\User\Repository\UserRepositoryInterface;
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\Console\Style\SymfonyStyle;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\ConstraintViolationListInterface;
use Webmozart\Assert\Assert;
trigger_deprecation(
'sylius/core-bundle',
'1.13',
'The "%s" class is deprecated and will be removed in Sylius 2.0. Use "%s" instead.',
SetupCommand::class,
\Sylius\Bundle\CoreBundle\Console\Command\SetupCommand::class,
);
final class SetupCommand extends AbstractInstallCommand
{
protected static $defaultName = 'sylius:install:setup';
class_exists(\Sylius\Bundle\CoreBundle\Console\Command\SetupCommand::class);
protected function configure(): void
if (false) {
final class SetupCommand
{
$this
->setDescription('Sylius configuration setup.')
->setHelp(
<<<EOT
The <info>%command.name%</info> command allows user to configure basic Sylius data.
EOT
)
;
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$currency = $this->getContainer()->get('sylius.setup.currency')->setup($input, $output, $this->getHelper('question'));
$locale = $this->getContainer()->get('sylius.setup.locale')->setup($input, $output, $this->getHelper('question'));
$this->getContainer()->get('sylius.setup.channel')->setup($locale, $currency);
$this->setupAdministratorUser($input, $output, $locale->getCode());
return 0;
}
protected function setupAdministratorUser(InputInterface $input, OutputInterface $output, string $localeCode): void
{
$outputStyle = new SymfonyStyle($input, $output);
$outputStyle->writeln('Create your administrator account.');
$userManager = $this->getContainer()->get('sylius.manager.admin_user');
$userFactory = $this->getContainer()->get('sylius.factory.admin_user');
try {
$user = $this->configureNewUser($userFactory->createNew(), $input, $output);
} catch (\InvalidArgumentException) {
return;
}
$user->setEnabled(true);
$user->setLocaleCode($localeCode);
$userManager->persist($user);
$userManager->flush();
$outputStyle->writeln('<info>Administrator account successfully registered.</info>');
$outputStyle->newLine();
}
private function configureNewUser(
AdminUserInterface $user,
InputInterface $input,
OutputInterface $output,
): AdminUserInterface {
/** @var UserRepositoryInterface $userRepository */
$userRepository = $this->getAdminUserRepository();
if ($input->getOption('no-interaction')) {
Assert::null($userRepository->findOneByEmail('sylius@example.com'));
$user->setEmail('sylius@example.com');
$user->setUsername('sylius');
$user->setPlainPassword('sylius');
return $user;
}
$email = $this->getAdministratorEmail($input, $output);
$user->setEmail($email);
$user->setUsername($this->getAdministratorUsername($input, $output, $email));
$user->setPlainPassword($this->getAdministratorPassword($input, $output));
return $user;
}
private function createEmailQuestion(): Question
{
return (new Question('E-mail: '))
->setValidator(
/**
* @param mixed $value
*/
function ($value): string {
/** @var ConstraintViolationListInterface $errors */
$errors = $this->getContainer()->get('validator')->validate((string) $value, [new Email(), new NotBlank()]);
foreach ($errors as $error) {
throw new \DomainException((string) $error->getMessage());
}
return $value;
},
)
->setMaxAttempts(3)
;
}
private function getAdministratorEmail(InputInterface $input, OutputInterface $output): string
{
/** @var QuestionHelper $questionHelper */
$questionHelper = $this->getHelper('question');
/** @var UserRepositoryInterface $userRepository */
$userRepository = $this->getAdminUserRepository();
do {
$question = $this->createEmailQuestion();
$email = $questionHelper->ask($input, $output, $question);
$exists = null !== $userRepository->findOneByEmail($email);
if ($exists) {
$output->writeln('<error>E-Mail is already in use!</error>');
}
} while ($exists);
return $email;
}
private function getAdministratorUsername(InputInterface $input, OutputInterface $output, string $email): string
{
/** @var QuestionHelper $questionHelper */
$questionHelper = $this->getHelper('question');
/** @var UserRepositoryInterface $userRepository */
$userRepository = $this->getAdminUserRepository();
do {
$question = new Question('Username (press enter to use email): ', $email);
$username = $questionHelper->ask($input, $output, $question);
$exists = null !== $userRepository->findOneBy(['username' => $username]);
if ($exists) {
$output->writeln('<error>Username is already in use!</error>');
}
} while ($exists);
return $username;
}
private function getAdministratorPassword(InputInterface $input, OutputInterface $output): string
{
/** @var QuestionHelper $questionHelper */
$questionHelper = $this->getHelper('question');
$validator = $this->getPasswordQuestionValidator();
do {
$passwordQuestion = $this->createPasswordQuestion('Choose password:', $validator);
$confirmPasswordQuestion = $this->createPasswordQuestion('Confirm password:', $validator);
$password = $questionHelper->ask($input, $output, $passwordQuestion);
$repeatedPassword = $questionHelper->ask($input, $output, $confirmPasswordQuestion);
if ($repeatedPassword !== $password) {
$output->writeln('<error>Passwords do not match!</error>');
}
} while ($repeatedPassword !== $password);
return $password;
}
private function getPasswordQuestionValidator(): \Closure
{
return
/** @param mixed $value */
function ($value): string {
/** @var ConstraintViolationListInterface $errors */
$errors = $this->getContainer()->get('validator')->validate($value, [new NotBlank()]);
foreach ($errors as $error) {
throw new \DomainException((string) $error->getMessage());
}
return $value;
}
;
}
private function createPasswordQuestion(string $message, \Closure $validator): Question
{
return (new Question($message))
->setValidator($validator)
->setMaxAttempts(3)
->setHidden(true)
->setHiddenFallback(false)
;
}
private function getAdminUserRepository(): UserRepositoryInterface
{
return $this->getContainer()->get('sylius.repository.admin_user');
}
}

View file

@ -13,52 +13,18 @@ declare(strict_types=1);
namespace Sylius\Bundle\CoreBundle\Command;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Sylius\Bundle\CoreBundle\Command\Model\PluginInfo;
use Sylius\Bundle\CoreBundle\Installer\Renderer\TableRenderer;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
trigger_deprecation(
'sylius/core-bundle',
'1.13',
'The "%s" class is deprecated and will be removed in Sylius 2.0. Use "%s" instead.',
ShowAvailablePluginsCommand::class,
\Sylius\Bundle\CoreBundle\Console\Command\ShowAvailablePluginsCommand::class,
);
final class ShowAvailablePluginsCommand extends Command
{
protected static $defaultName = 'sylius:show-available-plugins';
class_exists(\Sylius\Bundle\CoreBundle\Console\Command\ShowAvailablePluginsCommand::class);
/** @var ArrayCollection<array-key, PluginInfo> */
private Collection $plugins;
protected function configure(): void
if (false) {
final class ShowAvailablePluginsCommand
{
$this->setDescription('Shows official Sylius Plugins');
$this->configurePlugins();
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$output->writeln('<comment>Available official plugins and selected community plugins:</comment>');
$pluginTable = new TableRenderer($output);
$pluginTable->setHeaders(['Plugin', 'Description', 'URL']);
foreach ($this->plugins as $plugin) {
$pluginTable->addRow([sprintf('<info>%s</info>', $plugin->name()), $plugin->description(), $plugin->url()]);
}
$pluginTable->render();
return 0;
}
private function configurePlugins(): void
{
$this->plugins = new ArrayCollection();
$this->plugins->add(new PluginInfo('<info>Admin Order Creation</info>', 'Creating (and copying) orders in the administration panel.', 'https://github.com/Sylius/AdminOrderCreationPlugin'));
$this->plugins->add(new PluginInfo('<info>Customer Order Cancellation</info>', 'Allows customers to quickly cancel their unpaid and unshipped orders.', 'https://github.com/Sylius/CustomerOrderCancellationPlugin'));
$this->plugins->add(new PluginInfo('<info>Customer Reorder</info>', 'Convenient reordering for the customers from the `My account` section.', 'https://github.com/Sylius/CustomerReorderPlugin'));
$this->plugins->add(new PluginInfo('<info>Invoicing</info>', 'Automatised, basic invoicing system for orders.', 'https://github.com/Sylius/InvoicingPlugin'));
$this->plugins->add(new PluginInfo('<info>Refund</info>', 'Full and partial refunds of items and/or shipping costs including Credit Memos.', 'https://github.com/Sylius/RefundPlugin'));
$this->plugins->add(new PluginInfo('<info>CMS</info>', 'This plugin allows you to add dynamic blocks with images, text or HTML to your storefront as well as pages and FAQs section.', 'https://github.com/BitBagCommerce/SyliusCmsPlugin'));
}
}

View file

@ -0,0 +1,133 @@
<?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\Console\Command;
use Doctrine\ORM\EntityManagerInterface;
use Sylius\Bundle\CoreBundle\Installer\Executor\CommandExecutor;
use SyliusLabs\Polyfill\Symfony\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\Console\Output\OutputInterface;
abstract class AbstractInstallCommand extends ContainerAwareCommand
{
/** @deprecated */
public const WEB_ASSETS_DIRECTORY = 'web/assets/';
/** @deprecated */
public const WEB_BUNDLES_DIRECTORY = 'web/bundles/';
/** @deprecated */
public const WEB_MEDIA_DIRECTORY = 'web/media/';
/** @deprecated */
public const WEB_MEDIA_IMAGE_DIRECTORY = 'web/media/image/';
/** @var CommandExecutor|null */
protected $commandExecutor;
protected function initialize(InputInterface $input, OutputInterface $output): void
{
$application = $this->getApplication();
$application->setCatchExceptions(false);
$this->commandExecutor = new CommandExecutor($input, $output, $application);
}
/**
* @return object
*/
protected function get(string $id)
{
return $this->getContainer()->get($id);
}
protected function getEnvironment(): string
{
return (string) $this->getContainer()->getParameter('kernel.environment');
}
protected function isDebug(): bool
{
return (bool) $this->getContainer()->getParameter('kernel.debug');
}
/**
* @param array<array-key, mixed> $headers
* @param array<array-key, mixed> $rows
*/
protected function renderTable(array $headers, array $rows, OutputInterface $output): void
{
$table = new Table($output);
$table
->setHeaders($headers)
->setRows($rows)
->render()
;
}
protected function createProgressBar(OutputInterface $output, int $length = 10): ProgressBar
{
$progress = new ProgressBar($output);
$progress->setBarCharacter('<info>░</info>');
$progress->setEmptyBarCharacter(' ');
$progress->setProgressCharacter('<comment>░</comment>');
$progress->start($length);
return $progress;
}
/** @param array<array-key, mixed> $commands */
protected function runCommands(array $commands, OutputInterface $output, bool $displayProgress = true): void
{
$progress = $this->createProgressBar($displayProgress ? $output : new NullOutput(), count($commands));
foreach ($commands as $key => $value) {
if (is_string($key)) {
$command = $key;
$parameters = $value;
} else {
$command = $value;
$parameters = [];
}
$this->commandExecutor->runCommand($command, $parameters);
// PDO does not always close the connection after Doctrine commands.
// See https://github.com/symfony/symfony/issues/11750.
/** @var EntityManagerInterface $entityManager */
$entityManager = $this->getContainer()->get('doctrine')->getManager();
$entityManager->getConnection()->close();
$progress->advance();
}
$progress->finish();
}
protected function ensureDirectoryExistsAndIsWritable(string $directory, OutputInterface $output): void
{
$checker = $this->getContainer()->get('sylius.installer.checker.command_directory');
$checker->setCommandName($this->getName());
$checker->ensureDirectoryExists($directory, $output);
$checker->ensureDirectoryIsWritable($directory, $output);
}
}
class_alias(AbstractInstallCommand::class, '\Sylius\Bundle\CoreBundle\Command\AbstractInstallCommand');

View file

@ -0,0 +1,52 @@
<?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\Console\Command;
use SyliusLabs\Polyfill\Symfony\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
final class CancelUnpaidOrdersCommand extends ContainerAwareCommand
{
protected static $defaultName = 'sylius:cancel-unpaid-orders';
protected function configure(): void
{
$this
->setDescription(
'Removes order that have been unpaid for a configured period. Configuration parameter - sylius_order.order_expiration_period.',
)
;
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$expirationTime = $this->getContainer()->getParameter('sylius_order.order_expiration_period');
$output->writeln(sprintf(
'Command will cancel orders that have been unpaid for <info>%s</info>.',
(string) $expirationTime,
));
$unpaidCartsStateUpdater = $this->getContainer()->get('sylius.unpaid_orders_state_updater');
$unpaidCartsStateUpdater->cancel();
$this->getContainer()->get('sylius.manager.order')->flush();
$output->writeln('<info>Unpaid orders have been canceled</info>');
return 0;
}
}
class_alias(CancelUnpaidOrdersCommand::class, '\Sylius\Bundle\CoreBundle\Command\CancelUnpaidOrdersCommand');

View file

@ -0,0 +1,52 @@
<?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\Console\Command;
use RuntimeException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
final class CheckRequirementsCommand extends AbstractInstallCommand
{
protected static $defaultName = 'sylius:install:check-requirements';
protected function configure(): void
{
$this
->setDescription('Checks if all Sylius requirements are satisfied.')
->setHelp(
<<<EOT
The <info>%command.name%</info> command checks system requirements.
EOT
)
;
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$fulfilled = $this->getContainer()->get('sylius.installer.checker.sylius_requirements')->check($input, $output);
if (!$fulfilled) {
throw new RuntimeException(
'Some system requirements are not fulfilled. Please check output messages and fix them.',
);
}
$output->writeln('<info>Success! Your system can run Sylius properly.</info>');
return 0;
}
}
class_alias(CheckRequirementsCommand::class, '\Sylius\Bundle\CoreBundle\Command\CheckRequirementsCommand');

View file

@ -0,0 +1,53 @@
<?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\Console\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
final class InformAboutGUSCommand extends Command
{
protected static $defaultName = 'sylius:inform-about-gus';
protected function configure(): void
{
$this->setDescription('Informs about Sylius internal statistical service');
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$style = new SymfonyStyle($input, $output);
$style->note(
[
'For purely statistical purposes and in order to inform you about important updates and security patches, Sylius might send non-sensitive data to our servers. We send:',
'* Hostname',
'* User-agent',
'* Locale',
'* Environment (test, dev or prod)',
'* Currently used Sylius version',
'* Date of the last contact',
'If you do not consent please follow this cookbook article:',
'https://docs.sylius.com/en/latest/cookbook/configuration/disabling-admin-notifications.html',
'That being said, every time we get a notification about a new site deployed with Sylius, it brings a huge smile to our face and motivates us to continue our Open Source work.',
],
);
return 0;
}
}
class_alias(InformAboutGUSCommand::class, '\Sylius\Bundle\CoreBundle\Command\InformAboutGUSCommand');

View file

@ -0,0 +1,63 @@
<?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\Console\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
final class InstallAssetsCommand extends AbstractInstallCommand
{
protected static $defaultName = 'sylius:install:assets';
protected function configure(): void
{
$this
->setDescription('Installs all Sylius assets.')
->setHelp(
<<<EOT
The <info>%command.name%</info> command downloads and installs all Sylius media assets.
EOT
)
;
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$output->writeln(sprintf(
'Installing Sylius assets for environment <info>%s</info>.',
$this->getEnvironment(),
));
try {
$publicDir = $this->getContainer()->getParameter('sylius_core.public_dir');
$this->ensureDirectoryExistsAndIsWritable($publicDir . '/assets/', $output);
$this->ensureDirectoryExistsAndIsWritable($publicDir . '/bundles/', $output);
} catch (\RuntimeException $exception) {
$output->writeln($exception->getMessage());
return 1;
}
$commands = [
'assets:install' => ['target' => $publicDir],
];
$this->runCommands($commands, $output);
return 0;
}
}
class_alias(InstallAssetsCommand::class, '\Sylius\Bundle\CoreBundle\Command\InstallAssetsCommand');

View file

@ -0,0 +1,135 @@
<?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\Console\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Process\Exception\RuntimeException;
final class InstallCommand extends AbstractInstallCommand
{
protected static $defaultName = 'sylius:install';
/** @var array<int, array<string, string>> $commands */
private array $commands = [
[
'command' => 'check-requirements',
'message' => 'Checking system requirements.',
],
[
'command' => 'database',
'message' => 'Setting up the database.',
],
[
'command' => 'setup',
'message' => 'Shop configuration.',
],
[
'command' => 'jwt-setup',
'message' => 'Configuring JWT token.',
],
[
'command' => 'assets',
'message' => 'Installing assets.',
],
];
protected function configure(): void
{
$this
->setDescription('Installs Sylius in your preferred environment.')
->setHelp(
<<<EOT
The <info>%command.name%</info> command installs Sylius.
EOT
)
->addOption('fixture-suite', 's', InputOption::VALUE_OPTIONAL, 'Load specified fixture suite during install', null)
;
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$suite = $input->getOption('fixture-suite');
$outputStyle = new SymfonyStyle($input, $output);
$outputStyle->writeln('<info>Installing Sylius...</info>');
$outputStyle->writeln($this->getSyliusLogo());
$this->ensureDirectoryExistsAndIsWritable((string) $this->getContainer()->getParameter('kernel.cache_dir'), $output);
$errored = false;
foreach ($this->commands as $step => $command) {
try {
$outputStyle->newLine();
$outputStyle->section(sprintf(
'Step %d of %d. <info>%s</info>',
$step + 1,
count($this->commands),
$command['message'],
));
$parameters = [];
if ('database' === $command['command'] && null !== $suite) {
$parameters['--fixture-suite'] = $suite;
}
$this->commandExecutor->runCommand('sylius:install:' . $command['command'], $parameters, $output);
} catch (RuntimeException) {
$errored = true;
}
}
$outputStyle->newLine(2);
$outputStyle->success($this->getProperFinalMessage($errored));
$outputStyle->writeln('You can now open your store at the following path under the website root: /');
return $errored ? 1 : 0;
}
private function getProperFinalMessage(bool $errored): string
{
if ($errored) {
return 'Sylius has been installed, but some error occurred.';
}
return 'Sylius has been successfully installed.';
}
private function getSyliusLogo(): string
{
return '
<info>,</info>
<info>,;:,</info>
<info>`;;;.:`</info>
<info>`::;` :`</info>
<info>:::` `</info> .\'++: \'\'. \'.
<info>`:::</info> :+\',;+\' :+; `+.
<info>::::</info> +\' :\' `+;
<info>`:::,</info> \'+` ++ :+.`+; `++. ;+\' \'\' ,++++.
<info>,:::`</info> `++\'. .+: `+\' `+; .+, ;+ +\' +; \'\'
<info>::::`</info> ,+++. \'+` :+. `+; `+, ;+ +\' \'+.
<info>,. .::::</info> .++` `+: +\' `+; `+, ;+ +\' `;++;
<info>`;;.:::` :::::</info> :+. \'+,+. `+; `+, ;+ `+\' .++
<info>.;;;;;;::`.::::,</info> +\'` `++ `++\' `+; `+: :+. `++\' \'. ;+
<info>,;;;;;;;;;:::::</info> .+++++` ;+, ++; ++, `\'+++,\'+\' :++++,
<info>,;;;;;;;;;:::</info>` ;\'
<info>:;;;;;;;;;:,</info> :.:+,
<info>;;;;;;;;;:</info> ;++,'
;
}
}
class_alias(InstallCommand::class, '\Sylius\Bundle\CoreBundle\Command\InstallCommand');

View file

@ -0,0 +1,67 @@
<?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\Console\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
final class InstallDatabaseCommand extends AbstractInstallCommand
{
protected static $defaultName = 'sylius:install:database';
protected function configure(): void
{
$this
->setDescription('Install Sylius database.')
->setHelp(
<<<EOT
The <info>%command.name%</info> command creates Sylius database.
EOT
)
->addOption('fixture-suite', 's', InputOption::VALUE_OPTIONAL, 'Load specified fixture suite during install', null)
;
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$suite = $input->getOption('fixture-suite');
$outputStyle = new SymfonyStyle($input, $output);
$outputStyle->writeln(sprintf(
'Creating Sylius database for environment <info>%s</info>.',
$this->getEnvironment(),
));
$commands = $this
->getContainer()
->get('sylius.commands_provider.database_setup')
->getCommands($input, $output, $this->getHelper('question'))
;
$this->runCommands($commands, $output);
$outputStyle->newLine();
$parameters = [];
if (null !== $suite) {
$parameters['--fixture-suite'] = $suite;
}
$this->commandExecutor->runCommand('sylius:install:sample-data', $parameters, $output);
return 0;
}
}
class_alias(InstallDatabaseCommand::class, '\Sylius\Bundle\CoreBundle\Command\InstallDatabaseCommand');

View file

@ -0,0 +1,89 @@
<?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\Console\Command;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Style\SymfonyStyle;
final class InstallSampleDataCommand extends AbstractInstallCommand
{
protected static $defaultName = 'sylius:install:sample-data';
protected function configure(): void
{
$this
->setDescription('Install sample data into Sylius.')
->setHelp(
<<<EOT
The <info>%command.name%</info> command loads the sample data for Sylius.
EOT
)
->addOption('fixture-suite', 's', InputOption::VALUE_OPTIONAL, 'Load specified fixture suite during install', null)
;
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
/** @var QuestionHelper $questionHelper */
$questionHelper = $this->getHelper('question');
$suite = $input->getOption('fixture-suite');
$outputStyle = new SymfonyStyle($input, $output);
$outputStyle->newLine();
$outputStyle->writeln(sprintf(
'Loading sample data for environment <info>%s</info> from suite <info>%s</info>.',
$this->getEnvironment(),
$suite ?? 'default',
));
$outputStyle->writeln('<error>Warning! This action will erase your database.</error>');
if (!$questionHelper->ask($input, $output, new ConfirmationQuestion('Continue? (y/N) ', null !== $suite))) {
$outputStyle->writeln('Cancelled loading sample data.');
return 0;
}
try {
$publicDir = $this->getContainer()->getParameter('sylius_core.public_dir');
$this->ensureDirectoryExistsAndIsWritable($publicDir . '/media/', $output);
$this->ensureDirectoryExistsAndIsWritable($publicDir . '/media/image/', $output);
} catch (\RuntimeException $exception) {
$outputStyle->writeln($exception->getMessage());
return 1;
}
$parameters = ['--no-interaction' => true];
if (null !== $suite) {
$parameters['suite'] = $suite;
}
$commands = [
'sylius:fixtures:load' => $parameters,
];
$this->runCommands($commands, $output);
$outputStyle->newLine(2);
return 0;
}
}
class_alias(InstallSampleDataCommand::class, '\Sylius\Bundle\CoreBundle\Command\InstallSampleDataCommand');

View file

@ -0,0 +1,62 @@
<?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\Console\Command;
use Symfony\Component\Console\Helper\HelperInterface;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Webmozart\Assert\Assert;
final class JwtConfigurationCommand extends AbstractInstallCommand
{
protected static $defaultName = 'sylius:install:jwt-setup';
protected function configure(): void
{
$this
->setDescription('Setup JWT token')
->setHelp(
<<<EOT
The <info>%command.name%</info> command generates JWT token.
EOT
)
;
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
/** @var HelperInterface $helper */
$helper = $this->getHelper('question');
$output->writeln('Generating JWT token for Sylius API');
$question = new ConfirmationQuestion('Do you want to generate JWT token? (y/N)', false);
Assert::isInstanceOf($helper, QuestionHelper::class);
if (!$helper->ask($input, $output, $question)) {
return 0;
}
$this->commandExecutor->runCommand('lexik:jwt:generate-keypair', ['--overwrite' => true], $output);
$output->writeln('Please, remember to enable Sylius API');
$output->writeln('https://docs.sylius.com/en/1.10/book/api/introduction.html');
return 0;
}
}
class_alias(JwtConfigurationCommand::class, '\Sylius\Bundle\CoreBundle\Command\JwtConfigurationCommand');

View file

@ -0,0 +1,38 @@
<?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\Console\Command\Model;
final class PluginInfo
{
public function __construct(private string $name, private string $description, private string $url)
{
}
public function name(): string
{
return $this->name;
}
public function description(): string
{
return $this->description;
}
public function url(): string
{
return $this->url;
}
}
class_alias(PluginInfo::class, '\Sylius\Bundle\CoreBundle\Command\Model\PluginInfo');

View file

@ -0,0 +1,217 @@
<?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\Console\Command;
use Sylius\Component\Core\Model\AdminUserInterface;
use Sylius\Component\User\Model\UserInterface;
use Sylius\Component\User\Repository\UserRepositoryInterface;
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\Console\Style\SymfonyStyle;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\ConstraintViolationListInterface;
use Webmozart\Assert\Assert;
final class SetupCommand extends AbstractInstallCommand
{
protected static $defaultName = 'sylius:install:setup';
protected function configure(): void
{
$this
->setDescription('Sylius configuration setup.')
->setHelp(
<<<EOT
The <info>%command.name%</info> command allows user to configure basic Sylius data.
EOT
)
;
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$currency = $this->getContainer()->get('sylius.setup.currency')->setup($input, $output, $this->getHelper('question'));
$locale = $this->getContainer()->get('sylius.setup.locale')->setup($input, $output, $this->getHelper('question'));
$this->getContainer()->get('sylius.setup.channel')->setup($locale, $currency);
$this->setupAdministratorUser($input, $output, $locale->getCode());
return 0;
}
protected function setupAdministratorUser(InputInterface $input, OutputInterface $output, string $localeCode): void
{
$outputStyle = new SymfonyStyle($input, $output);
$outputStyle->writeln('Create your administrator account.');
$userManager = $this->getContainer()->get('sylius.manager.admin_user');
$userFactory = $this->getContainer()->get('sylius.factory.admin_user');
try {
$user = $this->configureNewUser($userFactory->createNew(), $input, $output);
} catch (\InvalidArgumentException) {
return;
}
$user->setEnabled(true);
$user->setLocaleCode($localeCode);
$userManager->persist($user);
$userManager->flush();
$outputStyle->writeln('<info>Administrator account successfully registered.</info>');
$outputStyle->newLine();
}
private function configureNewUser(
AdminUserInterface $user,
InputInterface $input,
OutputInterface $output,
): AdminUserInterface {
$userRepository = $this->getAdminUserRepository();
if ($input->getOption('no-interaction')) {
Assert::null($userRepository->findOneByEmail('sylius@example.com'));
$user->setEmail('sylius@example.com');
$user->setUsername('sylius');
$user->setPlainPassword('sylius');
return $user;
}
$email = $this->getAdministratorEmail($input, $output);
$user->setEmail($email);
$user->setUsername($this->getAdministratorUsername($input, $output, $email));
$user->setPlainPassword($this->getAdministratorPassword($input, $output));
return $user;
}
private function createEmailQuestion(): Question
{
return (new Question('E-mail: '))
->setValidator(
/**
* @param mixed $value
*/
function ($value): string {
/** @var ConstraintViolationListInterface $errors */
$errors = $this->getContainer()->get('validator')->validate((string) $value, [new Email(), new NotBlank()]);
foreach ($errors as $error) {
throw new \DomainException((string) $error->getMessage());
}
return $value;
},
)
->setMaxAttempts(3)
;
}
private function getAdministratorEmail(InputInterface $input, OutputInterface $output): string
{
/** @var QuestionHelper $questionHelper */
$questionHelper = $this->getHelper('question');
$userRepository = $this->getAdminUserRepository();
do {
$question = $this->createEmailQuestion();
$email = $questionHelper->ask($input, $output, $question);
$exists = null !== $userRepository->findOneByEmail($email);
if ($exists) {
$output->writeln('<error>E-Mail is already in use!</error>');
}
} while ($exists);
return $email;
}
private function getAdministratorUsername(InputInterface $input, OutputInterface $output, string $email): string
{
/** @var QuestionHelper $questionHelper */
$questionHelper = $this->getHelper('question');
$userRepository = $this->getAdminUserRepository();
do {
$question = new Question('Username (press enter to use email): ', $email);
$username = $questionHelper->ask($input, $output, $question);
$exists = null !== $userRepository->findOneBy(['username' => $username]);
if ($exists) {
$output->writeln('<error>Username is already in use!</error>');
}
} while ($exists);
return $username;
}
private function getAdministratorPassword(InputInterface $input, OutputInterface $output): string
{
/** @var QuestionHelper $questionHelper */
$questionHelper = $this->getHelper('question');
$validator = $this->getPasswordQuestionValidator();
do {
$passwordQuestion = $this->createPasswordQuestion('Choose password:', $validator);
$confirmPasswordQuestion = $this->createPasswordQuestion('Confirm password:', $validator);
$password = $questionHelper->ask($input, $output, $passwordQuestion);
$repeatedPassword = $questionHelper->ask($input, $output, $confirmPasswordQuestion);
if ($repeatedPassword !== $password) {
$output->writeln('<error>Passwords do not match!</error>');
}
} while ($repeatedPassword !== $password);
return $password;
}
private function getPasswordQuestionValidator(): \Closure
{
return
/** @param mixed $value */
function ($value): string {
/** @var ConstraintViolationListInterface $errors */
$errors = $this->getContainer()->get('validator')->validate($value, [new NotBlank()]);
foreach ($errors as $error) {
throw new \DomainException((string) $error->getMessage());
}
return $value;
}
;
}
private function createPasswordQuestion(string $message, \Closure $validator): Question
{
return (new Question($message))
->setValidator($validator)
->setMaxAttempts(3)
->setHidden(true)
->setHiddenFallback(false)
;
}
/** @return UserRepositoryInterface<UserInterface> */
private function getAdminUserRepository(): UserRepositoryInterface
{
return $this->getContainer()->get('sylius.repository.admin_user');
}
}
class_alias(SetupCommand::class, '\Sylius\Bundle\CoreBundle\Command\SetupCommand');

View file

@ -0,0 +1,66 @@
<?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\Console\Command;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Sylius\Bundle\CoreBundle\Command\Model\PluginInfo;
use Sylius\Bundle\CoreBundle\Installer\Renderer\TableRenderer;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
final class ShowAvailablePluginsCommand extends Command
{
protected static $defaultName = 'sylius:show-available-plugins';
/** @var ArrayCollection<array-key, PluginInfo> */
private Collection $plugins;
protected function configure(): void
{
$this->setDescription('Shows official Sylius Plugins');
$this->configurePlugins();
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$output->writeln('<comment>Available official plugins and selected community plugins:</comment>');
$pluginTable = new TableRenderer($output);
$pluginTable->setHeaders(['Plugin', 'Description', 'URL']);
foreach ($this->plugins as $plugin) {
$pluginTable->addRow([sprintf('<info>%s</info>', $plugin->name()), $plugin->description(), $plugin->url()]);
}
$pluginTable->render();
return 0;
}
private function configurePlugins(): void
{
$this->plugins = new ArrayCollection();
$this->plugins->add(new PluginInfo('<info>Admin Order Creation</info>', 'Creating (and copying) orders in the administration panel.', 'https://github.com/Sylius/AdminOrderCreationPlugin'));
$this->plugins->add(new PluginInfo('<info>Customer Order Cancellation</info>', 'Allows customers to quickly cancel their unpaid and unshipped orders.', 'https://github.com/Sylius/CustomerOrderCancellationPlugin'));
$this->plugins->add(new PluginInfo('<info>Customer Reorder</info>', 'Convenient reordering for the customers from the `My account` section.', 'https://github.com/Sylius/CustomerReorderPlugin'));
$this->plugins->add(new PluginInfo('<info>Invoicing</info>', 'Automatised, basic invoicing system for orders.', 'https://github.com/Sylius/InvoicingPlugin'));
$this->plugins->add(new PluginInfo('<info>Refund</info>', 'Full and partial refunds of items and/or shipping costs including Credit Memos.', 'https://github.com/Sylius/RefundPlugin'));
$this->plugins->add(new PluginInfo('<info>CMS</info>', 'This plugin allows you to add dynamic blocks with images, text or HTML to your storefront as well as pages and FAQs section.', 'https://github.com/BitBagCommerce/SyliusCmsPlugin'));
}
}
class_alias(ShowAvailablePluginsCommand::class, '\Sylius\Bundle\CoreBundle\Command\ShowAvailablePluginsCommand');

View file

@ -11,7 +11,7 @@
declare(strict_types=1);
namespace Sylius\Bundle\CoreBundle\PriceHistory\Cli\Command;
namespace Sylius\Bundle\CoreBundle\PriceHistory\Console\Command;
use Sylius\Bundle\CoreBundle\PriceHistory\Remover\ChannelPricingLogEntriesRemoverInterface;
use Symfony\Component\Console\Attribute\AsCommand;

View file

@ -13,34 +13,7 @@
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<imports>
<import resource="services/calculators.xml" />
<import resource="services/catalog_promotion.xml" />
<import resource="services/checkers.xml" />
<import resource="services/checkout.xml" />
<import resource="services/commands.xml" />
<import resource="services/context.xml" />
<import resource="services/dashboard.xml" />
<import resource="services/emails.xml" />
<import resource="services/factories.xml" />
<import resource="services/fixtures.xml" />
<import resource="services/fixtures_factories.xml" />
<import resource="services/fixtures_listeners.xml" />
<import resource="services/form.xml" />
<import resource="services/installer.xml" />
<import resource="services/installer_requirements.xml" />
<import resource="services/listeners.xml" />
<import resource="services/message_handlers.xml" />
<import resource="services/order_processing.xml" />
<import resource="services/payment.xml" />
<import resource="services/price_history.xml" />
<import resource="services/product_variant_map.xml" />
<import resource="services/promotion.xml" />
<import resource="services/providers.xml" />
<import resource="services/shipping.xml" />
<import resource="services/state_resolvers.xml" />
<import resource="services/taxation.xml" />
<import resource="services/templating.xml" />
<import resource="services/validators.xml" />
<import resource="services/*.xml" />
</imports>
<parameters>

View file

@ -15,49 +15,69 @@
<services>
<defaults public="true" />
<service id="Sylius\Bundle\CoreBundle\Command\CancelUnpaidOrdersCommand">
<service id="Sylius\Bundle\CoreBundle\Console\Command\CancelUnpaidOrdersCommand">
<tag name="console.command" />
</service>
<service id="Sylius\Bundle\CoreBundle\Command\CheckRequirementsCommand">
<service id="Sylius\Bundle\CoreBundle\Command\CancelUnpaidOrdersCommand" alias="Sylius\Bundle\CoreBundle\Console\Command\CancelUnpaidOrdersCommand" />
<service id="Sylius\Bundle\CoreBundle\Console\Command\CheckRequirementsCommand">
<tag name="console.command" />
</service>
<service id="Sylius\Bundle\CoreBundle\PriceHistory\Cli\Command\ClearPriceHistoryCommand">
<service id="Sylius\Bundle\CoreBundle\Command\CheckRequirementsCommand" alias="Sylius\Bundle\CoreBundle\Console\Command\CheckRequirementsCommand" />
<service id="Sylius\Bundle\CoreBundle\PriceHistory\Console\Command\ClearPriceHistoryCommand">
<argument type="service" id="Sylius\Bundle\CoreBundle\PriceHistory\Remover\ChannelPricingLogEntriesRemoverInterface" />
<tag name="console.command"/>
</service>
<service id="Sylius\Bundle\CoreBundle\Command\InstallAssetsCommand">
<service id="Sylius\Bundle\CoreBundle\Console\Command\InstallAssetsCommand">
<tag name="console.command" />
</service>
<service id="Sylius\Bundle\CoreBundle\Command\InstallCommand">
<service id="Sylius\Bundle\CoreBundle\Command\InstallAssetsCommand" alias="Sylius\Bundle\CoreBundle\Console\Command\InstallAssetsCommand" />
<service id="Sylius\Bundle\CoreBundle\Console\Command\InstallCommand">
<tag name="console.command" />
</service>
<service id="Sylius\Bundle\CoreBundle\Command\InstallDatabaseCommand">
<service id="Sylius\Bundle\CoreBundle\Command\InstallCommand" alias="Sylius\Bundle\CoreBundle\Console\Command\InstallCommand" />
<service id="Sylius\Bundle\CoreBundle\Console\Command\InstallDatabaseCommand">
<tag name="console.command" />
</service>
<service id="Sylius\Bundle\CoreBundle\Command\InstallSampleDataCommand">
<service id="Sylius\Bundle\CoreBundle\Command\InstallDatabaseCommand" alias="Sylius\Bundle\CoreBundle\Console\Command\InstallDatabaseCommand" />
<service id="Sylius\Bundle\CoreBundle\Console\Command\InstallSampleDataCommand">
<tag name="console.command" />
</service>
<service id="Sylius\Bundle\CoreBundle\Command\SetupCommand">
<service id="Sylius\Bundle\CoreBundle\Command\InstallSampleDataCommand" alias="Sylius\Bundle\CoreBundle\Console\Command\InstallSampleDataCommand" />
<service id="Sylius\Bundle\CoreBundle\Console\Command\SetupCommand">
<tag name="console.command" />
</service>
<service id="Sylius\Bundle\CoreBundle\Command\ShowAvailablePluginsCommand">
<service id="Sylius\Bundle\CoreBundle\Command\SetupCommand" alias="Sylius\Bundle\CoreBundle\Console\Command\SetupCommand" />
<service id="Sylius\Bundle\CoreBundle\Console\Command\ShowAvailablePluginsCommand">
<tag name="console.command" />
</service>
<service id="Sylius\Bundle\CoreBundle\Command\InformAboutGUSCommand">
<service id="Sylius\Bundle\CoreBundle\Command\ShowAvailablePluginsCommand" alias="Sylius\Bundle\CoreBundle\Console\Command\ShowAvailablePluginsCommand" />
<service id="Sylius\Bundle\CoreBundle\Console\Command\InformAboutGUSCommand">
<tag name="console.command" />
</service>
<service id="Sylius\Bundle\CoreBundle\Command\JwtConfigurationCommand">
<service id="Sylius\Bundle\CoreBundle\Command\InformAboutGUSCommand" alias="Sylius\Bundle\CoreBundle\Console\Command\InformAboutGUSCommand" />
<service id="Sylius\Bundle\CoreBundle\Console\Command\JwtConfigurationCommand">
<tag name="console.command" />
</service>
<service id="Sylius\Bundle\CoreBundle\Command\JwtConfigurationCommand" alias="Sylius\Bundle\CoreBundle\Console\Command\JwtConfigurationCommand" />
</services>
</container>

View file

@ -11,11 +11,11 @@
declare(strict_types=1);
namespace Tests\Sylius\Bundle\CoreBundle\PriceHistory\Cli\Command;
namespace Tests\Sylius\Bundle\CoreBundle\PriceHistory\Console\Command;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Sylius\Bundle\CoreBundle\PriceHistory\Cli\Command\ClearPriceHistoryCommand;
use Sylius\Bundle\CoreBundle\PriceHistory\Console\Command\ClearPriceHistoryCommand;
use Sylius\Bundle\CoreBundle\PriceHistory\Remover\ChannelPricingLogEntriesRemoverInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Tester\CommandTester;

View file

@ -11,7 +11,7 @@
declare(strict_types=1);
namespace spec\Sylius\Bundle\CoreBundle\Command\Model;
namespace spec\Sylius\Bundle\CoreBundle\Console\Command\Model;
use PhpSpec\ObjectBehavior;