PHP: Sending Email with Cyrillic (Ukrainian text) - php

Problem with sending Cyrillic Email with PHP.
My side:
Server IIS - Database MsSQL - email server: Exchange 2010 /communication via PHP EWS/
Reciever is UA Goverment owned company with their specific software for receiving emails. It is working with MS Outlook /manually send/.
I tried send it as text /not html/ or i tried PHP Mailer, i also already tried with C# /all are not working with this specific company /on gmail or hotmail it's working fine//.
$ews = new ExchangeWebServices($server, $username, $password);
$msg = new EWSType_MessageType();
$toAddresses = array();
$toAddresses[0] = new EWSType_EmailAddressType();
$toAddresses[0]->EmailAddress =;
$toAddresses[0]->Name =;
$msg->ToRecipients = $toAddresses;
$fromAddress = new EWSType_EmailAddressType();
$fromAddress->EmailAddress =;
$fromAddress->Name =;
$msg->From = new EWSType_SingleRecipientType();
$msg->From->Mailbox = $fromAddress;
$msg->Subject = "Test";
$msg->Body = new EWSType_BodyType();
$msg->Body->BodyType = 'HTML'; //Text HTML
$msg->Body->_ = $UAText;
$msgRequest = new EWSType_CreateItemType();
$msgRequest->Items = new EWSType_NonEmptyArrayOfAllItemsType();
$msgRequest->Items->Message = $msg;
$msgRequest->MessageDisposition = 'SendAndSaveCopy';
$msgRequest->MessageDispositionSpecified = true;
$response = $ews->CreateItem($msgRequest);
var_dump($response);
Thank You,

If its working with an normal Outlook client, however not with your solution my first check would be to compare the header from two example emails (one from outlook and one from your solution). I think that the content-type is set correctly with Outlook however not with your solution.
So you might wish to set the content encoding to UTF-8 in your solution. So I assume the content inside $UAText is some HTML stuff. You might therefore wish to flag that part as UTF-8 via:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
and see how it works.
Additional you might wish to set the encoding directly inside your code via:
$ews = new ExchangeWebServices($host, $user, $password, ExchangeWebServices::VERSION_2007_SP1);
$msg = new EWSType_MessageType();
$msg->MimeContent = new EWSType_MimeContentType();
$msg->MimeContent->_ = base64_encode("Mime-Version: 1.0\r\n"
. "From: michael#contoso.com\r\n"
. "To: amy#contoso.com\r\n"
. "Subject: nothing\r\n"
. "Date: Tue, 15 Feb 2011 22:06:21 -0000\r\n"
. "Message-ID: <{0}>\r\n"
. "X-Experimental: some value\r\n"
. "\r\n"
. "I have nothing further to say.\r\n");
$msg->MimeContent->CharacterSet = 'UTF-8';
Note: Here is a good starting point regarding the content-type encoding option. You also might wish to check the official Microsoft howto here.

Related

Laminas-mail. send as UFT8

I work with Laminas (former Zendframework 3). I want to send a mail with Laminas-Mail. I dont know how to change the Content-Type. Currently it is Content-Type: text/html but I want to send UTF8 mails, so therefore I want to use Content-Type: text/html; charset=utf-8.
I tried to change $html->type but I failed.
use Laminas\Mail;
use Laminas\Mail\Transport\Smtp as SmtpTransport;
use Laminas\Mail\Transport\SmtpOptions;
use Laminas\Mime\Message as MimeMessage;
use Laminas\Mime\Part as MimePart;
# ...
# much code
# ...
// Produce HTML
$bodyHtml = $this->viewRenderer->render('mymodule/email/email1');
$html = new MimePart($bodyHtml);
$html->type = "text/html; charset=utf-8"; #Seems not to work
$body = new MimeMessage();
$body->addPart($html);
$mail = new Mail\Message();
$mail->setEncoding('UTF-8');
$mail->setBody($body);
$mail->setFrom('bobafit#example.com','Boba Fit');
$mail->addTo('bobafit#example.com','Boba Fit');
$mail->setSubject('Thank you for reading my Question');
// Setup SMTP transport
$transport = new SmtpTransport();
$options = new SmtpOptions($this->config['smtp']);
$transport->setOptions($options);
$transport->send($mail);
Please check the official Dok:
https://docs.laminas.dev/laminas-mail/message/attachments/
Type and charset are defined separatly.
You are probably looking for something like that:
$html = new MimePart($htmlMarkup);
$html->type = Mime::TYPE_HTML;
$html->charset = 'utf-8';

