엔티티에 대한 데모 데이터를 생성하는 Shopware 사용자 정의 CLI 명령

엔티티에서 데모 데이터를 생성하는 CLI 명령을 생성하는 Shopware



이 블로그 게시물에서는 Shopware 6 플러그인에서 사용자 정의 명령을 생성하고 이를 사용하여 데모 데이터를 생성하는 방법을 배웁니다.

Shopware 6은 Symfony 프레임워크를 기반으로 하기 때문에 콘솔도 사용할 수 있습니다. 따라서 Shopware 6 플러그인을 개발하는 동안 필요한 대부분의 작업을 수행할 수 있습니다.

폴더 구조




<pluginRoot>
└── src
    ├── Command
    │   └── DemodataCommand.php
    │
    ├── Generator
    │   └── ArticleGenerator.php
    │
    └── Resources
        └── config
            └── services.xml


명령 등록



새 명령을 등록하려면 플러그인의 services.xml에 추가하고 console.command 태그를 지정하십시오.

<service id="Sas\BlogModule\Command\DemodataCommand">
    <argument type="service" id="Shopware\Core\Framework\Demodata\DemodataService"/>
    <tag name="console.command"/>
</service>


명령 구성



명령의 클래스는 Symfony\Component\Console\Command\Command에서 확장되어야 합니다.
수업:

class DemodataCommand extends Command
{
    protected static $defaultName = '';

    protected function configure(): void
    {
        //
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        //
    }
}


명령 이름부터 시작하겠습니다("bin/console"다음 부분).

// the command description shown when running "php bin/console list"
protected static $defaultName = 'article:demodata';


선택적으로 설명, 도움말 메시지 및 input options and arguments을 정의할 수 있습니다.configure() 메서드를 재정의하여:

protected function configure(): void
{
    $this->addArgument('count', InputArgument::REQUIRED, 'The number of the articles.');
}

