I am attempting to send an HTML email from a symfony (1.4.6) task, I don't want to send the entire rendered HTML output from a particular module/action, so I am rendering a partial. That's all fine, the issue is that the partial contains CSS references.
Is there a nice 'symfonic' way of including a CSS file in an HTML email from a symfony task, when all I am doing is rendering a specific partial? Or is the only solution to build the HTML head/body manually inside the task, using file_get_contents(cssFile) to grab the CSS file and then concatenating the rendered partial?
Any thoughts would be appreciated.
I ran into the same problem in my project. Here's how I fixed it:
To keep the CSS separate but get it inline before sending the email, we use Emogrifier. Download the source code and put it into %sf_lib_dir%/vendor/emogrifier.
Create a myMailer class that extends sfMailer. Mine is below. There are a few separate functions, but the key function is composeAndSendPartial, which takes a partial name (as a string), inserts all the CSS inline, and sends it. I tried to remove all code that's specific to my project, but I may have left some in. Let me know if it doesn't work for you or if you have any questions.
In factories.yml, set the mailer: to myMailer
myMailer.class.php:
<?php
class myMailer extends sfMailer
{
/**
* Creates a new message with 2 bodies:
* * 1 with $body and MIME type text/html.
* * 1 with $body and tags stripped with MIME type text/plain. Stipped <br/>, </p>, and </div> tags and replaced with \n
*
* #param string|array $from The from address
* #param string|array $to The recipient(s)
* #param string $subject The subject
* #param string $body The body
*
* #return Swift_Message A Swift_Message instance
*/
public function composeAndSendHtml($from, $to, $subject, $body)
{
return $this->send($this->composeHtml($from, $to, $subject, $body));
}
/**
* Sends a message using composeHtml.
*
* #param string|array $from The from address
* #param string|array $to The recipient(s)
* #param string $subject The subject
* #param string $body The body
*
* #return int The number of sent emails
*/
public function composeHtml($from = null, $to = null, $subject = null, $body = null)
{
return Swift_Message::newInstance()
->setFrom($from)
->setTo($to)
->setSubject($subject)
->addPart($this->createPlainTextBody($body), 'text/plain')
->addPart($body, 'text/html');
}
/**
* Attempts to create a plaintext message with all html tags stripped out and new lines inserted as necessary
* #param $body
* #return $body
*/
public function createPlainTextBody($body)
{
$body = preg_replace('/\<br\s*\/?\>/i', "\n", $body); //replace all <br/s> with new lines
$body = preg_replace('/\<\/p\s*\>/i', "</p>\n\n", $body); //append 2 newlines to the end of each </p>
$body = preg_replace('/\<\/div\s*\>/i', "</div>\n\n", $body); //append 2 newlines to the end of each </div>
$body = strip_tags($body); //strip all tags from the body
return $body;
}
/**
* Composes and sends an email with a body from rendering $partial with $parameters
* #param string $from
* #param string $to
* #param string $subject
* #param string $partial the partial as a string. Feel free to change the default module name below
* #param array $parameters Parameters for the partial
* #param array $globalStylesheets The stylesheets that are included globally (usually global.css, maybe others)
*/
public function composeAndSendPartial($from, $to, $subject, $partial, $parameters = array(), $globalStylesheets = array())
{
require_once(sfConfig::get('sf_lib_dir') . '/vendor/emogrifier/emogrifier.php');
$context = sfContext::getInstance();
$response = $context->getResponse();
$originalStylesheets = $response->getStylesheets();
if (false !== $sep = strpos($partial, '/'))
{
$moduleName = substr($partial, 0, $sep);
$templateName = '_' . substr($partial, $sep + 1);
}
else
{
$moduleName = 'email';
$templateName = '_' . $partial;
}
sfConfig::set('sf_is_email', true);
$view = new sfPHPView($context, $moduleName, $templateName, ''); #not sure what 4th parameter does
$view->getAttributeHolder()->add($parameters);
$view->setDecorator(true);
$view->setDecoratorTemplate('email.php');
$html = $view->render();
sfConfig::set('sf_is_email', false);
$emailStylesheets = array_keys(array_diff_key($response->getStylesheets(), $originalStylesheets));
$css = '';
foreach($globalStylesheets as $globalStylesheet)
{
$css .= file_get_contents(sfConfig::get('sf_web_dir') . '/css/' . $globalStylesheet . '.css');
}
foreach ($emailStylesheets as $stylesheet)
{
$css .= file_get_contents(sfConfig::get('sf_web_dir') . '/css/' . $stylesheet . '.css');
$response->removeStylesheet($stylesheet);
}
$emog = new Emogrifier($html, $css);
$body = $emog->emogrify();
$this->composeAndSendHtml($from, $to, $subject, $body);
}
}
Related
I am getting the above error upon submitting my registration form. I'm not quite sure what I'm overlooking. If I could get some direction and help on this, that would be wonderful. Thanks!
858. private function mailPassthru($to, $subject, $body, $header, $params)
859. {
860. //Check overloading of mail function to avoid double-encoding
861. if (ini_get('mbstring.func_overload') & 1) { // phpcs:ignore
PHPCompatibility.IniDirectives.RemovedIniDirectives.mbstring_func_overloadDeprecated
862. $subject = $this->secureHeader($subject);
863. } else {
864. $subject = $this->encodeHeader($this->secureHeader($subject));
865. }
866. //Calling mail() with null params breaks
867. $this->edebug('Sending with mail()');
868. $this->edebug('Sendmail path: ' . ini_get('sendmail_path'));
869. $this->edebug("Envelope sender: {$this->Sender}");
870. $this->edebug("To: {$to}");
871. $this->edebug("Subject: {$subject}");
872. $this->edebug("Headers: {$header}");
873. if (!$this->UseSendmailOptions || null === $params) {
874. $result = #mail($to, $subject, $body, $header);
875. } else {
876. $this->edebug("Additional params: {$params}");
877. $result = #mail($to, $subject, $body, $header, $params);
878. }
879. $this->edebug('Result: ' . ($result ? 'true' : 'false'));
880. return $result; }
/**
* Output debugging info via a user-defined method.
* Only generates output if debug output is enabled.
*
* #see PHPMailer::$Debugoutput
* #see PHPMailer::$SMTPDebug
*
* #param string $str
*/
I am handling imap in php via socket. Everything works perfect. I build mail swift object, then convert it to string and send to imap with append command, it works, I get OK [APPENDUID 1 4497] (Success), but if I attach file greater than about 3kb - imap server responds me nothing, and the mail doesn't append! What is the problem? May be I should make append something like part by part? I mean cut mail body for several parts and make several fwrite()?
These are several parts of my code. But I think problem is not in the code, but in some common imap stuff:
/**
* #param string $command
* #param string $successPattern
* #param bool $withCounter
* #return false|string
*/
protected function sendCommand($command, $successPattern = '', $withCounter = true)
{
$counter = $withCounter ? "{$this->commandHash}{$this->commandCounter} " : "";
$successPattern = !$successPattern ? $counter . 'OK' : $successPattern;
fwrite($this->stream, "{$counter}{$command}\r\n");
$this->commandCounter++;
$previousLine = '';
$buf = '';
$time = time();
while ((time() - $time) < $this->timeOut) {
$newLine = fread($this->stream, 4096);
if(!strlen($newLine)) continue;
$buf .= $newLine;
file_put_contents("/LOG2.txt", $newLine, FILE_APPEND);
if (strripos($previousLine.$newLine, $successPattern) !== FALSE){
$this->responseContainer->setLastResponseText($buf);
return $buf;
}
if (strripos($previousLine.$newLine, $this->commandHash . ($this->commandCounter - 1) . ' NO') !== FALSE
|| strripos($previousLine.$newLine, $this->commandHash . ($this->commandCounter - 1) . ' BAD') !== FALSE){
$this->responseContainer->setLastErrorText($buf);
return false;
}
$previousLine = $newLine;
}
var_dump(" Time out");
$this->responseContainer->setLastErrorText("{$command} {$counter} Time out");
return false;
}
/**
* #param $mailString
* #param string $folder
* #return false|int
*/
public function append($mailString, $folder = "INBOX")
{
if($this->sendCommand("APPEND {$folder} {".strlen($mailString)."}", "go ahead")){
$response = $this->sendCommand($mailString, '', false);
return $this->imapParser->parseAppendResult($response);
}
return false;
}
$message = new \Swift_Message();
$message->setSubject($mail->subject);
$message->setFrom($mail->from);
$message->setTo($mail->to);
$message->addPart($mail->body, 'text/html');
foreach($mail->files as $file){
$attachment = \Swift_Attachment::fromPath($file->getPath());
$attachment->setFilename($file->name.".".$file->type);
$message->attach($attachment);
}
$appendUid = $this->imapService->getCommander()->append($message->toString());
Creating stream:
/**
* #param string $host
* #param integer $port
* #return bool
*/
protected function createStream($host, $port)
{
//#todo proxy authentication
if($this->stream = #stream_socket_client("ssl://{$host}:{$port}", $errno, $errstr, $this->timeOut, STREAM_CLIENT_CONNECT, $this->context)) {
stream_set_timeout($this->stream, $this->timeOut);
return $this->stream;
}
$this->responseContainer->setLastErrorText("Failed connection to imap. Without proxy. " . $errstr);
return false;
}
I'm trying to get a script to poll a pop3 mailbox and extract some contents of the email body which is in MIME. The below script does the job however it only reads the first message because the $message variable is manually defined to look at the first message only. I need this script to loop and get all the messages in the inbox. I don't do programming for living so please excuse my ignorance if this is a simple task.
Below code was extracted from http://www.damnsemicolon.com/php/parse-emails-in-php-with-email-piping-part-2#.WnGfF2995EZ
require('mime_parser.php');
require('rfc822_addresses.php');
require('pop3.php');
stream_wrapper_register('mlpop3', 'pop3_stream'); /* Register the pop3 stream handler class */
$user=UrlEncode("someuserid");
$password=UrlEncode("somepassword");
$realm=UrlEncode(""); /* Authentication realm or domain */
$workstation=UrlEncode(""); /* Workstation for NTLM authentication */
$host = 'someip';
$apop=0; /* Use APOP authentication */
$authentication_mechanism=UrlEncode("USER"); /* SASL authentication mechanism */
$debug=0; /* Output debug information */
$html_debug=1; /* Debug information is in HTML */
$message=1;
$message_file='mlpop3://'.$user.':'.$password.'#'.$host.'/'.$message.
'?debug='.$debug.'&html_debug='.$html_debug.'&realm='.$realm.'&workstation='.$workstation.
'&apop='.$apop.'&authentication_mechanism='.$authentication_mechanism;
$mime=new mime_parser_class;
$mime->decode_bodies = 1;
$parameters=array(
'File'=>$message_file,
/* Read a message from a string instead of a file */
/* 'Data'=>'My message data string', */
/* Save the message body parts to a directory */
/* 'SaveBody'=>'/tmp', */
/* Do not retrieve or save message body parts */
);
$success=$mime->Decode($parameters, $decoded);
if(!$success)
echo '<h2>MIME message decoding error: '.HtmlSpecialChars($mime->error)."</h2>\n";
else
{
if($mime->Analyze($decoded[0], $results))
{
//for($line=0;$line<count($decoded);$line++)
$fromName = $decoded[0]['ExtractedAddresses']['from:'][0]['name'];
$fromEmail = $decoded[0]['ExtractedAddresses']['from:'][0]['address'];
//get the subject
$subject = $decoded[0]['Headers']['subject:'];
echo '<pre>';
//get the message body
if(substr($decoded[0]['Headers']['content-type:'],0,strlen('text/plain')) == 'text/plain' && isset($decoded[0]['Body'])){
$body = $decoded[0]['Body'];
} elseif(substr($decoded[0]['Parts'][0]['Headers']['content-type:'],0,strlen('text/plain')) == 'text/plain' && isset($decoded[0]['Parts'][0]['Body'])) {
$body = $decoded[0]['Parts'][0]['Body'];
} elseif(substr($decoded[0]['Parts'][0]['Parts'][0]['Headers']['content-type:'],0,strlen('text/plain')) == 'text/plain' && isset($decoded[0]['Parts'][0]['Parts'][0]['Body'])) {
$body = $decoded[0]['Parts'][0]['Parts'][0]['Body'];
}
echo "\nFrom: $fromName \n\nSubject: $subject \n\nAffected Sites: $searchmsg ";
echo '</pre>';
}
else
echo 'MIME message analyse error: '.$mime->error."\n";
}
i am trying to modify some code that parses text for html hyperlinks and puts them into a database.
The change i'm trying to make is to only match if html hyperlink contains a certain text such as:
my image
would not be matched but
my image2
would be matched based on that it has the "/thisismyunique/string" in the url.
Any ideas?
class blcHTMLLink extends blcParser {
var $supported_formats = array('html');
/**
* Parse a string for HTML links - anchor text
*
* #param string $content The text to parse.
* #param string $base_url The base URL to use for normalizing relative URLs. If ommitted, the blog's root URL will be used.
* #param string $default_link_text
* #return array An array of new blcLinkInstance objects. The objects will include info about the links found, but not about the corresponding container entity.
*/
function parse($content, $base_url = '', $default_link_text = ''){
//remove all <code></code> blocks first
$content = preg_replace('/<code[^>]*>.+?<\/code>/si', ' ', $content);
//Find links
$params = array(
'base_url' => $base_url,
'default_link_text' => $default_link_text,
);
$instances = $this->map($content, array($this, 'parser_callback'), $params);
//The parser callback returns NULL when it finds an invalid link. Filter out those nulls
//from the list of instances.
$instances = array_filter($instances);
return $instances;
}
/**
* blcHTMLLink::parser_callback()
*
* #access private
*
* #param array $link
* #param array $params
* #return blcLinkInstance|null
*/
function parser_callback($link, $params){
global $blclog;
$base_url = $params['base_url'];
$url = $raw_url = $link['href'];
$url = trim($url);
//$blclog->debug(__CLASS__ .':' . __FUNCTION__ . ' Found a link, raw URL = "' . $raw_url . '"');
//Sometimes links may contain shortcodes. Execute them.
$url = do_shortcode($url);
//Skip empty URLs
if ( empty($url) ){
$blclog->warn(__CLASS__ .':' . __FUNCTION__ . ' Skipping the link (empty URL)');
return null;
};
//Attempt to parse the URL
$parts = #parse_url($url);
if(!$parts) {
$blclog->warn(__CLASS__ .':' . __FUNCTION__ . ' Skipping the link (parse_url failed)', $url);
return null; //Skip invalid URLs
};
if ( !isset($parts['scheme']) ){
//No scheme - likely a relative URL. Turn it into an absolute one.
//TODO: Also log the original URL and base URL.
$url = $this->relative2absolute($url, $base_url); //$base_url comes from $params
$blclog->info(__CLASS__ .':' . __FUNCTION__ . ' Convert relative URL to absolute. Absolute URL = "' . $url . '"');
}
//Skip invalid links (again)
if ( !$url || (strlen($url)<6) ) {
$blclog->info(__CLASS__ .':' . __FUNCTION__ . ' Skipping the link (invalid/short URL)', $url);
return null;
}
//Remove left-to-right marks. See: https://en.wikipedia.org/wiki/Left-to-right_mark
$ltrm = json_decode('"\u200E"');
$url = str_replace($ltrm, '', $url);
$text = $link['#link_text'];
//The URL is okay, create and populate a new link instance.
$instance = new blcLinkInstance();
$instance->set_parser($this);
$instance->raw_url = $raw_url;
$instance->link_text = $text;
$link_obj = new blcLink($url); //Creates or loads the link
$instance->set_link($link_obj);
return $instance;
}
If you already have a href index in your $link parameter, which should contains the URL, you could easily do this:
$blockedWord = '/thisismyunique/string';
$blockedWordPosition = strpos($link['href'], $blockedWord);
$hasBlockedWord = $blockedWordPosition !== false;
Watch out, because strpos could return 0, if the needle has found in the beginning of the haystack string.
Find out more here:
http://php.net/manual/en/function.strpos.php
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);