Outlook 2013 shows "not supported calendar message.ics", but Gmail, Outlook 2007 are fine

My PHP program generate a ics file, it works previously for most email clients, but I got an error for Outlook 2013, the filename of the ics file, named "not supported calendar message.ics", but when double click to open it shows the content correctly. I search the internet but cannot find any reason. Could anyone help in this situation?
Here is the generated ics example:
BEGIN:VCALENDAR
PRODID:-//MY COMPANY NAME//System iCal Generator//EN
VERSION:2.0
METHOD:REQUEST
BEGIN:VEVENT
DTSTART:20170314T180000Z
DTEND:20170314T210000Z
DTSTAMP:20170217T161443Z
ORGANIZER;CN=name of event here:mailto:email#demoemailaddress.com
ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE:customer#demoemailaddress.com
SUMMARY:Test website for evet
DESCRIPTION:xyz
LOCATION:tbc
SEQUENCE:0
UID:ICAL_128_NTG47K1VYJ#www.companydomain.com
END:VEVENT
END:VCALENDAR
Thanks for the help!
An old one, but I'll go ahead and answer since it came up in my searches.
I had some problems with the newer Outlook being very particular about whether or not it would accept my event without weird issues...and a lot of it actually came down to proper line-endings. I had to make sure \r\n was used within the VCalendar code, but in PHP on Unix, I had to make sure that \n was used for the new lines in the actual e-mail. Here is some code that I have working with the latest Outlook, which uses string arrays so that the line-endings of each section is explicit and obvious:
Please note that this code does nothing to prevent header-injection.
Please use responsibly :)
<?php
date_default_timezone_set('America/New_York');
//CONFIGURE HERE
$fromName = "John Doe";
$fromEmail = "john.doe#example.com";
$toName = "Your Name";
$toEmail = isset($_GET['to']) ? $_GET['to'] : 'yourname#example.com';
$start = new DateTime('2017-08-15 15:00');
$end = new DateTime('2017-08-15 16:00');
$summary = "Hello World Event";
//END CONFIGURATION
$uid = "0123456789";
$headers = array();
$boundary = "_CAL_" . uniqid("B",true) . "_B_";
$headers[] = "MIME-Version: 1.0";
$headers[] = "Content-Type: multipart/alternative; boundary=\"".$boundary."\"";
$headers[] = "To: \"{$toName}\" <{$toEmail}>";
$headers[] = "From: \"{$fromName}\" <{$fromEmail}>";
$calendarLines = array(
"BEGIN:VCALENDAR",
"METHOD:REQUEST",
"PRODID:-//PHP//MeetingRequest//EN",
"VERSION:2.0",
"BEGIN:VEVENT",
"ORGANIZER;CN={$fromName}:MAILTO:{$fromEmail}",
"ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN={$toName}:MAILTO:{$toEmail}",
"DESCRIPTION:{$summary}",
"SUMMARY:{$summary}",
"DTSTART:".$start->setTimezone(new DateTimeZone('UTC'))->format('Ymd\THis\Z'),
"DTEND:".$end->setTimezone(new DateTimeZone('UTC'))->format('Ymd\THis\Z'),
"UID:{$uid}",
"CLASS:PUBLIC",
"PRIORITY:5",
"DTSTAMP:".gmdate('Ymd\THis\Z'),
"TRANSP:OPAQUE",
"STATUS:CONFIRMED",
"SEQUENCE:0",
"LOCATION:123 Any Street",
"BEGIN:VALARM",
"ACTION:DISPLAY",
"DESCRIPTION:REMINDER",
"TRIGGER;RELATED=START:-PT15M",
"END:VALARM",
"END:VEVENT",
"END:VCALENDAR"
);
$calendarBase64 = base64_encode(implode("\r\n",$calendarLines));
//ensure we don't have lines longer than 70 characters for older computers:
$calendarResult = wordwrap($calendarBase64,68,"\n",true);
$emailLines = array(
"--{$boundary}",
"Content-Type: text/html; charset=\"iso - 8859 - 1\"",
"Content-Transfer-Encoding: quoted-printable",
"",
"<html><body>",
"<h1>Hello World</h1>",
"<p>This is a calendar event test</p>",
"</body></html>",
"",
"--{$boundary}",
"Content-Type: text/calendar; charset=\"utf - 8\"; method=REQUEST",
"Content-Transfer-Encoding: base64",
"",
$calendarResult,
"",
"--{$boundary}--"
);
$emailContent = implode("\n",$emailLines);
$headersResult = implode("\n",$headers);
mail($toEmail, $summary, $emailContent, $headersResult );
echo("<pre>".htmlentities($headersResult)."\n\n".htmlentities($emailContent)."</pre>");
echo("<br /><br />");
echo("<pre>".base64_decode($calendarResult)."</pre>");
Please feel free to add comments on applications/sites that this does or doesn't work with. Thx.
Try to create an appointment in Outlook and then save it using the .ics format. See How To Save A Selected Appointment As Ics File In Outlook? for more informaiton. Then you can open the saved file and compare its content with a generated programmatically one.
Testing your icalendar feed with the icalendar validator at https://icalendar.org/validator.html it found the ATTENDEE line is longer than 75 characters, which is the maximum line size for an icalendar file. Perhaps that is why it is not working?

