Completed
Push — master ( 0ba7dd...4699e0 )
by Dominik
11s
created

Command/ClearAndLogFailedMailsCommand.php (1 issue)

Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Azine\EmailBundle\Command;
4
5
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
6
use Symfony\Component\Console\Input\InputArgument;
7
use Symfony\Component\Console\Input\InputInterface;
8
use Symfony\Component\Console\Output\OutputInterface;
9
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
10
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
11
use Symfony\Component\Finder\Finder;
12
13
/**
14
 * Try to send emails that failed and are still pending in the spool-folder.
15
 *
16
 * After trying to send them one more time, delete the files and log any email-address that still failed.
17
 *
18
 * @author dominik
19
 */
20
class ClearAndLogFailedMailsCommand extends ContainerAwareCommand
0 ignored issues
show
Deprecated Code introduced by
The class Symfony\Bundle\Framework...d\ContainerAwareCommand has been deprecated with message: since Symfony 4.2, use {@see Command} instead.

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
21
{
22 6
    protected function configure()
23
    {
24 6
        $this->setName('emails:clear-and-log-failures')
25 6
            ->setDescription('Clears and logs failed emails from the spool')
26 6
            ->setDefinition(array(new InputArgument('date',
27 6
                                                        InputArgument::OPTIONAL,
28 6
                                                        'Try to send and then delete all failed emails that are older than "date". The date must be something that strtotime() is able to parse:  => e.g. "since yesterday", "until 2 days ago", "> now - 2 hours", ">= 2005-10-15" '
29
                                                    ),
30
                            ))
31 6
            ->setHelp(<<<EOF
32 6
The <info>emails:clear-and-log-failures</info> command tries to send failed emails and deletes them
33
from the spool directory after this last try. Any email-address that still failed, is logged.
34
EOF
35
            )
36
            ;
37 6
    }
38
39 5
    protected function execute(InputInterface $input, OutputInterface $output)
40
    {
41 5
        $failedRecipients = array();
42
43
        // check if the current environment is configured to spool emails
44
        try {
45
            /** @var $transport \Swift_Transport */
46 5
            $transport = $this->getContainer()->get('swiftmailer.transport.real');
47 1
        } catch (ServiceNotFoundException $ex) {
48 1
            $output->writeln("\n\n\nCould not load transport. Is file-spooling configured in your config.yml for this environment?\n\n\n");
49
50 1
            return;
51
        }
52
53
        try {
54 4
            $mailers = $this->getContainer()->getParameter('swiftmailer.mailers');
55 3
            $mailerName = key($mailers);
56 3
            $spoolPath = $this->getContainer()->getParameter("swiftmailer.spool.$mailerName.file.path");
57 1
        } catch (InvalidArgumentException $ex) {
58 1
            $output->writeln("\n\n\nCould not find file spool path. Is file-spooling configured in your config.yml for this environment?\n\n\n");
59
60 1
            return;
61
        }
62
63
        // start the mail transport
64 3
        if (!$transport->isStarted()) {
65 3
            $transport->start();
66
        }
67
68
        // find pending mails and try to send them again now
69 3
        $finder = Finder::create()->in($spoolPath)->name('*.sending');
70
71 3
        $date = $input->getArgument('date');
72
73 3
        if ($date) {
74 1
            $finder->date($date);
75
        }
76
77 3
        if (0 == $finder->count()) {
78 1
            $output->writeln("No failed-message-files found in '$spoolPath' for retry.");
79
80 1
            return;
81
        }
82
83 2
        foreach ($finder as $failedFile) {
84
            // rename the file, so no other process tries to find it
85 2
            $tmpFilename = $failedFile.'.finalretry';
86 2
            rename($failedFile, $tmpFilename);
87
88
            /** @var $message \Swift_Message */
89 2
            $message = unserialize(file_get_contents($tmpFilename));
90 2
            $output->writeln(sprintf(
91 2
                    "Retrying to send '<info>%s</info>' to '<info>%s</info>'",
92 2
                    $message->getSubject(),
93 2
                    implode(', ', array_keys($message->getTo()))
94
            ));
95
96
            try {
97 2
                $transport->send($message, $failedRecipients);
98 2
                $output->writeln('Sent!');
99
            } catch (\Swift_TransportException $e) {
100
                $output->writeln('<error>Send failed - deleting spooled message</error>');
101
            }
102
103
            // delete the file, either because it sent, or because it failed
104 2
            unlink($tmpFilename);
105
        }
106
107
        // write the failure to the log
108 2
        if (sizeof($failedRecipients) > 0) {
109
            /** @var $logger LoggerInterface */
110 2
            $logger = $this->getContainer()->get('logger');
111 2
            $logger->warning('<error>Failed to send an email to : '.implode(', ', $failedRecipients).'</error>');
112
        }
113 2
    }
114
}
115