Completed
Push — master ( 974133...f3d891 )
by Marc
05:38
created

ContactModel   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 158
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 19
c 1
b 0
f 0
lcom 1
cbo 0
dl 0
loc 158
rs 10
1
<?php
2
3
namespace org\example\Contact;
4
5
use PHPMailer;
6
7
/**
8
 * Application logic for contact form
9
 */
10
class ContactModel
11
{
12
    /**
13
     * @var array Holds all titles (salutations) that may be chosen from
14
     */
15
    protected $titles = array(
16
       #0 => intentionally left blank ("not chosen")
17
        1 => 'Mr',
18
        2 => 'Ms',
19
        3 => 'Company'
20
    );
21
22
    /**
23
     * @var string Path to PHPMailer directory in local file system
24
     */
25
    protected $pathToMailer = './library/phpmailer/PHPMailer_v5.1';
26
27
    /**
28
     * @var string All e-mails will be sent to this address
29
     */
30
    protected $emailRecipient = '[email protected]';
31
32
    /**
33
     * @var int Number of seconds a session has to wait before a second e-mail
34
     *          will be accepted (protection from spam and accidental double
35
     *          posts)
36
     * @todo Probably not the most clever way to do this
37
     */
38
    protected $emailInterval = 60;
39
40
    /**
41
     * Returns all titles (salutations) a user may chose from
42
     *
43
     * @return array Titles to chose from
44
     */
45
    public function getTitles()
46
    {
47
        return $this->titles;
48
    }
49
50
    /**
51
     * Sanitizes and validates input, calls the method to mail the supplied
52
     * contact form data and returns an array of errors
53
     *
54
     * @return array Errors (an empty array indicates there are no errors)
55
     */
56
    public function sendEmailFromPOST()
57
    {
58
        $errors = array();
59
60
        // Do not overwrite original data in $_POST
61
        $data = $_POST;
62
63
        // Make sure every field is set
64
        $data['email'] = (isset($data['email']))
65
                       ? trim((string) $data['email']) : '';
66
        $data['title'] = (isset($data['title']))
67
                       ? (int) $data['title'] : 0;
68
        $data['name']  = (isset($data['name']))
69
                       ? trim((string) $data['name']) : '';
70
        $data['phone'] = (isset($data['phone']))
71
                       ? trim((string) $data['phone']) : '';
72
        $data['callback'] = (isset($data['callback']))
73
                          ? (bool) $data['callback'] : false;
74
75
        // Validate input
76
        $data['email'] = preg_match('/^[^@\s]+@[^@\s]+\.[^@\s.]+$/',
77
                                    $data['email'])
78
                       ? $data['email'] : '';
79
        $data['title'] = (isset($this->titles[$data['title']]))
80
                       ? $data['title'] : 0;
81
82
        // Generate error messages for fields that have to be filled
83
        if ($data['email'] === '') {
84
            $errors[] = 'Please provide a valid e-mail address.';
85
        }
86
        if ($data['title'] === 0) {
87
            $errors[] = 'Please choose a title from the list.';
88
        }
89
        if ($data['name'] === '') {
90
            $errors[] = 'Please enter your name.';
91
        }
92
93
        // In case of error, return
94
        if (!empty($errors)) {
95
            return $errors;
96
        }
97
98
        // Otherwise, we're clear to mail the data
99
        $errors = $this->doSendEmail($data);
100
101
        return $errors;
102
    }
103
104
    /**
105
     * Mails data from contact form
106
     *
107
     * @param array $data Sanitized and validated form input
108
     * @return array Errors (an empty array indicates there are no errors)
109
     */
110
    protected function doSendEmail($data)
111
    {
112
        // Application relies on session for spam protection
113
        if (!isset($_SESSION['contact']['lastEmailSent'])) {
114
            return array('You have to accept the session cookie.');
115
        }
116
117
        // See if enough time has passed to send another e-mail
118
        if (isset($_SESSION['contact']['lastEmailSent'])
119
                && ($_SESSION['contact']['lastEmailSent']
120
                        + $this->emailInterval > time())
121
        ) {
122
            return array(sprintf(
123
                    'You have to wait a total of %d seconds before you can '
124
                    . 'send another e-mail.', $this->emailInterval));
125
        }
126
127
        require_once $this->pathToMailer . '/class.phpmailer.php';
128
129
        // Generate body
130
        $body = sprintf("E-Mail:   %s\n", $data['email'])
131
              . sprintf("Title:    %s\n", $this->titles[$data['title']])
132
              . sprintf("Name:     %s\n", $data['name'])
133
              . sprintf("Phone:    %s\n", $data['phone'])
134
              . sprintf("Callback: %s", ($data['callback']) ? 'yes' : 'no');
135
136
        $mail = new PHPMailer();
137
138
        // Setup mailing method
139
        /** @todo Configuration settings should be moved to a config file */
140
        $mail->IsSMTP(true);
141
        $mail->Host     = 'ssl://smtp.example.org:465';
142
        $mail->SMTPAuth = true;
143
        $mail->Username = '';
144
        $mail->Password = '';
145
146
        // Set e-mail headers to more or less fitting values
147
        $mail->Subject = 'example.org -- Contact inquiry';
148
        $mail->Body    = $body;
149
        $mail->CharSet = 'UTF-8';
150
151
        $mail->AddReplyTo($data['email'], $data['name']);
152
        $mail->SetFrom('[email protected]');
153
        
154
        $mail->AddAddress($this->emailRecipient);        
155
156
        // Try to send mail, return errors on failure
157
        if (!$mail->Send()) {
158
            return array('Mailer Error: ' . $mail->ErrorInfo);
159
        }
160
161
        // E-mail sent, as far as we can tell. No errors
162
        $_SESSION['contact']['lastEmailSent'] = time();
163
        $_POST = array();
164
165
        return array();
166
    }
167
}