Why it takes so long to send multiple emails with Sendgrid?

I have a sport betting tips website and on every tip that i publish i send an email to every user (about 700 users in total) with SendGrid. The problem comes with the delivery time. The email is delayed even half an hour from the time of send.
Does anyone know why and how could i fix it?
I am sending it with SMTP.
Here is some of my code:
$catre = array();
$subiect = $mailPronostic['subiect'];
$titlu = $mailPronostic['titlu'];
$text = $mailPronostic['text'];
$data = new DateTime($this->_dataPronostic);
foreach($users as $user){
array_push($catre, $user->_emailUser);
}
$data = urlencode($data->format("d-m-Y H:i"));
$echipe = urlencode($this->_gazdaPronostic." vs ".$this->_oaspetePronostic);
$pronostic = urlencode($predictii[$this->_textPronostic]);
$cota = $this->_cotaPronostic;
$mesaj = file_get_contents("http://plivetips.com/mailFiles/mailPronostic.php?text=".urlencode($text)."&titlu=".urlencode($titlu)."&data=$data&echipe=$echipe&pronostic=$pronostic&cota=$cota");
//return mail(null, $subiect, $mesaj, $header);
$from = array('staff#plivetips.com' => 'PLIVEtips');
$to = $catre;
$subject = "PLIVEtips Tip";
$username = 'user';
$password = 'pass';
$transport = Swift_SmtpTransport::newInstance('smtp.sendgrid.net', 587);
$transport->setUsername($username);
$transport->setPassword($password);
$swift = Swift_Mailer::newInstance($transport);
$message = new Swift_Message($subject);
$message->setFrom($from);
$message->setBody($mesaj, 'text/html');
$numSent = 0;
foreach ($to as $address => $name)
{
if (is_int($address)) {
$message->setTo($name);
} else {
$message->setTo(array($address => $name));
}
$numSent += $swift->send($message, $failures);
}
Thx.
how long does the script take to run? I have a feeling the script is taking a long time. If that's the case, I think it is because you are opening a connection for each message.
With SendGrid, you can send a message to 1000 recipients with one connection by using the X-SMTPAPI header to define the recipients. The easiest way to do this to use the official sendgrid-php library and use the setTos method.
Recipients added to the X-SMTPAPI header will each be sent a unique email. Basically SendGrid's servers will perform a mail merge. It doesn't look like your email content varies with each user, but if it does, then you may use substitution tags in the header to specify custom data per recipient.
If you don't want to use sendgrid-php, you can see how to build the header in this example.

Has anyone created an ics iCalendar generator function that works with Google Calendar?

