mrpc Big Bang Co-ordinator


Ηλικία:25 Φύλο:
Ένταξη: Sep 11, 2002 Δημοσιεύσεις: 3024 Κατοικίδιο Τόπος: Ικαρία Euro: 1520 Items
|
Δημοσιεύθηκε: 20/08/2005 05:44 Θέμα δημοσίευσης: [tutorial] Multipart email form με ελληνικά και greeklish |
|
|
Πρόσφατα μου ζητήθηκε να φτιάξω μια εφαρμογή αποστολής email (για mailing list) η οποία θα μεταφράζει αυτόματα τα ελληνικά σε greeklish και θα στέλνει ένα multipart email το οποίο θα περιέχει Ελληνικά και Greeklish σε html και plain text.
Έφτιαξα λοιπόν ένα μικρό δείγμα το οποίο ίσως να βοηθήσει κάποιους. Βέβαια ο κώδικας είναι γραμμένος πολύ βιαστικά.
Ξεκινάμε λοιπόν φτιάχνοντας μια απλή html σελίδα με μια φόρμα που θα δέχεται τα στοιχεία που δίνουμε:
| Κώδικας: |
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Greeklish stuff</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-7">
<style type="text/css">
<!--
.style1 {font-size: small}
-->
</style>
</head>
<body>
<form name="form1" method="post" action="">
<p> Αποστολέας:
<input name="from" type="text" id="from">
<br>
Θέμα:
<input name="title" type="text" id="title">
<br>
Προς:
<input name="to" type="text" id="to" ">
</p>
<p>Μήνυμα <span class="style1">(Ελληνικά - html)</span> : </p>
<p>
<textarea name="text" rows="10" cols="50" id="text">
</textarea>
</p>
<p>
<input type="submit" name="Submit" value="Submit">
</p>
</form>
</body>
</html> |
Μια απλή Post φόρμα, η οποία επειδή δεν έχει δηλωμένο action, με το submit θα ξαναφορτώσει την ίδια σελίδα, αλλά με τα στοιχεία που θέλουμε.
Πριν δούμε τι θα κάνουμε με αυτά τα στοιχεία, καλό είναι να προσθέσουμε ένα τυπικό validation:
| Κώδικας: |
<?
if ($_POST['to']){
$Email_to = $_POST['to']; // Που θα πάει το mail
}
else {
$Email_to = '';
}
if ($_POST['title']) {
$Email_subject = $_POST['title']; // Θέμα
}
else {
$Email_subject = '';
}
if ($_POST['from']){
$from = $_POST['from']; // Αποστολέας
}
else {
$from = "";
}
if (isset($_POST['text'])) {
$text = $_POST['text'];
}
else {
$text ="";
}
$error = 0;
if ($Email_to == "") {
?> <b>ΔΕΝ ΕΧΕΤΕ ΕΙΣΑΓΕΙ ΔΙΕΥΘΥΝΣΗ ΠΑΡΑΛΗΠΤΗ</b><?
$error = 1;
}
if ($Email_subject == "") {
?> <b>ΔΕΝ ΕΧΕΤΕ ΕΙΣΑΓΕΙ ΘΕΜΑ</b><?
$error = 1;
}
if ($from == "") {
?> <b>ΔΕΝ ΕΧΕΤΕ ΔΙΕΥΘΥΝΣΗ ΑΠΟΣΤΟΛΕΑ</b><?
$error = 1;
}
if ($text == "") {
?> <b>ΔΕΝ ΕΙΣΑΓΕΙ ΚΕΙΜΕΝΟ</b><?
$error = 1;
}
?> |
Στον παραπάνω κώδικα ορίσαμε τις μεταβλητές μας για να μπορέσουμε να επεξεργαστούμε τα data που παίρνουμε από τη φόρμα και ελέγχουμε αν έχουμε ό,τι χρειαζόμαστε. Αν κάτι λείπει βγαίνει αντίστοιχο μήνυμα.
Επίσης έχουμε τη μεταβλητή $error η οποία αν όλα πάνε καλά θα πρέπει να είναι 0, σε οποιοδήποτε λάθος αλλάζει τιμή. Θα μας χρειαστεί αργότερα.
Φυσικά αφού έχουμε τις μεταβλητές, μπορούμε να τις χρησιμοποιήσουμε και στη φόρμα μας για να βλέπει ο χρήστης τι έχει εισάγει ήδη. Έτσι λοιπόν αντίστοιχα τις γραμμές:
| Κώδικας: |
| <input name="from" type="text" id="from"> |
| Κώδικας: |
| <input name="title" type="text" id="title"> |
| Κώδικας: |
| <input name="to" type="text" id="to" "> |
| Κώδικας: |
| <textarea name="text" rows="10" cols="50" id="text"></textarea> |
σε:
| Κώδικας: |
| <input name="from" type="text" id="from" value="<?=$from?>"> |
| Κώδικας: |
| <input name="title" type="text" id="title" value="<?=$Email_subject?>"> |
| Κώδικας: |
| <input name="to" type="text" id="to" value="<?=$Email_to?>"> |
| Κώδικας: |
<textarea name="text" rows="10" cols="50" id="text"><?=$text?>
</textarea> |
Τώρα το πρώτο πρόβλημα που αντιμετωπίζουμε είναι η μετατροπή των ελληνικών σε greeklish. Η πιο γρήγορη λύση είναι η function str_replace.
Η σύνταξή της σύμφωνα με το manual έχει ως εξής:
| Κώδικας: |
| str_replace ( mixed search, mixed replace, mixed subject [, int &count] ) |
Για τα search και replace μπορούμε να χρησιμοποιήσουμε arrays. Έτσι φτιάχνουμε ένα array με όλους τους ελληνικούς χαρακτήρες, κεφαλαίους, πεζούς, τονισμένους, με διαλυτικά, αι, οι, ου κλπ, και ένα δεύτερο array με τους αγγλικούς χαρακτήρες που θα αντικαταστήσουν τους ελληνικούς.
προσθέτουμε λοιπόν πριν το ?> στο τέλος του προηγούμενου κώδικα:
| Κώδικας: |
$greekfind = array("αι", "οι", "ου", "ει", "ευ", "αυ",
"Α", "Β", "Γ", "Δ", "Ε", "Ζ", "Η", "Θ", "Ι", "Κ", "Λ", "Μ", "Ν", "Ξ", "Ο", "Π", "Ρ", "Σ", "Τ", "Υ", "Φ", "Χ", "Ψ", "Ω",
"α", "β", "γ", "δ", "ε", "ζ", "η", "θ","ι", "κ", "λ", "μ", "ν", "ξ", "ο", "π", "ρ", "σ", "τ", "υ", "φ", "χ", "ψ", "ω",
"¶", "ά", "Έ", "έ", "Ή", "ή", "Ί", "ί", "Ό", "ό", "Ύ", "ύ", "Ώ", "ώ", "ΐ", "ΰ", "ϊ", "ϋ", "ς");
$greekreplace = array ("ai", "oi", "ou", "ei", "ef", "af",
"A", "V", "G", "D", "E", "Z", "I", "Th", "I", "K", "L", "M", "N", "X", "O", "P", "R","S","T","I","F","H", "Ps", "W",
"a", "v", "g", "d", "e", "z", "i", "th", "i", "k", "l","m","n","x","o","p","r","s","t","i","f","h","ps","w",
"a","a","e","e","i","i", "i", "i", "o", "o", "i", "i", "w", "w", "i", "i", "i", "i", "s");
$greeklish = str_replace ($greekfind, $greekreplace, $text); |
Έτσι τώρα έχουμε όλο το ελληνικό κείμενο στη μεταβλητή $text και όλο το greeklish στη μεταβλητή $greeklish. Νομίζω πως είναι πολύ απλό μέχρι εδώ.
Όμως έχουμε άλλο ένα ζητούμενο. Ως εδώ έχουμε το κείμενό μας κανονικά με όλα τα html tags του. Τι γίνεται με την plain text έκδοσή του;
Θα χρειαστούμε άλλη μια λειτουργία για να αφαιρέσουμε όλα τα html tags.
Ο τρόπος για να το κάνουμε είναι ανάλογος με τη μετατροπή σε greeklish, μόνο που τώρα θα χρησιμοποιήσουμε την preg_replace, η οποία αντί να ψάχνει για strings, ψάχνει για regular expressions.
Έτσι προσθέτουμε, πάλι πριν το ?>, τον παρακάτω κώδικα (τον οποίο μπορείτε να βρείτε σε 100δες εφαρμογές php και φυσικά τον πήρα από μια από αυτές):
| Κώδικας: |
$search = array ("'<script[^>]*?>.*?</script>'si", // Strip out javascript
"'<[/!]*?[^<>]*?>'si", // Strip out HTML tags
"'([rn])[s]+'", // Strip out white space
"'&(quot|#34);'i", // Replace HTML entities
"'&(amp|#38);'i",
"'&(lt|#60);'i",
"'&(gt|#62);'i",
"'&(nbsp|#160);'i",
"'&(iexcl|#161);'i",
"'&(cent|#162);'i",
"'&(pound|#163);'i",
"'&(copy|#169);'i",
"'(d+);'e"); // evaluate as php
$replace = array ("",
"",
"\1",
"\"",
"&",
"<",
">",
" ",
chr(161),
chr(162),
chr(163),
chr(169),
"chr(\1)");
$nohtmlgreeklish = preg_replace($search, $replace, $greeklish);
$nohtml = preg_replace($search, $replace, $text); |
Τώρα έχουμε άλλες δύο μεταβλητές:
την $nohtmlgreeklish που έχει το greeklish κείμενο σε plain text και
την $nohtml που έχει το ελληνικό κείμενο σε plain text.
Και φτάνουμε στο τελευταίο κομμάτι του κώδικα που είναι η δημιουργία και η αποστολή του email.
Όπως είπαμε θέλουμε να στείλουμε ένα Multipart email, το οποίο θα περιέχει και την plain text και την html έκδοση του κειμένου, και ο κάθε email client θα αποφασίζει τι θα εμφανίσει αυτόματα.
Πάλι λοιπόν πριν το ?> τοποθετούμε τον παρακάτω κώδικα:
| Κώδικας: |
$semi_rand = md5(time());
$Email_boundary = "==Multipart_Boundary_x{$semi_rand}x";
$Email_body_text = "Ελληνικά\n\n$nohtml\n\n\nGreeklish\n\n$nohtmlgreeklish";
$Email_body_html = "<b>Ελληνικά</b><br><Br>".nl2br ($text)."<br><BR><Br><b>Greeklish</b><br><Br>".nl2br($greeklish);
$Email_body = 'Content-Transfer-Encoding: 7bit' .
"\r\n\r\n$nohtmlgreeklish\r\n\r\n" .
'--' . $Email_boundary . "\r\n" .
'Content-Type: text/plain;
charset="iso-8859-7"' . "\r\n" .
'Content-Transfer-Encoding: 7bit' .
"\r\n" .
"\r\n" .
$Email_body_text . "\r\n" .
"\r\n" .
'--' . $Email_boundary . "\r\n" .
'Content-Type: text/html; charset="iso-8859-7"' . "\r\n" .
'Content-Transfer-Encoding: 7bit' .
"\r\n\r\n" .
'<html>' . "\r\n" .
'<body>' . "\r\n" .
'<p>' . $Email_body_html . '</p>' .
"\r\n" .
'</body>' . "\r\n" .
'</html>' .
"\r\n" .
'--' . $Email_boundary . "--" ;
$Email_headers = 'From: ' . "$from\r\n" .
'Reply-To: ' . "$from\r\n" .
'MIME-Version: 1.0' . "\r\n" .
'X-Mailer: PHP/' . phpversion() . "\r\n" .
'Content-Type: multipart/alternative; boundary="' . $Email_boundary . "\";\r\n";
if ($error ==0){
if (mail($Email_to, $Email_subject, $Email_body, $Email_headers)) {
?> <b>Το μήνυμα στάλθηκε επιτυχώς</b><?
}
}
|
Τα πράγματα φαίνονται μπερδεμένα, όμως δεν είναι.
Για να στείλουμε το email χρησιμοποιούμε την mail () στην οποία δίνουμε 4 παραμέτρους: τον παραλήπτη, το θέμα, το περιεχόμενο του μηνύματος και τους headers.
Για να μπορέσουμε να αναλύσουμε πως δουλεύει θα προσθέσουμε τα παρακάτω στο Html κομάτι του script μας, πριν από το .
| Κώδικας: |
<p>Greeklish:</p>
<p>
<textarea readonly name="textarea" rows="10" cols="50"><?=$greeklish?>
</textarea>
</p>
<p>Ελληνικά χωρίς html :</p>
<p>
<textarea readonly name="textarea2" rows="10" cols="50"><?=$nohtml?>
</textarea>
</p>
<p>Greeklish χωρίς html:</p>
<p>
<textarea readonly name="textarea3" rows="10" cols="50"><?=$nohtmlgreeklish?>
</textarea>
</p>
<p>Message Body:</p>
<p>
<textarea readonly name="textarea4" rows="10" cols="50"><?=$Email_body?>
</textarea>
</p>
<p>Message Headers: </p>
<p>
<textarea readonly name="textarea5" rows="10" cols="50"><?=$Email_headers?>
</textarea>
</p>
<p>&</p> |
Έτσι δοκιμάζοντας να στείλουμε ένα email με το κείμενο test, θα δούμε κάποιες επιπλέον πληροφορίες, τα headers και το περιεχόμενο του mail όπως το στέλουμε. (επίσης για ευκολία έχω προσθέσει σε text area όλες τις μορφές του κειμένου που θα φύγει).
Βλέπουμε στα headers τα παρακάτω:
| Παράθεση: |
From: χχχχ@χχχχ.com
Reply-To: χχχχχχ@χχχχχ.com
MIME-Version: 1.0
X-Mailer: PHP/4.3.11
Content-Type: multipart/alternative; boundary="==Multipart_Boundary_xfb728be978e3933c9478450b61e21b72x"; |
Η έκδοση MIME χρειάζεται για να ξέρει ο email client πως θα διαχειριστεί τα δεδομένα. Επίσης του ορίζουμε ότι το περιεχόμενο είναι τύπου multipart/alternative, δηλαδή εναλακτικές εκδόσεις του content.
Τέλος ορίζουμε το boundary, το οποίο είναι ίσως και το πιο βασικό κομάτι.
Ουσιαστικά είναι ένα String το οποίο όταν το βλέπει ο client καταλαβαίνει ότι έχει αρχίσει ένα άλλο part του content μας. Μπορεί να είναι οποιοδήποτε string, όμως για να είμαστε σίγουροι ότι δεν θα εισαχθεί τυχαία στο κείμενο του email μπερδεύοντας έτσι τον client, βάζουμε κάτι που είναι αδύνατον να το πετύχει κανείς στην τύχη.
Στο συγκεκριμένο παράδειγμα χρησιμοποιώ το τρέχον unix timestamp σε md5:
| Κώδικας: |
$semi_rand = md5(time());
$Email_boundary = "==Multipart_Boundary_x{$semi_rand}x"; |
Πάμε τώρα να δούμε και το message body.
Σε κάθε μέρος του body ορίζουμε και κάποια headers για το συγκεκριμένο κομάτι. Στην αρχή το:
| Παράθεση: |
Content-Transfer-Encoding: 7bit
test |
το οποίο δεν περιέχει το boundary string, χρησιμοποιείται από τους email clients που δεν υποστηρίζουν multipart μηνύματα. Ότι βάλουμε σε αυτό το κομάτι θα εμφανίζεται μόνο από αυτούς. Για αυτό εμείς εμφανίζουμε το greeklish κείμενο χωρίς html tags, μέσα από τις γραμμές:
| Κώδικας: |
$Email_body = 'Content-Transfer-Encoding: 7bit' .
"\r\n\r\n$nohtmlgreeklish\r\n\r\n" . |
Στη συνέχεια του body θα δούμε τα παρακάτω:
| Παράθεση: |
| --==Multipart_Boundary_xfb728be978e3933c9478450b61e21b72x |
Βλέπουμε ότι χρησιμοποιούμε το boundary string, έχοντας πάντα ως πρόθεμα το -- . Έτσι ορίζουμε ότι έχουμε ένα νέο part του body. Αμέσως από κάτω ορίζουμε τα headers:
| Παράθεση: |
Content-Type: text/plain;
charset="iso-8859-7"
Content-Transfer-Encoding: 7bit |
Λέμε λοιπόν ότι έχουμε το plain text με κωδικοποίηση iso-8859-7 (Ελληνικά), και παρακάτω τοποθετούμε το κείμενό μας σε Ελληνικά και greeklish.
| Παράθεση: |
Ελληνικά
test
Greeklish
test |
Αντίστοιχα παρακάτω βάζουμε το html part:
| Παράθεση: |
--==Multipart_Boundary_xfb728be978e3933c9478450b61e21b72x
Content-Type: text/html; charset="iso-8859-7"
Content-Transfer-Encoding: 7bit
<html>
<p>Ελληνικά
test
Greeklish
test</p>
</html> |
Τέλος πρέπει να πούμε που τελειώνει το τελευταίο part του μηνύματος μας. Αυτό γίνεται εισάγωντας άλλη μια φορά το boundary string, αυτή τη φορά όμως μετά από αυτό βάζουμε τα -- , σαν να κλείνουμε ένα tag:
| Παράθεση: |
| --==Multipart_Boundary_xfb728be978e3933c9478450b61e21b72x-- |
Το script αυτό με λίγη τροποποίηση μπορείτε να το αξιοποιησετε με διάφορους τρόπους, με λίγη φαντασία πάντα.
Ολοκληρωμένο το αρχείο το τοποθετώ και σαν attachment.
| Description: |
|
 Download |
| Filename: |
greeklish.zip |
| Filesize: |
2.14 KB |
| Downloaded: |
249 Time(s) |
_________________ [ Ικαρία | mrpc's blog | Παραπληροφόρηση ] |
|