Completed
Push — feature/send_corpus ( 0e2c78...458a19 )
by Manuel
08:57
created

SpammerCommand::sendFakeEmail()   A

Complexity

Conditions 5
Paths 12

Size

Total Lines 50
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 33
nc 12
nop 2
dl 0
loc 50
rs 9.0808
c 0
b 0
f 0
1
<?php
2
3
namespace EndelWar\Spammer\Command;
4
5
use EndelWar\Spammer\Validator;
6
use Faker;
7
use Swift_Mailer;
8
use Swift_Message;
9
use Swift_SmtpTransport;
10
use Symfony\Component\Console\Command\Command;
11
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
12
use Symfony\Component\Console\Input\InputInterface;
13
use Symfony\Component\Console\Input\InputOption;
14
use Symfony\Component\Console\Output\OutputInterface;
15
16
class SpammerCommand extends Command
17
{
18
    /**
19
     * @throws \Symfony\Component\Console\Exception\InvalidArgumentException
20
     */
21
    protected function configure()
22
    {
23
        $count = 10;
24
        $smtpServerIp = '127.0.0.1';
25
        $smtpServerPort = '25';
26
        $locale = 'en_US';
27
28
        $this
29
            ->setName('spammer')
30
            ->setDescription('Send random content email or email from a corpus')
31
            ->setDefinition(
32
                [
33
                    new InputOption('server', 's', InputOption::VALUE_OPTIONAL, 'SMTP Server ip to send email to', $smtpServerIp),
34
                    new InputOption('port', 'p', InputOption::VALUE_OPTIONAL, 'SMTP Server port to send email to', $smtpServerPort),
35
                    new InputOption('count', 'c', InputOption::VALUE_OPTIONAL, 'Number of email to send', $count),
36
                    new InputOption('locale', 'l', InputOption::VALUE_OPTIONAL, 'Locale to use', $locale),
37
                    new InputOption('to', 't', InputOption::VALUE_OPTIONAL, 'To address or domain'),
38
                    new InputOption('from', 'f', InputOption::VALUE_OPTIONAL, 'From address or domain'),
39
                    new InputOption('set-corpus-path', null, InputOption::VALUE_OPTIONAL, 'Directory containing email corpus'),
40
                ]
41
            );
42
    }
43
44
    /**
45
     * @param InputInterface $input
46
     * @param OutputInterface $output
47
     * @throws \Exception
48
     * @return int
49
     */
50
    protected function execute(InputInterface $input, OutputInterface $output): int
51
    {
52
        $validator = new Validator($input);
53
        $validInput = $validator->validateInput();
54
55
        $style = new OutputFormatterStyle('green', null, ['bold']);
56
        $output->getFormatter()->setStyle('bold', $style);
57
        $output->writeln('<comment>Spammer starting up</comment>');
58
59
        return $this->sendFakeEmail($output, $validInput);
60
    }
61
62
    /**
63
     * @param OutputInterface $output
64
     * @param array $validInput
65
     * @throws \Exception
66
     * @return int
67
     */
68
    private function sendFakeEmail(OutputInterface $output, array $validInput): int
69
    {
70
        $message = '<info>Sending </info><bold>' . $validInput['count'] . '</bold>' .
71
            '<info> email to server </info><bold>' . $validInput['smtpServerIp'] . '</bold>' .
72
            '<info>:</info><bold>' . $validInput['smtpServerPort'] . '</bold>';
73
        if ($validInput['from'] !== '') {
74
            $message .= '<info> from </info><bold>' . $validInput['from'] . '</bold>';
75
        }
76
        if ($validInput['to'] !== '') {
77
            $message .= '<info> to </info><bold>' . $validInput['to'] . '</bold>';
78
        }
79
        $output->write($message);
80
        $output->writeln('<info> using locale </info><bold>' . $validInput['locale'] . '</bold>');
81
82
        $faker = Faker\Factory::create($validInput['locale']);
83
        $faker->seed(mt_rand());
84
85
        $transport = new Swift_SmtpTransport($validInput['smtpServerIp'], $validInput['smtpServerPort']);
86
        $mailer = new Swift_Mailer($transport);
87
88
        $numSent = 0;
89
        for ($i = 0; $i < $validInput['count']; $i++) {
90
            $emaiText = $faker->realText(random_int(200, 1000));
91
            $emailSubject = implode(' ', $faker->words(random_int(3, 7)));
0 ignored issues
show
Bug introduced by
It seems like $faker->words(random_int(3, 7)) can also be of type string; however, parameter $pieces of implode() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

91
            $emailSubject = implode(' ', /** @scrutinizer ignore-type */ $faker->words(random_int(3, 7)));
Loading history...
92
            $message = new Swift_Message($emailSubject);
93
94
            $from = $this->getFromTo($faker, $validInput['from']);
95
            $message->setFrom($from);
96
97
            $to = $this->getFromTo($faker, $validInput['to']);
98
            $message->setTo($to);
99
100
            $message->setBody($emaiText, 'text/plain');
101
            $message->addPart('<p>' . $emaiText . '</p>', 'text/html');
102
103
            $output->writeln('Sending email nr. ' . ($i + 1) . ': ' . key($from) . ' => ' . key($to));
104
            try {
105
                $numSent += $mailer->send($message);
106
            } catch (\Exception $swe) {
107
                $output->writeln('<error>' . $swe->getMessage() . '</error>');
108
109
                return 1;
110
            }
111
        }
112
113
        $output->writeln('Sent ' . $numSent . ' messages');
114
115
        unset($faker);
116
117
        return 0;
118
    }
119
120
    /**
121
     * @param Faker\Generator $faker
122
     * @param string $validInputFromTo
123
     * @return array
124
     */
125
    private function getFromTo(Faker\Generator $faker, $validInputFromTo): array
126
    {
127
        // generate fake address and name if null
128
        if ($validInputFromTo === '') {
129
            return [$faker->safeEmail => $faker->name];
130
        }
131
132
        // use user submitted email if is email
133
        if (filter_var($validInputFromTo, FILTER_VALIDATE_EMAIL)) {
134
            return [$validInputFromTo => $faker->name];
135
        }
136
137
        // get a random username and attach it to domain supplied by user
138
        $user = strstr($faker->safeEmail, '@', true);
139
140
        return [$user . '@' . $validInputFromTo => $faker->name];
141
    }
142
}
143