I'm trying to generate an .ics file that imports successfully into Google calendar. Google Calendar is proving especially difficult (I've got Outlook and Apple iCal working perfectly).
Does anyone have a php function or class which creates the right headers and inserts events that's been proven to work with Google calendar?
I also see this is an older post, but with no accepted answer.
Recently, I needed to implement ical generation into my web app... but mine also required recurring events with a given formula. For this, I used a combination of the following packages:
For ical generation: https://github.com/markuspoerschke/iCal
For recurring events: https://github.com/simshaun/recurr
I use recurr to generate a list of dates based on a recurrence formula:
public function generate_dates_array(\DateTime $end_date = null) : array
{
if(! $end_date) {
$end_date = new \DateTime('midnight');
}
$rule = new \Recurr\Rule($this->recurrence_rule, $this->created_at->setTime(0,0));
$rule->setUntil($end_date);
$transformer = new ArrayTransformer();
$dates = $transformer->transform($rule);
$dateArray = [];
foreach($dates as $date) {
$dateArray[] = $date->getStart();
}
return $dateArray;
}
Then setup my calendar:
$vCalendar = new \Eluceo\iCal\Component\Calendar('YourUrlHere');
$vCalendar->setName('YOUR NAME HERE');
$vCalendar->setDescription('YOUR DESCRIPTION HERE');
Then loop over those dates adding events to my calendar object... making sure to adjust my times to UTC from the user's chosen timezone.
$today = new Carbon();
$end_date = $today->addMonth();
foreach($events as $event) {
$dates = $event->generate_dates_array($end_date); // function shown in above code snippet
$duration = $event->duration ? $event->duration : 30;
// Each Occurrence for event
foreach($dates as $date) {
$vEvent = new \Eluceo\iCal\Component\Event();
$date_string = "{$date->format('Y-m-d')} {$event->time}";
$start_time = new Carbon($date_string, $user->time_zone);
$start_time->setTimezone('UTC');
$vEvent->setDtStart($start_time);
$end_time = new Carbon($date_string, $user->time_zone);
$end_time = $end_time->addMinutes($duration);
$end_time->setTimezone('UTC');
$vEvent->setDtEnd($end_time);
$vEvent->setNoTime(false);
$vEvent->setSummary($event->name);
$vEvent->setDescription("$event->description");
$vCalendar->addComponent($vEvent);
}
}
After everything is setup properly, I output the calendar. This means I can use the URL that generates this file to import the calendar into Google Calendar (or any other calendar program) and it'll ping it daily for updates. (URL must be publicly accessibly, which required I used a guid as the identifier instead of user_id, by the way)
header('Content-Type: text/calendar; charset=utf-8');
echo $vCalendar->render();
Hopefully this helps anyone else landing here!
This is an old one, and the only answer wasn't accepted, so not sure if the below code fixed your issue. However, I came across this in my own searches to try to fix a bug I had, and now that I have a solution, I figured I would share it. The below code has been tested with the latest Outlook and with Gmail.
With outlook what was causing my bug was that I was using \n instead of \r\n for the event details. So, as you'll see below, I use \r\n for the event and \n for everythign else so that PHP processes it correctly. Perhaps a similar problem was causing the issues with gmail?
Warning, this code does nothing to prevent header injection, please
use responsibly ;-)
<?php
date_default_timezone_set('America/New_York');
//CONFIGURE HERE
$fromName = "John Doe";
$fromEmail = "john.doe#example.com";
$toName = "Your Name";
$toEmail = 'yourname#example.com';
$start = new DateTime('2017-08-15 15:00');
$end = new DateTime('2017-08-15 16:00');
$summary = "Hello World Event";
//END CONFIGURATION
$uid = "0123456789";
$headers = array();
$boundary = "_CAL_" . uniqid("B",true) . "_B_";
$headers[] = "MIME-Version: 1.0";
$headers[] = "Content-Type: multipart/alternative; boundary=\"".$boundary."\"";
$headers[] = "To: \"{$toName}\" <{$toEmail}>";
$headers[] = "From: \"{$fromName}\" <{$fromEmail}>";
$calendarLines = array(
"BEGIN:VCALENDAR",
"METHOD:REQUEST",
"PRODID:-//PHP//MeetingRequest//EN",
"VERSION:2.0",
"BEGIN:VEVENT",
"ORGANIZER;CN={$fromName}:MAILTO:{$fromEmail}",
"ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN={$toName}:MAILTO:{$toEmail}",
"DESCRIPTION:{$summary}",
"SUMMARY:{$summary}",
"DTSTART:".$start->setTimezone(new DateTimeZone('UTC'))->format('Ymd\THis\Z'),
"DTEND:".$end->setTimezone(new DateTimeZone('UTC'))->format('Ymd\THis\Z'),
"UID:{$uid}",
"CLASS:PUBLIC",
"PRIORITY:5",
"DTSTAMP:".gmdate('Ymd\THis\Z'),
"TRANSP:OPAQUE",
"STATUS:CONFIRMED",
"SEQUENCE:0",
"LOCATION:123 Any Street",
"BEGIN:VALARM",
"ACTION:DISPLAY",
"DESCRIPTION:REMINDER",
"TRIGGER;RELATED=START:-PT15M",
"END:VALARM",
"END:VEVENT",
"END:VCALENDAR"
);
$calendarBase64 = base64_encode(implode("\r\n",$calendarLines));
//ensure we don't have lines longer than 70 characters for older computers:
$calendarResult = wordwrap($calendarBase64,68,"\n",true);
$emailLines = array(
"--{$boundary}",
"Content-Type: text/html; charset=\"iso - 8859 - 1\"",
"Content-Transfer-Encoding: quoted-printable",
"",
"<html><body>",
"<h1>Hello World</h1>",
"<p>This is a calendar event test</p>",
"</body></html>",
"",
"--{$boundary}",
"Content-Type: text/calendar; charset=\"utf - 8\"; method=REQUEST",
"Content-Transfer-Encoding: base64",
"",
$calendarResult,
"",
"--{$boundary}--"
);
$emailContent = implode("\n",$emailLines);
$headersResult = implode("\n",$headers);
mail($toEmail, $summary, $emailContent, $headersResult );
echo("<pre>".htmlentities($headersResult)."\n\n".htmlentities($emailContent)."</pre>");
echo("<br /><br />");
echo("<pre>".base64_decode($calendarResult)."</pre>");
I have done a similar thing but just created a URL instead of an iCal.
Check out https://support.google.com/calendar/answer/3033039
Fill out the form and generate HTML then in the php file I was using to create the ical i just created a separate thing to replace the details with variables.
EG:
if($calType === "iCal"){
//set correct content-type-header
header('Content-Disposition: attachment; filename=AddToCalendar.ics');
header('Content-Type: text/calendar; charset=utf-8');
$desc = str_replace("\n", '\n', $desc);
$desc = str_replace(array("\r","\n","\r"), '', $desc);
$ical = "BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Smartershows.com//TheBatteryShow//EN
X-WR-CALNAME;CHARSET=utf-8:".$subj."
METHOD:PUBLISH
X-MS-OLK-FORCEINSPECTOROPEN:TRUE
BEGIN:VEVENT
SUMMARY;CHARSET=utf-8:".$subj."
LOCATION;CHARSET=utf-8:".$loc."
URL:".$url."
UID:30fc985de98ed0dabfeb13722e3c82259fcd33e3
DESCRIPTION:".$desc."
DTSTART:".$sDate."T".$sTime."
DTEND:".$eDate."T".$eTime."
END:VEVENT
END:VCALENDAR";
return $ical;
exit;
}else if($calType === "gCal"){
$href = "http://www.google.com/calendar/event?";
$href .= "action=TEMPLATE";
$href .= "&text=".urlencode($subj);
$href .= "&dates=".$sDate."T".$sTime."/".$eDate."T".$eTime;
$href .= "&details=".urlencode($desc);
$href .= "&location=".urlencode($loc);
$href .= "&trp=false";
$href .= "&sprop=".urlencode($subj);
$href .= "&sprop=name:".urlencode($url);
return '<strong>Download for Gmail</strong>';
}
So the first block in the if is making the ical and the second is taking the same info to build a url that google will take and populate a calendar page.
The downside of this though is that you can only put basic things into the description...not a lot of fancy html or anything...unless you htmlencode everything i guess but even then im not sure what the character limit of a url is...
Hotmail and Yahoo mail can both populate calendars this way as well but unfortunately neither have a nice tool (that i can find) that generates a link beforehand that you can use.
Hope this helps!

