Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
47.27% covered (danger)
47.27%
26 / 55
50.00% covered (danger)
50.00%
2 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
Email
47.27% covered (danger)
47.27%
26 / 55
50.00% covered (danger)
50.00%
2 / 4
33.11
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 handle
54.84% covered (warning)
54.84%
17 / 31
0.00% covered (danger)
0.00%
0 / 1
7.30
 getSender
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 sendEmail
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2
3/**
4 * Class Email
5 *
6 * PHP version 8
7 *
8 * Copyright (C) Moravian Library 2022.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2,
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22 *
23 * @category VuFind
24 * @package  Form
25 * @author   Josef Moravec <moravec@mzk.cz>
26 * @license  https://opensource.org/licenses/gpl-2.0.php GNU General Public License
27 * @link     https://vufind.org/wiki/development Wiki
28 */
29
30declare(strict_types=1);
31
32namespace VuFind\Form\Handler;
33
34use Laminas\Config\Config;
35use Laminas\Log\LoggerAwareInterface;
36use Laminas\Mail\Address;
37use Laminas\View\Renderer\RendererInterface;
38use VuFind\Db\Entity\UserEntityInterface;
39use VuFind\Exception\Mail as MailException;
40use VuFind\Form\Form;
41use VuFind\Log\LoggerAwareTrait;
42use VuFind\Mailer\Mailer;
43
44/**
45 * Class Email
46 *
47 * @category VuFind
48 * @package  Form
49 * @author   Josef Moravec <moravec@mzk.cz>
50 * @license  https://opensource.org/licenses/gpl-2.0.php GNU General Public License
51 * @link     https://vufind.org/wiki/development Wiki
52 */
53class Email implements HandlerInterface, LoggerAwareInterface
54{
55    use LoggerAwareTrait;
56
57    /**
58     * View renderer
59     *
60     * @var RendererInterface
61     */
62    protected $viewRenderer;
63
64    /**
65     * Main config
66     *
67     * @var Config
68     */
69    protected $mainConfig;
70
71    /**
72     * Mailer
73     *
74     * @var Mailer
75     */
76    protected $mailer;
77
78    /**
79     * Constructor
80     *
81     * @param RendererInterface $viewRenderer View renderer
82     * @param Config            $config       Main config
83     * @param Mailer            $mailer       Mailer
84     */
85    public function __construct(
86        RendererInterface $viewRenderer,
87        Config $config,
88        Mailer $mailer
89    ) {
90        $this->viewRenderer = $viewRenderer;
91        $this->mainConfig = $config;
92        $this->mailer = $mailer;
93    }
94
95    /**
96     * Get data from submitted form and process them.
97     *
98     * @param \VuFind\Form\Form                     $form   Submitted form
99     * @param \Laminas\Mvc\Controller\Plugin\Params $params Request params
100     * @param ?UserEntityInterface                  $user   Authenticated user
101     *
102     * @return bool
103     */
104    public function handle(
105        \VuFind\Form\Form $form,
106        \Laminas\Mvc\Controller\Plugin\Params $params,
107        ?UserEntityInterface $user = null
108    ): bool {
109        $postParams = $params->fromPost();
110        $fields = $form->mapRequestParamsToFieldValues($postParams);
111        $emailMessage = $this->viewRenderer->render(
112            'Email/form.phtml',
113            compact('fields')
114        );
115
116        [$senderName, $senderEmail] = $this->getSender($form);
117
118        $replyToName = $params->fromPost(
119            'name',
120            $user ? trim($user->getFirstname() . ' ' . $user->getLastname()) : null
121        );
122        $replyToEmail = $params->fromPost('email', $user?->getEmail());
123        $recipients = $form->getRecipient($postParams);
124        $emailSubject = $form->getEmailSubject($postParams);
125
126        $result = true;
127        foreach ($recipients as $recipient) {
128            if ($recipient['email']) {
129                $success = $this->sendEmail(
130                    $recipient['name'],
131                    $recipient['email'],
132                    $senderName,
133                    $senderEmail,
134                    $replyToName,
135                    $replyToEmail,
136                    $emailSubject,
137                    $emailMessage
138                );
139            } else {
140                $this->logError('Form recipient email missing; check recipient_email in config.ini.');
141                $success = false;
142            }
143
144            $result = $result && $success;
145        }
146        return $result;
147    }
148
149    /**
150     * Return email sender from configuration.
151     *
152     * @param Form $form Form
153     *
154     * @return array with name, email
155     */
156    protected function getSender(Form $form)
157    {
158        $config = $this->mainConfig;
159        $email = $form->getEmailFromAddress()
160            ?: $config->Feedback->sender_email ?? 'noreply@vufind.org';
161        $name = $form->getEmailFromName()
162            ?: $config->Feedback->sender_name ?? 'VuFind Feedback';
163
164        return [$name, $email];
165    }
166
167    /**
168     * Send form data as email.
169     *
170     * @param string $recipientName  Recipient name
171     * @param string $recipientEmail Recipient email
172     * @param string $senderName     Sender name
173     * @param string $senderEmail    Sender email
174     * @param string $replyToName    Reply-to name
175     * @param string $replyToEmail   Reply-to email
176     * @param string $emailSubject   Email subject
177     * @param string $emailMessage   Email message
178     *
179     * @return bool
180     */
181    protected function sendEmail(
182        $recipientName,
183        $recipientEmail,
184        $senderName,
185        $senderEmail,
186        $replyToName,
187        $replyToEmail,
188        $emailSubject,
189        $emailMessage
190    ): bool {
191        try {
192            $this->mailer->send(
193                new Address($recipientEmail, $recipientName),
194                new Address($senderEmail, $senderName),
195                $emailSubject,
196                $emailMessage,
197                null,
198                !empty($replyToEmail)
199                    ? new Address($replyToEmail, $replyToName) : null
200            );
201            return true;
202        } catch (MailException $e) {
203            $this->logError(
204                "Failed to send email to '$recipientEmail': " . $e->getMessage()
205            );
206            return false;
207        }
208    }
209}