mail-rss/src/Command/MailImportCommand.php

136 lines
4.1 KiB
PHP

<?php
namespace App\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use App\Repository\MailingRepository;
use Doctrine\ORM\EntityManagerInterface;
use PhpMimeMailParser\Parser;
use App\Entity\Mail;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Filesystem\Filesystem;
use App\Entity\MailAttachment;
class MailImportCommand extends Command
{
protected static $defaultName = 'mail:import';
protected EntityManagerInterface $em;
protected MailingRepository $mailingRepo;
protected KernelInterface $kernel;
public function __construct(EntityManagerInterface $em, MailingRepository $mailingRepo, KernelInterface $kernel)
{
parent::__construct();
$this->em = $em;
$this->mailingRepo = $mailingRepo;
$this->kernel = $kernel;
}
protected function configure()
{
$this
->setDescription('Import a mail into a mailing')
->addOption('file', 'f', InputOption::VALUE_REQUIRED, 'File')
->addArgument('mailing_id', InputArgument::OPTIONAL, 'ID of the mailing')
;
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$mailingId = $input->getArgument('mailing_id');
$file = $input->getOption('file');
$mailing = $this->mailingRepo->find(['id' => $mailingId]);
if (null === $mailing) {
$io->error(sprintf('Mailing "%s" is not found!', $mailingId));
return Command::FAILURE;
}
if (empty($file)) {
$file = 'php://stdin';
$content = trim(file_get_contents($file));
if (empty($content)) {
$io->error('Standard input is empty');
return Command::FAILURE;
}
} elseif (file_exists($file) && is_readable($file) && is_file($file)) {
$content = trim(file_get_contents($file));
if (empty($content)) {
$io->error('File is empty');
return Command::FAILURE;
}
} else {
$io->error('No such file or is not readable');
return Command::FAILURE;
}
$parser = new Parser();
$parser->setText($content);
$subject = $parser->getHeader('subject');
$date = $parser->getHeader('date');
$text = $parser->getMessageBody('text');
$htmlEmbeddedContent = $parser->getMessageBody('htmlEmbedded');
$attachments = $parser->getAttachments();
if ($subject === false && $date === false) {
$io->error('The subject and the date are empty. Is it a valid mail?');
return Command::FAILURE;
}
$entity = new Mail();
$entity
->setMailing($mailing)
->setSubject($subject)
->setDate(new \DateTime($date))
->setTextContent($text)
->setHtmlContent($htmlEmbeddedContent);
$this->em->persist($entity);
$this->em->flush();
if (!empty($attachments)) {
$attachmentsDirectory = $this->kernel->getProjectDir().'/private/attachments/'.$mailing->getId().'/'.$entity->getId();
$filesystem = new Filesystem();
$filesystem->mkdir($attachmentsDirectory, 0700);
foreach ($attachments as $attachment) {
$filename = basename($attachment->save($attachmentsDirectory, Parser::ATTACHMENT_DUPLICATE_SUFFIX));
$mailAttachment = new MailAttachment();
$mailAttachment
->setMail($entity)
->setContentType($attachment->getContentType())
->setFilename($filename);
$this->em->persist($mailAttachment);
$this->em->flush();
}
}
$io->success('Mail imported!');
return Command::SUCCESS;
}
}