execute() 메서드에 데모 데이터를 생성하는 코드를 입력합니다.
이 메서드는 명령의 "종료 상태 코드"와 함께 정수를 반환해야 합니다. 다음 상수를 사용하여 코드를 더 읽기 쉽게 만들 수도 있습니다.
  • Command::SUCCESS 명령 실행에 문제가 없는 경우.
  • Command::FAILURE 실행 중에 일부 오류가 발생한 경우.
  • Command::INVALID는 잘못된 명령 사용을 나타냅니다. 옵션이 잘못되었거나 인수가 누락되었습니다.

  • protected function execute(InputInterface $input, OutputInterface $output): int
    {
        // ... put here the code to create articles
    
        return Command::SUCCESS;
    }
    

    명령 스타일링



    제목

    주어진 문자열을 명령 제목으로 표시합니다. 이 방법은 주어진 명령에서 한 번만 사용하도록 되어 있지만 반복적으로 사용하는 것을 방해하는 것은 없습니다.

    $io->title('Article Data Generator');
    


    콘솔 출력은 다음과 같아야 합니다.

    Article Data Generator
    ======================
    


    테이블

    주어진 헤더 및 행 배열을 압축 테이블로 표시합니다.

    $io->table(
        ['Entity', 'Items', 'Time'],
        $demoContext->getTimings()
    );
    


    콘솔 출력은 다음과 같아야 합니다.

    ---------------------- ------- --------------------
      Entity                 Items   Time
    ---------------------- ------- --------------------
      media                  1000    3.7
      article                1000    6.1
    ---------------------- ------- --------------------
    


    진행 표시 줄

    더 오래 실행되는 명령을 실행할 때 명령이 실행될 때 업데이트되는 진행 정보를 표시하는 것이 도움이 될 수 있습니다.

    Generating 1000 items for article
    ---------------------------------
    
    1000/1000 [============================] 100%
    
    ! [NOTE] Took 6.1 seconds
    


    시작 진행 표시줄: 메서드에 전달된 인수와 동일한 여러 단계의 진행 표시줄을 표시합니다(진행 표시줄의 진행 표시줄 길이는 알 수 없음).

    // displays a progress bar of unknown length
    $context->getConsole()->progressStart();
    
    // displays a 100-step length progress bar
    $context->getConsole()->progressStart(100);
    


    진행률 표시줄 진행: 진행률 표시줄이 주어진 단계만큼 진행됩니다.

    // advances the progress bar 1 step
    $context->getConsole()->progressAdvance();
    
    // advances the progress bar 10 steps
    $context->getConsole()->progressAdvance(10);
    


    진행률 표시줄 완료: 진행률 표시줄을 완료합니다(길이를 알면 나머지 단계를 모두 채움).

    $context->getConsole()->progressFinish();
    


    데이터 생성기 만들기



    새 생성기를 등록하려면 플러그인의 services.xml에 추가하고 shopware.demodata_generator 태그를 지정하십시오.

    <service id="Sas\BlogModule\Generator\ArticleGenerator">
        <argument type="service" id="Shopware\Core\Framework\DataAbstractionLayer\Write\EntityWriter" />
        <argument type="service" id="Doctrine\DBAL\Connection" />
        <argument type="service" id="Sas\BlogModule\Content\Article\ArticleDefinition"/>
        <tag name="shopware.demodata_generator"/>
    </service>
    


    이제 생성기가 정의 클래스를 알아야 합니다. 이는 메서드를 재정의하여 수행됩니다getDefinition().

    public function getDefinition(): string
    {
        return ArticleDefinition::class;
    }
    

    generate() 메서드에 데모 데이터를 생성하는 코드를 입력합니다.

    public function generate(int $numberOfItems, DemodataContext $context, array $options = []): void
    {
        $writeContext = WriteContext::createFromContext($context->getContext());
    
        $payload = [
            // an array of articles
        ];
    
        $this->writer->upsert($this->articleDefinition, $payload, $writeContext);
    }
    


    명령 실행




    bin/console article:demodata 1000
    



    전체 클래스 및 XML 파일



    DemodataCommand.php

    use Sas\BlogModule\Content\Article\ArticleDefinition;
    use Shopware\Core\Framework\Adapter\Console\ShopwareStyle;
    use Shopware\Core\Framework\Context;
    use Shopware\Core\Framework\Demodata\DemodataRequest;
    use Shopware\Core\Framework\Demodata\DemodataService;
    use Symfony\Component\Console\Command\Command;
    use Symfony\Component\Console\Input\InputArgument;
    use Symfony\Component\Console\Input\InputInterface;
    use Symfony\Component\Console\Output\OutputInterface;
    
    class DemodataCommand extends Command
    {
        protected static $defaultName = 'article:demodata';
    
        private DemodataService $demodataService;
    
        public function __construct(DemodataService $demodataService)
        {
            parent::__construct();
    
            $this->demodataService = $demodataService;
        }
    
        protected function configure(): void
        {
            $this->addArgument('count', InputArgument::REQUIRED, 'The number of the articles.');
        }
    
        protected function execute(InputInterface $input, OutputInterface $output): int
        {
            $io = new ShopwareStyle($input, $output);
            $io->title('Article Data Generator');
    
            $context = Context::createDefaultContext();
    
            $request = new DemodataRequest();
    
            $request->add(ArticleDefinition::class, (int)$input->getArgument('count'));
    
            $demoContext = $this->demodataService->generate($request, $context, $io);
    
            $io->table(
                ['Entity', 'Items', 'Time'],
                $demoContext->getTimings()
            );
    
            return self::SUCCESS;
        }
    }
    


    ArticleGenerator.php

    use Doctrine\DBAL\Connection;
    use Sas\BlogModule\Content\Article\ArticleDefinition;
    use Shopware\Core\Framework\DataAbstractionLayer\Write\EntityWriterInterface;
    use Shopware\Core\Framework\DataAbstractionLayer\Write\WriteContext;
    use Shopware\Core\Framework\Demodata\DemodataContext;
    use Shopware\Core\Framework\Demodata\DemodataGeneratorInterface;
    use Shopware\Core\Framework\Uuid\Uuid;
    
    class ArticleGenerator implements DemodataGeneratorInterface
    {
        private EntityWriterInterface $writer;
    
        private Connection $connection;
    
        private ArticleDefinition $articleDefinition;
    
        public function __construct(
            EntityWriterInterface $writer,
            Connection            $connection,
            ArticleDefinition     $articleDefinition
        ) {
            $this->writer = $writer;
            $this->connection = $connection;
            $this->articleDefinition = $articleDefinition;
        }
    
        public function getDefinition(): string
        {
            return ArticleDefinition::class;
        }
    
        public function generate(int $numberOfItems, DemodataContext $context, array $options = []): void
        {
            $authorId = $this->connection->fetchOne('SELECT LOWER(HEX(id)) FROM author');
    
            $writeContext = WriteContext::createFromContext($context->getContext());
    
            $context->getConsole()->progressStart($numberOfItems);
    
            $payload = [];
            for ($i = 0; $i < $numberOfItems; ++$i) {
                            $translations = [
                    'en-GB' => [
                        'title' => $title,
                        'teaser' => $context->getFaker()->text(200),
                        'content' => $context->getFaker()->text(50),
                    ],
                ];
    
                $article = [
                    'id' => Uuid::randomHex(),
                    'active' => true,
                    'authorId' => $authorId,
                    'translations' => $translations
                ];
    
                $payload[] = $article;
    
                if (\count($payload) >= 100) {
                    $this->writer->upsert($this->articleDefinition, $payload, $writeContext);
                    $context->getConsole()->progressAdvance(\count($payload));
                    $payload = [];
                }
            }
    
            if (!empty($payload)) {
                $this->writer->upsert($this->articleDefinition, $payload, $writeContext);
                $context->getConsole()->progressAdvance(\count($payload));
            }
    
            $context->getConsole()->progressFinish();
        }
    }
    


    services.xml

    <?xml version="1.0" ?>
    
    <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">
    
        <services>
    
            <service id="Sas\BlogModule\Command\DemodataCommand">
                <argument type="service" id="Shopware\Core\Framework\Demodata\DemodataService"/>
                <tag name="console.command"/>
            </service>
    
            <service id="Sas\BlogModule\Generator\ArticleGenerator">
                <argument type="service" id="Shopware\Core\Framework\DataAbstractionLayer\Write\EntityWriter" />
                <argument type="service" id="Doctrine\DBAL\Connection" />
                <argument type="service" id="Sas\BlogModule\Content\Article\ArticleDefinition"/>
                <tag name="shopware.demodata_generator"/>
            </service>
    
        </services>
    </container>
    



    이 기사에 대한 피드백을 받게 되어 정말 기쁩니다. 소중한 시간을 내어 읽어주셔서 감사합니다.

    출처: https://viennt.me/shopware-custom-cli-command-to-generate-demo-data-on-your-entity

    좋은 웹페이지 즐겨찾기