<?php declare(strict_types=1); 
 
namespace Shopware\Core\Content\LandingPage; 
 
use Shopware\Core\Content\LandingPage\Aggregate\LandingPageSalesChannel\LandingPageSalesChannelDefinition; 
use Shopware\Core\Framework\DataAbstractionLayer\Write\Command\InsertCommand; 
use Shopware\Core\Framework\DataAbstractionLayer\Write\Command\WriteCommand; 
use Shopware\Core\Framework\DataAbstractionLayer\Write\Validation\PostWriteValidationEvent; 
use Shopware\Core\Framework\Validation\WriteConstraintViolationException; 
use Symfony\Component\EventDispatcher\EventSubscriberInterface; 
use Symfony\Component\Validator\Constraints\NotBlank; 
use Symfony\Component\Validator\ConstraintViolationList; 
use Symfony\Component\Validator\Validator\ValidatorInterface; 
 
class LandingPageValidator implements EventSubscriberInterface 
{ 
    private ValidatorInterface $validator; 
 
    /** 
     * @internal 
     */ 
    public function __construct(ValidatorInterface $validator) 
    { 
        $this->validator = $validator; 
    } 
 
    /** 
     * @return array<string, string|array{0: string, 1: int}|list<array{0: string, 1?: int}>> 
     */ 
    public static function getSubscribedEvents() 
    { 
        return [ 
            PostWriteValidationEvent::class => 'preValidate', 
        ]; 
    } 
 
    public function preValidate(PostWriteValidationEvent $event): void 
    { 
        $writeException = $event->getExceptions(); 
        $commands = $event->getCommands(); 
        $violationList = new ConstraintViolationList(); 
 
        foreach ($commands as $command) { 
            if (!($command instanceof InsertCommand) || $command->getDefinition()->getClass() !== LandingPageDefinition::class) { 
                continue; 
            } 
 
            if (!$this->hasAnotherValidCommand($commands, $command)) { 
                $violationList->addAll( 
                    $this->validator->startContext() 
                        ->atPath($command->getPath() . '/salesChannels') 
                        ->validate(null, [new NotBlank()]) 
                        ->getViolations() 
                ); 
                $writeException->add(new WriteConstraintViolationException($violationList)); 
            } 
        } 
    } 
 
    /** 
     * @param WriteCommand[] $commands 
     */ 
    private function hasAnotherValidCommand(array $commands, WriteCommand $command): bool 
    { 
        $isValid = false; 
        foreach ($commands as $searchCommand) { 
            if ($searchCommand->getDefinition()->getClass() === LandingPageSalesChannelDefinition::class && $searchCommand instanceof InsertCommand) { 
                $searchPrimaryKey = $searchCommand->getPrimaryKey(); 
                $searchLandingPageId = $searchPrimaryKey['landing_page_id'] ?? null; 
 
                $currentPrimaryKey = $command->getPrimaryKey(); 
                $currentLandingPageId = $currentPrimaryKey['id'] ?? null; 
 
                if ($searchLandingPageId === $currentLandingPageId) { 
                    $isValid = true; 
                } 
            } 
        } 
 
        return $isValid; 
    } 
}