Send Mail from raw body for testing purposes

I am developing a PHP application that needs to retrieve arbitrary emails from an email server. Then, the message is completely parsed and stored in a database.
Of course, I have to do a lot of tests as this task is not really trivial with all that different mail formats under the sun. Therefore I started to "collect" emails from certain clients and with different contents.
I would like to have a script so that I can send out those emails automatically to my application to test the mail handling.
Therefore, I need a way to send the raw emails - so that the structure is exactly the same as they would come from the respective client. I have the emails stored as .eml files.
Does somebody know how to send emails by supplying the raw body?
Edit:
To be more specific: I am searching for a way to send out multipart emails by using their source code. For example I would like to be able to use something like that (an email with plain and HTML part, HTML part has one inline attachment).
--Apple-Mail-159-396126150
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
The plain text email!
--=20
=20
=20
--Apple-Mail-159-396126150
Content-Type: multipart/related;
type="text/html";
boundary=Apple-Mail-160-396126150
--Apple-Mail-160-396126150
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html;
charset=iso-8859-1
<html><head>
<title>Daisies</title>=20
</head><body style=3D"background-attachment: initial; background-origin: =
initial; background-image: =
url(cid:4BFF075A-09D1-4118-9AE5-2DA8295BDF33/bg_pattern.jpg); =
background-position: 50% 0px; ">
[ - snip - the html email content ]
</body></html>=
--Apple-Mail-160-396126150
Content-Transfer-Encoding: base64
Content-Disposition: inline;
filename=bg_pattern.jpg
Content-Type: image/jpg;
x-apple-mail-type=stationery;
name="bg_pattern.jpg"
Content-Id: <4BFF075A-09D1-4118-9AE5-2DA8295BDF33/tbg.jpg>
/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAASAAA/+IFOElDQ19QUk9GSUxFAAEB
[ - snip - the image content ]
nU4IGsoTr47IczxmCMvPypi6XZOWKYz/AB42mcaD/9k=
--Apple-Mail-159-396126150--
Using PHPMailer, you can set the body of a message directly:
$mail->Body = 'the contents of one of your .eml files here'
If your mails contain any mime attachments, this will most likely not work properly, as some of the MIME stuff has to go into the mail's headers. You'd have to massage the .eml to extract those particular headers and add them to the PHPMailer mail as a customheader
You could just use the telnet program to send those emails:
$ telnet <host> <port> // execute telnet
HELO my.domain.com // enter HELO command
MAIL FROM: sender#address.com // enter MAIL FROM command
RCPT TO: recipient#address.com // enter RCPT TO command
<past here, without adding a newline> // enter the raw content of the message
[ctrl]+d // hit [ctrl] and d simultaneously to end the message
If you really want to do this in PHP, you can use fsockopen() or stream_socket_client() family. Basically you do the same thing: talking to the mailserver directly.
// open connection
$stream = #stream_socket_client($host . ':' . $port);
// write HELO command
fwrite($stream, "HELO my.domain.com\r\n");
// read response
$data = '';
while (!feof($stream)) {
$data += fgets($stream, 1024);
}
// repeat for other steps
// ...
// close connection
fclose($stream);
You can just use the build in PHP function mail for it. The body part doesnt have to be just text, it can also contain mixed part data.
Keep in mind that this is a proof of concept. The sendEmlFile function could use some more checking, like "Does the file exists" and "Does it have a boundry set". As you mentioned it is for testing/development, I have not included it.
<?php
function sendmail($body,$subject,$to, $boundry='') {
define ("CRLF", "\r\n");
//basic settings
$from = "Example mail<info#example.com>";
//define headers
$sHeaders = "From: ".$from.CRLF;
$sHeaders .= "X-Mailer: PHP/".phpversion().CRLF;
$sHeaders .= "MIME-Version: 1.0".CRLF;
//if you supply a boundry, it will be send with your own data
//else it will be send as regular html email
if (strlen($boundry)>0)
$sHeaders .= "Content-Type: multipart/mixed; boundary=\"".$boundry."\"".CRLF;
else
{
$sHeaders .= "Content-type: text/html;".CRLF."\tcharset=\"iso-8859-1\"".CRLF;
$sHeaders .= "Content-Transfer-Encoding: 7bit".CRLF."Content-Disposition: inline";
}
mail($to,$subject,$body,$sHeaders);
}
function sendEmlFile($subject, $to, $filename) {
$body = file_get_contents($filename);
//get first line "--Apple-Mail-159-396126150"
$boundry = $str = strtok($body, "\n");
sendmail($body,$subject,$to, $boundry);
}
?>
Update:
After some more testing I found that all .eml files are different. There might be a standard, but I had tons of options when exporting to .eml. I had to use a seperate tool to create the file, because you cannot save to .eml by default using outlook.
You can download an example of the mail script. It contains two versions.
The simple version has two files, one is the index.php file that sends the test.eml file. This is just a file where i pasted in the example code you posted in your question.
The advanced version sends an email using an actual .eml file I created. it will get the required headers from the file it self. Keep in mind that this also sets the To and From part of the mail, so change it to match your own/server settings.
The advanced code works like this:
<?php
function sendEmlFile($filename) {
//define a clear line
define ("CRLF", "\r\n");
//eml content to array.
$file = file($filename);
//var to store the headers
$headers = "";
$to = "";
$subject = "";
//loop trough each line
//the first part are the headers, until you reach a white line
while(true) {
//get the first line and remove it from the file
$line = array_shift($file);
if (strlen(trim($line))==0) {
//headers are complete
break;
}
//is it the To header
if (substr(strtolower($line), 0,3)=="to:") {
$to = trim(substr($line, 3));
continue;
}
//Is it the subject header
if (substr(strtolower($line), 0,8)=="subject:") {
$subject = trim(substr($line, 8));
continue;
}
$headers .= $line . CRLF;
}
//implode the remaining content into the body and trim it, incase the headers where seperated with multiple white lines
$body = trim(implode('', $file));
//echo content for debugging
/*
echo $headers;
echo '<hr>';
echo $to;
echo '<hr>';
echo $subject;
echo '<hr>';
echo $body;
*/
//send the email
mail($to,$subject,$body,$headers);
}
//initiate a test with the test file
sendEmlFile("Test.eml");
?>
You could start here
http://www.dreamincode.net/forums/topic/36108-send-emails-using-php-smtp-direct/
I have no idea how good that code is, but it would make a starting point.
What you are doing is connecting direct to port 25 on the remote machine, as you would with telnet, and issuing smtp commands. See eg http://www.yuki-onna.co.uk/email/smtp.html for what's going on (or see Jasper N. Brouwer's answer).
Just make a quick shell script which processes a directory and call it when you want e.g. using at crontab etc
for I in ls /mydir/ do cat I | awk .. | sendmail -options
http://www.manpagez.com/man/1/awk/
You could also just talk to the mail server using the script to send the emls with a templated body..
Edit: I have added the code to Github, for ease of use by other people. https://github.com/xrobau/smtphack
I realise I am somewhat necro-answering this question, but it wasn't answered and I needed to do this myself. Here's the code!
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
class SMTPHack
{
private $phpmailer;
private $smtp;
private $from;
private $to;
/**
* #param string $from
* #param string $to
* #param string $smtphost
* #return void
*/
public function __construct(string $from, string $to, string $smtphost = 'mailrx')
{
$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->SMTPDebug = SMTP::DEBUG_SERVER;
$mail->SMTPAutoTLS = false;
$mail->Host = $smtphost;
$this->phpmailer = $mail;
$this->from = $from;
$this->to = $to;
}
/**
* #param string $helo
* #return SMTP
*/
public function getSmtp(string $helo = ''): SMTP
{
if (!$this->smtp) {
if ($helo) {
$this->phpmailer->Helo = $helo;
}
$this->phpmailer->smtpConnect();
$this->smtp = $this->phpmailer->getSMTPInstance();
$this->smtp->mail($this->from);
$this->smtp->recipient($this->to);
}
return $this->smtp;
}
/**
* #param string $data
* #param string $helo
* #param boolean $quiet
* #return void
* #throws \PHPMailer\PHPMailer\Exception
*/
public function data(string $data, string $helo = '', bool $quiet = true)
{
$smtp = $this->getSmtp($helo);
$prev = $smtp->do_debug;
if ($quiet) {
$smtp->do_debug = 0;
}
$smtp->data($data);
$smtp->do_debug = $prev;
}
}
Using that, you can simply beat PHPMailer into submission with a few simple commands:
$from = 'xrobau#example.com';
$to = 'fred#example.com';
$hack = new SMTPHack($from, $to);
$smtp = $hack->getSmtp('helo.hostname');
$errors = $smtp->getError();
// Assuming this is running in a phpunit test...
$this->assertEmpty($errors['error']);
$testemail = file_get_contents(__DIR__ . '/TestEmail.eml');
$hack->data($testemail);

Categories