Driver_SMTP   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 190
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
dl 0
loc 190
rs 10
c 0
b 0
f 0
wmc 10
lcom 1
cbo 2

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
B _commands() 0 26 1
B _remote() 0 47 4
A _errorlog() 0 10 2
A prepare() 0 19 1
A send() 0 14 1
1
<?php
2
3
/**
4
 * Provides mail functionality using a remote smtp connection
5
 *
6
 * PHP Version 5
7
 *
8
 * @category  Core
9
 * @package   Mail
10
 * @author    Hans-Joachim Piepereit <[email protected]>
11
 * @copyright 2013 cSphere Team
12
 * @license   http://opensource.org/licenses/bsd-license Simplified BSD License
13
 * @link      http://www.csphere.eu
14
 **/
15
16
namespace csphere\core\mail;
17
18
/**
19
 * Provides mail functionality using a remote smtp connection
20
 *
21
 * @category  Core
22
 * @package   Mail
23
 * @author    Hans-Joachim Piepereit <[email protected]>
24
 * @copyright 2013 cSphere Team
25
 * @license   http://opensource.org/licenses/bsd-license Simplified BSD License
26
 * @link      http://www.csphere.eu
27
 **/
28
29
class Driver_SMTP extends Base
30
{
31
    /**
32
     * Stores the server address
33
     **/
34
     private $_server = '';
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 4 spaces, found 5
Loading history...
35
36
    /**
37
     * Creates the mail handler object
38
     *
39
     * @param array $config Configuration details as an array
40
     *
41
     * @return \csphere\core\mail\Driver_SMTP
42
     **/
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
Coding Style introduced by
There must be no blank lines after the function comment
Loading history...
43
44
    public function __construct(array $config)
45
    {
46
        parent::__construct($config);
47
48
        // Get server address of this machine
49
        $this->_server = \csphere\core\http\Input::get('server', 'SERVER_ADDR');
50
    }
51
52
    /**
53
     * Prepares a command list for later usage
54
     *
55
     * @param string $email Email target
56
     *
57
     * @return array
58
     **/
0 ignored issues
show
Coding Style introduced by
There must be no blank lines after the function comment
Loading history...
59
60
    private function _commands($email)
61
    {
62
        // Prepare header data
63
        $headers   = [];
64
        $headers[] = 'To: ' . $email;
65
        $headers[] = 'Subject: ' . $this->content['subject_b64'];
66
67
        $headers = implode($this->config['eol'], $this->headers);
68
69
        // Combine content parts
70
        $data = $headers . $this->config['eol']
71
              . $this->content['message_b64'] . $this->config['eol'] . '.';
72
73
        // Create command list
74
        $commands = ['helo' => 'HELO ' . $this->_server,
75
                     'login' => 'AUTH LOGIN',
76
                     'user' => base64_encode($this->config['username']),
77
                     'pw' => base64_encode($this->config['password']),
78
                     'from' => 'MAIL FROM:' . $this->config['from'],
79
                     'to' => 'RCPT TO:' . $email,
80
                     'data' => 'DATA',
81
                     'response' => $data,
82
                     'quit' => 'QUIT'];
83
84
        return $commands;
85
    }
86
87
    /**
88
     * Execute the commands on smtp server
89
     *
90
     * @param array $commands Commands to work with
91
     *
92
     * @return boolean
93
     **/
0 ignored issues
show
Coding Style introduced by
There must be no blank lines after the function comment
Loading history...
94
95
    private function _remote(array $commands)
96
    {
97
        $result = false;
98
99
        $log = [];
100
101
        // Open connection to smtp server
102
        $remote = fsockopen($this->config['host'], (int)$this->config['port']);
103
104
        // On success proceed
105
        if (is_resource($remote)) {
106
107
            // Set timeout
108
            stream_set_timeout($remote, (int)$this->config['timeout']);
109
110
            foreach ($commands AS $com_name => $com_exec) {
111
112
                // Send command and get answer
113
                fwrite($remote, $com_exec . $this->config['eol']);
114
115
                $read = fread($remote, 2048);
116
117
                // Store communication in log
118
                $log[] = $com_name . ': ' . $read;
119
120
                // Stop on bad status code
121
                $code = (int) substr($read, 0, 3);
122
123
                if ($code >= 400) {
124
125
                    fclose($remote);
126
127
                    $this->_errorlog($code, (array)$log);
128
129
                    return false;
130
                }
131
            }
132
133
            // Tidy up and store success
134
            fclose($remote);
135
136
            $result = true;
137
138
        }
139
140
        return $result;
141
    }
142
143
    /**
144
     * Handle SMTP Server communication errors
145
     *
146
     * @param integer $code Status code
147
     * @param array   $log  Log as an array
148
     *
149
     * @throws \Exception
150
     *
151
     * @return void
152
     **/
0 ignored issues
show
Coding Style introduced by
There must be no blank lines after the function comment
Loading history...
153
154
    private function _errorlog($code, array $log)
155
    {
156
        $error = empty($code) ? 'Unknown' : 'Bad status code - ' . $code;
157
158
        // Append server communication
159
        $error .= "\n" . 'Communication:' . "\n" . implode("\n", $log);
160
161
        // Throw exception
162
        throw new \Exception($error);
163
    }
164
165
    /**
166
     * Prepares a mail by setting its content
167
     *
168
     * @param string $subject Subject to use in email
169
     * @param string $message Message to use in email
170
     * @param string $type    Defaults to text/plain
171
     *
172
     * @return boolean
173
     **/
0 ignored issues
show
Coding Style introduced by
There must be no blank lines after the function comment
Loading history...
174
175
    public function prepare($subject, $message, $type = 'text/plain')
176
    {
177
        // Run initial preparations
178
        parent::prepare($subject, $message, $type);
179
180
        // Set header data
181
        $headers = ['MIME-Version: 1.0',
182
                    'Content-Type: ' . $type . '; charset=UTF-8',
183
                    'Content-Transfer-Encoding: base64',
184
                    'X-Mailer: cSphere',
185
                    'From: ' . $this->config['from']];
186
187
        $this->headers = array_merge($this->headers, $headers);
188
189
        // Create encoded subject and content strings
190
        $this->encode();
191
192
        return true;
193
    }
194
195
    /**
196
     * Sends the prepared content to a given email
197
     *
198
     * @param string  $email Email target
199
     * @param boolean $clear Defaults to true which keeps mail data
200
     *
201
     * @return boolean
202
     **/
0 ignored issues
show
Coding Style introduced by
There must be no blank lines after the function comment
Loading history...
203
204
    public function send($email, $clear = true)
205
    {
206
        // Send mail
207
        $commands = $this->_commands($email);
208
209
        $send = $this->_remote($commands);
210
211
        // Log mail and handle clear status
212
        $this->log($email, $send);
213
214
        $this->clear($clear);
215
216
        return $send;
217
    }
218
}
219