Files
2026-09-15 10:35:56 +08:00

96 lines
4.0 KiB
PHP

<?php
declare(strict_types=1);
namespace Esun\BlogImport\Console\Command;
use Esun\BlogImport\Model\BlogImporter;
use Magento\Framework\App\Filesystem\DirectoryList;
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 ImportBlogCommand extends Command
{
private const COMMAND_NAME = 'esun:blog:import';
public function __construct(
private readonly BlogImporter $blogImporter,
private readonly DirectoryList $directoryList
) {
parent::__construct(self::COMMAND_NAME);
}
protected function configure(): void
{
$this->setDescription('Import eSUN JSON and HTML files into Mageplaza Blog posts.');
$this->addOption('source', null, InputOption::VALUE_REQUIRED, 'Extracted import directory; defaults to var/import.');
$this->addOption('store-id', null, InputOption::VALUE_REQUIRED, 'Magento store ID assigned to posts.', '0');
$this->addOption(
'media-subdir',
null,
InputOption::VALUE_REQUIRED,
'Subdirectory beneath pub/media.',
'mageplaza/blog/post/uploads'
);
$this->addOption('dry-run', null, InputOption::VALUE_NONE, 'Validate and report without writing posts.');
$this->addOption(
'allow-missing-media',
null,
InputOption::VALUE_NONE,
'Continue when HTML references media files that are not present locally.'
);
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$sourceOption = $input->getOption('source');
$source = is_string($sourceOption) && trim($sourceOption) !== ''
? trim($sourceOption)
: $this->directoryList->getPath(DirectoryList::VAR_DIR) . DIRECTORY_SEPARATOR . 'import';
$storeId = filter_var($input->getOption('store-id'), FILTER_VALIDATE_INT);
if ($storeId === false || $storeId < 0) {
$output->writeln('<error>The --store-id option must be a non-negative integer.</error>');
return Cli::RETURN_FAILURE;
}
$mediaSubdirectory = trim((string)$input->getOption('media-subdir'));
$dryRun = (bool)$input->getOption('dry-run');
$output->writeln(sprintf('<info>%s eSUN Blog import from %s</info>', $dryRun ? 'Validating' : 'Importing', $source));
try {
$stats = $this->blogImporter->import(
$source,
$storeId,
$mediaSubdirectory,
$dryRun,
(bool)$input->getOption('allow-missing-media'),
$output->isVerbose() ? static function (string $message) use ($output): void {
$output->writeln($message);
} : null
);
} catch (\Throwable $exception) {
$output->writeln('<error>' . $exception->getMessage() . '</error>');
return Cli::RETURN_FAILURE;
}
$output->writeln(sprintf('JSON records: %d', $stats['json_records']));
$output->writeln(sprintf('Unique posts: %d', $stats['unique_posts']));
$output->writeln(sprintf('Duplicate records: %d', $stats['duplicate_records']));
$output->writeln(sprintf('Missing media: %d', $stats['missing_media']));
$output->writeln(sprintf(
'%-20s%d',
$dryRun ? 'Media to normalize:' : 'Media normalized:',
$stats['normalized_media']
));
if (!$dryRun) {
$output->writeln(sprintf('Created: %d', $stats['created']));
$output->writeln(sprintf('Updated: %d', $stats['updated']));
$output->writeln(sprintf('Unchanged: %d', $stats['unchanged']));
}
$output->writeln($dryRun ? '<info>Validation completed; no data was written.</info>' : '<info>Blog import completed.</info>');
return Cli::RETURN_SUCCESS;
}
}