This source file includes following definitions.
- valid_eMailAddress
- validContentId
- validContentKey
- mime_content_type
- __construct
- setTo
- setFrom
- setSubject
- setTextMessage
- setTextMessageProperty
- setHtmlMessage
- setHtmlMessageProperty
- addRelated
- setRelatedProperty
- addAttachment
- setAttachmentProperty
- finalize
- createMultipartAlternativeMessage
- createMultipartRelatedMessage
- createMultipartMixedMessage
- getSource
- sendMail
1 <?php
2
3
4
5
6
7
8
9
10 final class sendMail {
11
12 const eMailAddressErrorMessage="L' e-Mail indicata non rispetta un formato valido.";
13 const defaultSubject="this is the subject.";
14 const defaultTextMessage="this is text message.";
15 const defaultHtmlMessage="this is html message.";
16 const defaultHeaderMessage="this is a multi-part message in MIME format.";
17
18 private static $messageProperties=array(
19 "charset" => array(
20 "modifiable" => true,
21 "values" => array(
22 "iso-8859-1",
23 "iso-8859-15",
24 "utf-8",
25 "utf-16"
26 )
27 ),
28 "content-transfer-encoding" => array(
29 "modifiable" => true,
30 "values" => array(
31 "7bit",
32 "8bit",
33 "quoted-printable"
34 )
35 )
36 );
37
38 private $attachmentProperties=array(
39 "content-type" => array(
40 "modifiable" => false,
41 "values" => array(
42 "application/octet-stream"
43 )
44 ),
45 "content-transfer-encoding" => array(
46 "modifiable" => false,
47 "values" => array(
48 "base64"
49 )
50 ),
51 "content-disposition" => array(
52 "modifiable" => true,
53 "values" => array(
54 "attachment",
55 "inline"
56 )
57 )
58 );
59
60 private static $relatedProperties=array(
61 "content-transfer-encoding" => array(
62 "modifiable" => false,
63 "values" => array(
64 "base64"
65 )
66 )
67 );
68
69 private $html;
70 private $text;
71
72 private $related;
73 private $attachments;
74
75 public static function valid_eMailAddress($eMailAddress) {
76 if(ereg("^[^@ ]+@[^@ ]+\.[^@ ]+$", $eMailAddress))
77 return true;
78 else
79 return false;
80 }
81
82 public static function validContentId($contentId) {
83 if(ereg("^[a-zA-Z0-9]+$", $contentId))
84 return true;
85 else
86 return false;
87 }
88
89 public static function validContentKey($contentKey) {
90 if(ereg("^[a-zA-Z0-9]+$", $contentKey))
91 return true;
92 else
93 return false;
94 }
95
96 public static function mime_content_type($filename) {
97 $mime=array(
98 '.3dmf' => 'x-world/x-3dmf',
99 '.a' => 'application/octet-stream',
100 '.aab' => 'application/x-authorware-bin',
101 '.xwd' => 'image/x-xwd',
102 '.xyz' => 'chemical/x-pdb',
103 '.z' => 'application/x-compressed',
104 '.zip' => 'application/x-zip-compressed',
105 '.zoo' => 'application/octet-stream',
106 '.zsh' => 'text/x-script.zsh',
107 '.css' => 'text/css'
108 );
109 return $mime[strrchr($filename, '.')];
110 }
111
112 private $from;
113 private $to;
114 private $subject;
115
116 private $finalized;
117
118 private $headerMessage;
119 private $bodyMessage;
120
121 private $boundaries;
122
123 public function __construct($from, $to, $subject=self::defaultSubject) {
124
125
126 if(!self::valid_eMailAddress($from))
127 die(self::eMailAddressErrorMessage);
128 else
129 $this->from=$from;
130
131
132 if(!self::valid_eMailAddress($to))
133 die(self::eMailAddressErrorMessage);
134 else
135 $this->to=$to;
136
137
138 $this->subject=$subject;
139
140
141 $this->text=array(
142 "message" => self::defaultTextMessage,
143 "properties" => array(
144 "charset" => self::$messageProperties["charset"]["values"][0],
145 "content-transfer-encoding" => self::$messageProperties["content-transfer-encoding"]["values"][0]
146 )
147 );
148
149
150 $this->html=array(
151 "message" => self::defaultHtmlMessage,
152 "properties" => array(
153 "charset" => self::$messageProperties["charset"]["values"][0],
154 "content-transfer-encoding" => self::$messageProperties["content-transfer-encoding"]["values"][1]
155 )
156 );
157
158
159 $this->related=array();
160 $this->attachments=array();
161
162
163 $this->finalized=false;
164
165 $this->headerMessage="";
166 $this->bodyMessage="";
167
168 $this->boundaries=array(
169 "multipart/alternative" => md5(uniqid(microtime())),
170 "multipart/related" => md5(uniqid(microtime())),
171 "multipart/mixed" => md5(uniqid(microtime()))
172 );
173
174 }
175
176 public function setTo($to, &$errorString) {
177 if(self::valid_eMailAddress($to)) {
178 $this->to=$to;
179 return true;
180 } else {
181 $errorString=eMailAddressErrorMessage;
182 return false;
183 }
184 }
185
186 public function setFrom($from, &$errorString) {
187 if(self::valid_eMailAddress($from)) {
188 $this->from=$from;
189 return true;
190 } else {
191 $errorString=eMailAddressErrorMessage;
192 return false;
193 }
194 }
195
196 public function setSubject($subject=self::defaultSubject) {
197 $this->subject=$subject;
198 }
199
200 public function setTextMessage($textMessage=self::defaultTextMessage) {
201 $this->text["message"]=$textMessage;
202 }
203
204 public function setTextMessageProperty($key, $value, &$errorString) {
205
206 $key=strtolower($key);
207 $value=strtolower($value);
208
209 if(isset(self::$messageProperties[$key])) {
210 if(in_array($value, self::$messageProperties[$key]["values"])) {
211 if(self::$messageProperties[$key]["modifiable"]) {
212 $this->text["properties"][$key]=$value;
213 return true;
214 } else {
215 $errorString="Il valore della propriet? indicata non ? modificabile.";
216 return false;
217 }
218 } else {
219 $errorString="Il valore indicato per questa propriet? non ? valido.";
220 return false;
221 }
222 } else {
223 $errorString="Non esiste questa propriet? per i messaggi html.";
224 return false;
225 }
226 }
227
228 public function setHtmlMessage($htmlMessage=self::defaultHtmlMessage) {
229 $this->html["message"]=$htmlMessage;
230 }
231
232 public function setHtmlMessageProperty($key, $value, &$errorString) {
233
234 $key=strtolower($key);
235 $value=strtolower($value);
236
237 if(isset(self::$messageProperties[$key])) {
238 if(in_array($value, self::$messageProperties[$key]["values"])) {
239 if(self::$messageProperties[$key]["modifiable"]) {
240 $this->html["properties"][$key]=$value;
241 return true;
242 } else {
243 $errorString="Il valore della propriet? indicata non ? modificabile.";
244 return false;
245 }
246 } else {
247 $errorString="Il valore indicato per questa propriet? non ? valido.";
248 return false;
249 }
250 } else {
251 $errorString="Non esiste questa propriet? per i messaggi html.";
252 return false;
253 }
254 }
255
256 public function addRelated($fileName, $relatedKey, $contentId, &$errorString) {
257 if(is_file($fileName)) {
258 if($fileHandle=fopen($fileName, "r")) {
259 if(self::validContentId($contentId)) {
260 if(!isset($this->related[$relatedKey])) {
261 if(self::validContentKey($relatedKey)) {
262 $this->related[$relatedKey]=array(
263 "fileName" => basename($fileName),
264 "properties" => array(
265 "content-type" => self::mime_content_type($fileName),
266 "content-transfer-encoding" => self::$relatedProperties["content-transfer-encoding"]["values"][0],
267 "content-id" => $contentId
268 ),
269 "source" => base64_encode(
270 fread($fileHandle, filesize($fileName))
271 )
272 );
273 return true;
274 } else {
275 $errorString="L' id specificato non ? valido.";
276 return false;
277 }
278 } else {
279 $errorString="La chiave specificata ? gi? associata ad un altro related.";
280 return false;
281 }
282 } else {
283 $errorString="La chiave specificata per il related non ? valida.";
284 return false;
285 }
286 } else {
287 $errorString="Non ? possibile aprire il file indicato.";
288 return false;
289 }
290 } else {
291 $errorString="Il nome del file indicato non ? valido.";
292 return false;
293 }
294 }
295
296 public function setRelatedProperty($relatedKey, $key, $value, &$errorString) {
297
298 $key=strtolower($key);
299 $value=strtolower($value);
300
301 if(isset(self::$relatedProperties[$key])) {
302 if(in_array($value, self::$relatedProperties[$key]["values"])) {
303 if(self::$relatedProperties[$key]["modifiable"]) {
304 if(isset($this->related[$relatedKey])) {
305 $this->related[$relatedKey]["properties"][$key]=$value;
306 return true;
307 } else {
308 $errorString="Il related indicato non esiste.";
309 return false;
310 }
311 } else {
312 $errorString="Il valore della propriet? indicata non ? modificabile.";
313 return false;
314 }
315 } else {
316 $errorString="Il valore indicato per questa propriet? non ? valido.";
317 return false;
318 }
319 } else {
320 $errorString="Non esiste questa propriet? per i related.";
321 return false;
322 }
323 }
324
325 public function addAttachment($fileName, $attachmentKey, &$errorString) {
326 if(is_file($fileName)) {
327 if($fileHandle=fopen($fileName, "r")) {
328 if(self::validContentKey($attachmentKey)) {
329 if(!isset($this->attachments[$attachmentKey])) {
330 $this->attachments[$attachmentKey]=array(
331 "fileName" => basename($fileName),
332 "properties" => array(
333 "content-type" => self::$attachmentProperties["content-type"]["values"][0],
334 "content-disposition" => self::$attachmentProperties["content-disposition"]["values"][0],
335 "content-transfer-encoding" => self::$attachmentProperties["content-transfer-encoding"]["values"][0]
336 ),
337 "source" => base64_encode(
338 fread($fileHandle, filesize($fileName))
339 )
340 );
341 return true;
342 } else {
343 $errorString="La chiave specificata ? gi? associata ad un altro allegato.";
344 return false;
345 }
346 } else {
347 $errorString="La chiave specificata per l'allegato non ? valida.";
348 return false;
349 }
350 } else {
351 $errorString="Non ? possibile aprire il file indicato.";
352 return false;
353 }
354 } else {
355 $errorString="Il nome del file indicato non ? valido.";
356 return false;
357 }
358 }
359
360 public function setAttachmentProperty($attachmentKey, $key, $value, &$errorString) {
361
362 $key=strtolower($key);
363 $value=strtolower($value);
364
365 if(isset(self::$attachmentProperties[$key])) {
366 if(in_array($value, self::$attachmentProperties[$key]["values"])) {
367 if(self::$attachmentProperties[$key]["modifiable"]) {
368 if(isset($this->attachments[$attachmentKey])) {
369 $this->attachments[$attachmentKey]["properties"][$key]=$value;
370 return true;
371 } else {
372 $errorString="L'allegato indicato non esiste.";
373 return false;
374 }
375 } else {
376 $errorString="Il valore della propriet? indicata non ? modificabile.";
377 return false;
378 }
379 } else {
380 $errorString="Il valore indicato per questa propriet? non ? valido.";
381 return false;
382 }
383 } else {
384 $errorString="Non esiste questa propriet? per gli allegati.";
385 return false;
386 }
387 }
388
389 public function finalize(&$errorString) {
390 if(!$this->finalized) {
391 $this->headerMessage="from: ".($this->from)."\n";
392 $this->headerMessage.="to: ".($this->to)."\n";
393 $this->headerMessage.="subject: ".($this->subject)."\n";
394 $this->headerMessage.="mime-version: 1.0\n";
395
396 if(($countAttachments=count($this->attachments))>0) {
397 $this->headerMessage.="content-type: multipart/mixed; boundary=\"".($this->boundaries["multipart/mixed"])."\"\n\n";
398 $this->headerMessage.=self::defaultHeaderMessage;
399 $this->headerMessage.="\n\n";
400
401 $this->bodyMessage="--".($this->boundaries["multipart/mixed"])."\n";
402
403 if(($countRelated=count($this->related))>0) {
404 $this->bodyMessage.="content-type: multipart/related; type=\"multipart/alternative\"; boundary=\"".($this->boundaries["multipart/related"])."\"\n\n";
405
406 $this->bodyMessage.="--".($this->boundaries["multipart/related"])."\n";
407
408 $this->bodyMessage.="content-type: multipart/alternative; boundary=\"".($this->boundaries["multipart/alternative"])."\"\n\n";
409 $this->createMultipartAlternativeMessage($this->boundaries["multipart/alternative"]);
410 $this->bodyMessage.="--".($this->boundaries["multipart/alternative"])."--\n\n";
411
412
413
414 $relatedCounter=0;
415 while(list($key,)=each($this->related)) {
416 $relatedCounter++;
417
418 $this->bodyMessage.="--".$this->boundaries["multipart/related"]."\n";
419 $this->createMultipartRelatedMessage($key);
420 if($relatedCounter!=$countRelated) $this->bodyMessage.="--".($this->boundaries["multipart/related"])."\n";
421 else $this->bodyMessage.="--".($this->boundaries["multipart/related"])."--\n\n";
422 }
423 } else {
424 $this->bodyMessage.="content-type: multipart/alternative; boundary=\"".($this->boundaries["multipart/alternative"])."\"\n\n";
425 $this->createMultipartAlternativeMessage();
426 $this->bodyMessage.="--".($this->boundaries["multipart/alternative"])."--\n\n";
427 }
428
429 $attachmentsCounter=0;
430 while(list($key,)=each($this->attachments)) {
431 $attachmentsCounter++;
432 $this->bodyMessage.="--".($this->boundaries["multipart/mixed"])."\n";
433 $this->createMultipartMixedMessage($key);
434 if($attachmentsCounter!=$countAttachments) $this->bodyMessage.="--".($this->boundaries["multipart/mixed"])."\n";
435 else $this->bodyMessage.="--".($this->boundaries["multipart/mixed"])."--\n\n";
436 }
437 } else {
438 if(($countRelated=count($this->related))>0) {
439 $this->headerMessage.="content-type: multipart/related; type=\"multipart/alternative\"; boundary=\"".($this->boundaries["multipart/related"])."\"\n\n";
440 $this->headerMessage.=self::defaultHeaderMessage;
441 $this->headerMessage.="\n\n";
442
443 $this->bodyMessage="--".($this->boundaries["multipart/related"])."\n";
444 $this->bodyMessage.="content-type: multipart/alternative; boundary=\"".($this->boundaries["multipart/alternative"])."\"\n\n";
445 $this->createMultipartAlternativeMessage();
446 $this->bodyMessage.="--".($this->boundaries["multipart/alternative"])."--\n\n";
447
448 $relatedCounter=0;
449 while(list($key,)=each($this->related)) {
450 $relatedCounter++;
451 $this->bodyMessage.="--".$this->boundaries["multipart/related"]."\n";
452 $this->createMultipartRelatedMessage($key);
453 if($relatedCounter!=$countRelated) $this->bodyMessage.="--".($this->boundaries["multipart/related"])."\n";
454 else $this->bodyMessage.="--".($this->boundaries["multipart/related"])."--\n\n";
455 }
456 } else {
457 $this->headerMessage.="content-type: multipart/alternative; boundary=\"".($this->boundaries["multipart/alternative"])."\"\n\n";
458 $this->headerMessage.=self::defaultHeaderMessage;
459 $this->headerMessage.="\n\n";
460
461 $this->createMultipartAlternativeMessage();
462 $this->bodyMessage.="--".($this->boundaries["multipart/alternative"])."--";
463
464 }
465 }
466 $this->finalized=true;
467 return true;
468 } else {
469 $errorString="Al momento non ? possibile finalizzare.";
470 return false;
471 }
472 }
473
474 private function createMultipartAlternativeMessage() {
475 $multipartAlternativeBoundary=$this->boundaries["multipart/alternative"];
476 $this->bodyMessage.="--$multipartAlternativeBoundary\n";
477 $this->bodyMessage.="content-type: text/plain; charset=\"".($this->text["properties"]["charset"])."\"\n";
478 $this->bodyMessage.="content-transfer-encoding: ".($this->text["properties"]["content-transfer-encoding"])."\n\n";
479 $this->bodyMessage.=$this->text["message"];
480 $this->bodyMessage.="\n\n";
481 $this->bodyMessage.="--$multipartAlternativeBoundary\n";
482 $this->bodyMessage.="content-type: text/html; charset=\"".($this->html["properties"]["charset"])."\"\n";
483 $this->bodyMessage.="content-transfer-encoding: ".($this->html["properties"]["content-transfer-encoding"])."\n\n";
484 $this->bodyMessage.=$this->html["message"];
485 $this->bodyMessage.="\n\n";
486 }
487
488 private function createMultipartRelatedMessage($key) {
489 $obj=$this->related[$key];
490 $this->bodyMessage.="content-type: ".($obj["properties"]["content-type"])."; name=\"".($obj["fileName"])."\"\n";
491 $this->bodyMessage.="content-transfer-encoding: ".($obj["properties"]["content-transfer-encoding"])."\n";
492 $this->bodyMessage.="content-id: <".($obj["properties"]["content-id"]).">\n\n";
493 $this->bodyMessage.=$obj["source"];
494 $this->bodyMessage.="\n\n";
495 }
496
497 private function createMultipartMixedMessage($key) {
498 $obj=$this->attachments[$key];
499 $this->bodyMessage.="content-type: ".($obj["properties"]["content-type"])."; name=\"".($obj["fileName"])."\"\n";
500 $this->bodyMessage.="content-transfer-encoding: ".($obj["properties"]["content-transfer-encoding"])."\n";
501 $this->bodyMessage.="content-disposition: ".($obj["properties"]["content-disposition"])."; filename=\"".($obj["fileName"])."\"\n\n";
502 $this->bodyMessage.=$obj["source"];
503 $this->bodyMessage.="\n\n";
504 }
505
506 public function getSource(&$errorString) {
507 if($this->finalized) {
508 return ($this->headerMessage).($this->bodyMessage);
509 } else {
510 $errorString="Ancora non ? avvenuta la finalizzazione.";
511 return false;
512 }
513 }
514
515 public function sendMail(&$errorString) {
516 if($this->finalized) {
517 mail($this->to, $this->subject, $this->bodyMessage, $this->headerMessage);
518 $this->finalized=false;
519 return true;
520 } else {
521 $errorString="Ancora non ? avvenuta la finalizzazione.";
522 return false;
523 }
524 }
525 }
526
527 ?>