Proyectos de Subversion LeadersLinked - Services

Rev

Rev 345 | Rev 607 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |

<?php
declare(strict_types = 1);
namespace LeadersLinked\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
// use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Laminas\Db\Adapter\AdapterInterface;
use Laminas\Log\LoggerInterface;
use LeadersLinked\Mapper\EmailMapper;
use PHPMailer\PHPMailer\PHPMailer;
use LeadersLinked\Model\Email;
use Laminas\Mvc\I18n\Translator;
use LeadersLinked\Cache\CacheInterface;

class ProcessQueueEmailCommand extends Command
{

    /**
     *
     * @var \Laminas\Db\Adapter\AdapterInterface
     */
    private $adapter;

    /**
     *
     * @var \LeadersLinked\Cache\CacheInterface
     */
    private $cache;

    /**
     *
     * @var \Laminas\Log\LoggerInterface
     */
    private $logger;

    /**
     *
     * @var array
     */
    private $config;

    /**
     *
     * @var \Laminas\Mvc\I18n\Translator
     */
    private $translator;

    /**
     *
     * @param \Laminas\Db\Adapter\AdapterInterface $adapter
     * @param \LeadersLinked\Cache\CacheInterface $cache
     * @param
     *            \Laminas\Log\LoggerInterface
     * @param array $config
     * @param \Laminas\Mvc\I18n\Translator $translator
     */
    public function __construct($adapter, $cache, $logger, $config, $translator)
    {
        $this->adapter = $adapter;
        $this->cache = $cache;
        $this->logger = $logger;
        $this->config = $config;
        $this->translator = $translator;

        parent::__construct();
    }

    protected function execute($input, $output)
    {
        $output->writeln('Inicio del proceso de la cola de Email');

        $emailConfig = $this->getEmailConfig();
        $this->logEmailConfig($emailConfig);

        $emailMapper = EmailMapper::getInstance($this->adapter);
        $emails = $emailMapper->fetchBatch($emailConfig['batch_size']);

        $stats = $this->processEmails($emails, $emailConfig, $emailMapper);

        $output->writeln('Email con Errores descartados: ' . $stats['error']);
        $output->writeln('Email enviados correctamente:' . $stats['completed']);
        $output->writeln('Fin del proceso de la cola de Email');

        return 0;
    }

    private function getEmailConfig(): array
    {
        $sandbox = $this->config['leaderslinked.runmode.sandbox'];
        $prefix = $sandbox ? 'sandbox' : 'production';

        return [
            'batch_size' => $this->config["leaderslinked.email.{$prefix}_batch_size"],
            'from_address' => $this->config["leaderslinked.email.{$prefix}_from_address"],
            'from_name' => $this->config["leaderslinked.email.{$prefix}_from_name"],
            'host' => $this->config["leaderslinked.email.{$prefix}_host"],
            'port' => $this->config["leaderslinked.email.{$prefix}_port"],
            'username' => $this->config["leaderslinked.email.{$prefix}_username"],
            'password' => $this->config["leaderslinked.email.{$prefix}_password"]
        ];
    }

    private function logEmailConfig($config)
    {
        echo 'Username : ' . $config['username'] . PHP_EOL;
        echo 'Password : ' . $config['password'] . PHP_EOL;
        echo 'Host : ' . $config['host'] . PHP_EOL;
        echo 'Port : ' . $config['port'] . PHP_EOL;
    }

    private function processEmails($emails, $config, $emailMapper)
    {
        $stats = ['completed' => 0, 'error' => 0];

        if (!$emails) {
            return $stats;
        }

        foreach ($emails as $email) {
            $content = json_decode($email->content, true);
            $result = $this->sendEmail($content, $config);

            if ($result) {
                $stats['completed']++;
                $email->status = Email::STATUS_COMPLETED;
            } else {
                if ($email->tried == 2) {
                    $stats['error']++;
                    $email->status = Email::STATUS_ERROR;
                }
                $email->tried++;
            }
            $emailMapper->update($email);
        }

        return $stats;
    }

    private function sendEmail($content, $config)
    {
        $to_address = $content['to_address'];
        $to_name = $content['to_name'];
        $cc = $content['cc'];
        $bcc = $content['bcc'];
        $subject = $this->ensureUtf8($content['subject']);
        $message = $this->ensureUtf8($content['message']);

        $phpMailer = new PHPMailer();
        $phpMailer->isSMTP();
        $phpMailer->addAddress($to_address, $to_name);

        if ($cc) {
            foreach ($cc as $address => $name) {
                $phpMailer->addCC($address, $name);
            }
        }

        if ($bcc) {
            foreach ($bcc as $address => $name) {
                $phpMailer->addBCC($address, $name);
            }
        }

        $phpMailer->setFrom($config['from_address'], $config['from_name']);
        $phpMailer->SMTPDebug = 2;
        $phpMailer->Debugoutput = function($str, $level) {
            $this->logger->debug("PHPMailer: $str");
        };
        $phpMailer->Host = $config['host'];
        $phpMailer->Port = $config['port'];
        $phpMailer->IsHTML(true);
        $phpMailer->SMTPAuth = true;
        $phpMailer->SMTPSecure = 'tls';
        $phpMailer->Username = $config['username'];
        $phpMailer->Password = $config['password'];
        $phpMailer->Subject = $subject;
        $phpMailer->Body = $message;
        $phpMailer->AltBody = $message;
        $phpMailer->CharSet = 'UTF-8';

        try {
            return $phpMailer->send();
        } catch (\Exception $e) {
            $this->logger->error("Email sending failed: " . $e->getMessage());
            return false;
        }
    }

    private function ensureUtf8($text)
    {
        $encoding = mb_detect_encoding($text);
        return $encoding != 'UTF-8' ? mb_convert_encoding($text, 'UTF-8', $encoding) : $text;
    }
}