Files
esun3d/app/code/Esun/Catalog/Console/Command/RebuildSpecificationArchiveCommand.php
2026-09-15 10:35:56 +08:00

97 lines
3.6 KiB
PHP

<?php
declare(strict_types=1);
namespace Esun\Catalog\Console\Command;
use Esun\Catalog\Model\ResourceModel\SpecificationBrand\CollectionFactory as BrandCollectionFactory;
use Esun\Catalog\Model\SpecificationArchiveRebuilder;
use Magento\Framework\Console\Cli;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class RebuildSpecificationArchiveCommand extends Command
{
private const COMMAND_NAME = 'esun:catalog:specification-archive:rebuild';
private const OPTION_BRAND_ID = 'brand-id';
private const OPTION_FORCE = 'force';
public function __construct(
private readonly BrandCollectionFactory $brandCollectionFactory,
private readonly SpecificationArchiveRebuilder $archiveRebuilder
) {
parent::__construct(self::COMMAND_NAME);
}
protected function configure(): void
{
$this->setDescription('Rebuild downloadable specification ZIP archives from parsed specification files.');
$this->addOption(
self::OPTION_BRAND_ID,
null,
InputOption::VALUE_REQUIRED,
'Only rebuild the specified specification brand ID.'
);
$this->addOption(
self::OPTION_FORCE,
'f',
InputOption::VALUE_NONE,
'Overwrite an existing valid brand archive.'
);
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$brandIdOption = $input->getOption(self::OPTION_BRAND_ID);
$brandId = $brandIdOption !== null ? filter_var($brandIdOption, FILTER_VALIDATE_INT) : null;
if ($brandIdOption !== null && (!$brandId || $brandId < 1)) {
$output->writeln('<error>The --brand-id option must be a positive integer.</error>');
return Cli::RETURN_FAILURE;
}
$collection = $this->brandCollectionFactory->create()
->addFieldToFilter('status', 1)
->setOrder('sort_order', 'ASC')
->setOrder('brand_name', 'ASC');
if ($brandId !== null) {
$collection->addFieldToFilter('brand_id', $brandId);
}
if (!$collection->getSize()) {
$output->writeln('<error>No enabled specification brands matched the command options.</error>');
return Cli::RETURN_FAILURE;
}
$force = (bool)$input->getOption(self::OPTION_FORCE);
$failed = 0;
foreach ($collection as $brand) {
$brandName = (string)$brand->getData('brand_name');
try {
$result = $this->archiveRebuilder->rebuild($brand, $force);
if ($result['status'] === 'skipped') {
$output->writeln(sprintf('<comment>Skipped %s: archive already exists.</comment>', $brandName));
continue;
}
$message = sprintf(
'%s %s: %d file(s), %d missing file(s), %s',
ucfirst($result['status']),
$brandName,
$result['file_count'],
$result['missing_count'],
$result['path']
);
$output->writeln('<info>' . $message . '</info>');
} catch (\Throwable $exception) {
$failed++;
$output->writeln(sprintf('<error>Failed %s: %s</error>', $brandName, $exception->getMessage()));
}
}
return $failed === 0 ? Cli::RETURN_SUCCESS : Cli::RETURN_FAILURE;
}
}