96 lines
4.0 KiB
PHP
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;
|
|
}
|
|
}
|