Touren application
[infodrom.org/touren.infodrom.org] / core / mail.class.php
1 <?php
2
3 class Mail {
4   protected $header = array();
5   protected $env_from = false;
6   protected $attachments = array();
7   protected $CRLF = "\r\n";
8
9   public function set($name, $value)
10   {
11     $this->header[$name][] = $value;
12   }
13
14   public function env_from($value)
15   {
16     $this->env_from = $value;
17   }
18
19   protected function contentType($path)
20   {
21     if (($fh = popen('/usr/bin/file -i -b ' . escapeshellarg(realpath($path)), 'r')) !== false) {
22       $type = fread($fh, 1024);
23       fclose($fh);
24       $parts = explode(';', $type);
25       return trim($parts[0]);
26     } else
27       return mime_content_type($file);
28   }
29
30   public function attach($content, $type=false, $first=false)
31   {
32     $part = new stdClass();
33
34     if ($type === false) {
35       if (file_exists($content)) {
36         $part->content = chunk_split(base64_encode(file_get_contents($content)));
37         $part->header = 'Content-Type: ' . $this->contentType($content) . '; name="'.basename($content).'"'. $this->CRLF .
38           'Content-Transfer-Encoding: base64' . $this->CRLF .
39           'Content-Disposition: attachment';
40       }
41     } elseif (substr($type, 0, 10) == 'text/plain' ||
42               substr($type, 0, 9) == 'text/html') {
43       if (strpos($type, 'charset=') === false)
44         $type .= '; charset="UTF-8"';
45       $part->content = $content;
46       $part->header = 'Content-Type: ' . $type . $this->CRLF .
47         'Content-Transfer-Encoding: 8bit';
48     } else {
49       $part->content = chunk_split(base64_encode($content));
50       $part->header = 'Content-Type: ' . $type . $this->CRLF .
51         'Content-Transfer-Encoding: base64' . $this->CRLF .
52         'Content-Disposition: attachment';
53     }
54
55     if (!empty($part->content)) {
56       if ($first)
57         array_unshift($this->attachments, $part);
58       else
59         $this->attachments[] = $part;
60     }
61   }
62
63   public function send($body=false)
64   {
65     if (!array_key_exists('From', $this->header))
66       throw new Exception('No sender given.');
67     if (!array_key_exists('To', $this->header))
68       throw new Exception('No recipient given.');
69     if (!array_key_exists('Subject', $this->header))
70       throw new Exception('No subject given.');
71     if (!count($this->attachments) && empty($body))
72       throw new Exception('Mail body empty and no attachments.');
73
74     if (count($this->attachments)) {
75       $boundary = md5(uniqid(time()));
76       $this->header['MIME-Version'] = array('1.0');
77       $this->header['Content-Type'] = array('multipart/mixed; boundary="'.$boundary.'"');
78       if ($body)
79         $this->attach($body, substr($body,0,1) == '<' ? 'text/html' : 'text/plain', true);
80     } else {
81       if (!array_key_exists('Content-Type', $this->header)) {
82         if ($body && substr($body,0,1) == '<')
83           $this->set('Content-Type', 'text/html; charset=UTF-8');
84         else
85           $this->set('Content-Type', 'text/plain; charset=UTF-8');
86       }
87       if (!array_key_exists('Content-Disposition', $this->header))
88         $this->set('Content-Disposition', 'inline');
89       if (!array_key_exists('Content-Transfer-Encoding', $this->header))
90         $this->set('Content-Transfer-Encoding', '8bit');
91     }
92
93     $header = '';
94     $to = implode(', ', $this->header['To']);
95     if (defined('MAIL_DISABLED') && MAIL_DISABLED !== false) {
96       $header .= 'Orig-To: ' . $to . $this->CRLF;
97       $to = MAIL_DISABLED;
98
99       if (array_key_exists('Cc', $this->header)) {
100         $this->header['Orig-Cc'] = $this->header['Cc'];
101         unset($this->header['Cc']);
102       }
103       if (array_key_exists('Bcc', $this->header)) {
104         $this->header['Orig-Bcc'] = $this->header['Bcc'];
105         unset($this->header['Bcc']);
106       }
107     }
108     foreach ($this->header as $name => $values) {
109       if ($name == 'To' || $name == 'Subject')
110         continue;
111       else
112         $header .= $name . ': ' . implode(', ', $values) . $this->CRLF;
113     }
114
115     $opts = '-t';
116     $opts .= strlen($this->env_from) ? ' -f '.$this->env_from : '';
117
118     $header = substr($header,0,-strlen($this->CRLF));
119     if (count($this->attachments)) {
120       $header .= $this->CRLF . "This is a MIME encoded message." . $this->CRLF;
121
122       foreach ($this->attachments as $part) {
123         $header .= "--$boundary" . $this->CRLF;
124         $header .= $part->header . $this->CRLF;
125         $header .= $this->CRLF . $part->content . $this->CRLF;
126       }
127       $header .= "--$boundary--";
128
129       $result = mail($to, $this->header['Subject'][0], '', $header, $opts);
130     } else {
131       $result = mail($to, $this->header['Subject'][0], $body, $header, $opts);
132     }
133
134     Application::debug(sprintf('Send Mail "%s" to %s', $this->header['Subject'][0], $this->header['To'][0]));
135     return $result;
136   }
137 }