ClearAndLogFailedMailsCommand   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 92
Duplicated Lines 0 %

Test Coverage

Coverage 95.65%

Importance

Changes 2
Bugs 0 Features 1
Metric Value
eloc 49
c 2
b 0
f 1
dl 0
loc 92
ccs 44
cts 46
cp 0.9565
rs 10
wmc 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
A configure() 0 10 1
B execute() 0 73 9
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: since Symfony 4.2, use {@see Command} instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

20
class ClearAndLogFailedMailsCommand extends /** @scrutinizer ignore-deprecated */ ContainerAwareCommand
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