preg_replace on email template - php

i use swift mailer , and when i get an email from the server i get this :
You request your password via Forget Password
Your username is : {myusername}
Your password is : {mypassword}
with { } , the function for send is :
function format_emailforget($info, $format){
//set the root
$root = $_SERVER['DOCUMENT_ROOT'].'/email';
//grab the template content
$template = file_get_contents($root.'/forget_template.'.$format);
//replace all the tags
$template = preg_replace('{USERNAME}', $info['username'], $template);
$template = preg_replace('{EMAIL}', $info['email'], $template);
$template = preg_replace('{PASSWORD}', $info['password'], $template);
$template = preg_replace('{SITEPATH}','http://smracer.com', $template);
//return the html of the template
return $template;
}
where is the bad think of this code ?

More elegant way and easy to maintain :)
$pattern = array('/\{USERNAME\}/' , '/\{EMAIL\}/' , '/\{PASSWORD\}/' , '/\{SITEPATH\}/');
$replacement = array($info['username'], $info['email'], $info['password'], 'http://smracer.com');
$template = preg_replace($pattern, $replacement, $template);

Related

text to link, problem with link that has not https

Users can add texts. This texts can have links.
I'd like do add click to it.
The problem is, some links works like:
http://www.example.com
links that has no http will not work and will become:
http://mywebsite.com/www.example.com
any ideas how to solve it?
function toLink($titulo){
$url = '~(?:(https?)://([^\s<]+)|(www\.[^\s<]+?\.[^\s<]+))(?<![\.,:])~i';
$titulo = preg_replace($url, '$0', $titulo);
return $titulo;
}
Use preg_replace_callback instead and you can interrogate the match to see if you need to add the protocol.
function toLink($titulo) {
$url = '~(?:(https?)://([^\s<]+)|(www\.[^\s<]+?\.[^\s<]+))(?<![\.,:])~i';
$titulo = preg_replace_callback($url, function($matches) {
$url = $matches[0];
if (!preg_match('/^https?:\/\//', $url)) $url = 'http://'.$matches[0];
''.$url.'';
}, $titulo);
return $titulo;
}

IMAP PHP with embedded images not showing Codeigniter on localhost

I use codeigniter and imap php currently developing project xampp. For some reason them embedded images not showing.
In my getBody() function I have this call back
$body = preg_replace_callback(
'/src="cid:(.*)">/Uims',
function($m) use($email, $uid){
//split on #
$parts = explode('#', $m[1]);
//replace local path with absolute path
$img = str_replace($parts[0], '', $parts[0]);
return "src='$img'>";
},
$body);
I get error
Question: How can I make sure it gets the images correct for the text/html body etc.
<?php
class Email extends MY_Controller {
private $enc;
private $host;
private $user;
private $pass;
private $mailbox;
private $mbox;
public function __construct() {
parent::__construct();
$this->enc = '/imap/ssl/novalidate-cert';
$this->host = '****';
$this->user = '****'; // email
$this->pass = '****'; // Pass
$this->mailbox = '{' . $this->host . $this->enc . '}';
$this->mbox = imap_open($this->mailbox, $this->user, $this->pass);
}
public function view() {
$this->data['message'] = $this->getBody($this->uri->segment(4));
$this->load->view('template/common/header', $this->data);
$this->load->view('template/common/nav', $this->data);
$this->load->view('template/mail/view', $this->data);
$this->load->view('template/common/footer', $this->data);
imap_close($this->mbox);
}
public function getBody($uid) {
$body = $this->get_part($uid, "TEXT/HTML");
// if HTML body is empty, try getting text body
if ($body == "") {
$body = $this->get_part($uid, "TEXT/PLAIN");
}
$email = $this->user;
//replace cid with full path to image
$body = preg_replace_callback(
'/src="cid:(.*)">/Uims',
function($m) use($email, $uid){
//split on #
$parts = explode('#', $m[1]);
//replace local path with absolute path
$img = str_replace($parts[0], '', $parts[0]);
return "src='$img'>";
},
$body);
return trim(utf8_encode(quoted_printable_decode($body)));
}
private function get_part($uid, $mimetype, $structure = false, $partNumber = false) {
if (!$structure) {
$structure = imap_fetchstructure($this->mbox, $uid);
}
if ($structure) {
if ($mimetype == $this->get_mime_type($structure)) {
if (!$partNumber) {
$partNumber = 1;
}
$text = imap_fetchbody($this->mbox, $uid, $partNumber, FT_PEEK);
switch ($structure->encoding) {
# 7BIT
case 0:
return imap_qprint($text);
# 8BIT
case 1:
return imap_8bit($text);
# BINARY
case 2:
return imap_binary($text);
# BASE64
case 3:
return imap_base64($text);
# QUOTED-PRINTABLE
case 4:
return quoted_printable_decode($text);
# OTHER
case 5:
return $text;
# UNKNOWN
default:
return $text;
}
}
// multipart
if ($structure->type == 1) {
foreach ($structure->parts as $index => $subStruct) {
$prefix = "";
if ($partNumber) {
$prefix = $partNumber . ".";
}
$data = $this->get_part($uid, $mimetype, $subStruct, $prefix . ($index + 1));
if ($data) {
return $data;
}
}
}
}
return false;
}
private function get_mime_type($structure) {
$primaryMimetype = array("TEXT", "MULTIPART", "MESSAGE", "APPLICATION", "AUDIO", "IMAGE", "VIDEO", "OTHER");
if ($structure->subtype) {
return $primaryMimetype[(int)$structure->type] . "/" . $structure->subtype;
}
return "TEXT/PLAIN";
}
}
Introduction
You are trying to convert an Email into a HTML Page.
An Email has multiple parts:
Headers
Text based email
HTML based email
Attachments
In the header you will find the Message-ID as well as other relevant metadata.
In order to convert an Email into a website you have to expose the HTML and the Attachments to the browser.
Each of the Parts has its own headers. When you have a url='cid:Whatever' you have to look for which part of the email hast that Content-Id header.
Serve the Email as a Web Page
You need to find wich Email part contains the HTML Body. Parse it and replace the CID URL's for your http://yourhost/{emailId} you already implemented that part so I will not add how to do it here.
Replace CID URL on HTML - Implementation
This is a prototype that may work for you.
$mailHTML="<html>All your long code here</html>";
$mailId="email.eml";
$generatePartURL=function ($messgeId, $cid) {
return "http://myhost/".$messgeId."/".$cid; //Adapt this url according to your needs
};
$replace=function ($matches) use ($generatePartURL, $mailId) {
list($uri, $cid) = $matches;
return $generatePartURL($mailId, $cid);
};
$mailHTML=preg_replace_callback("/cid:([^'\" \]]*)/", $replace, $mailHTML);
Find the part by CID
http://yourhost/{emailId}/{cid}
Pseudo code:
Load email
Find part by CID
Decode from Base64 or other Encoding used (Check Content-Transfer-Encoding header)
Serve the file as an HTTP Response
Which part has my CID image?
Iterate all email parts looking for the Content-ID header that match your CID value.
--_part_boundery_
Content-Type: image/jpeg; name="filename.jpg"
Content-Description: filename.jpg
Content-Disposition: inline; filename="filename.jpg"; size=39619; creation-date="Thu, 28 Dec 2017 10:53:51 GMT"; modification-date="Thu, 28 Dec 2017 10:53:51 GMT"
Content-ID: <YOUR CID WILL BE HERE>
Content-Transfer-Encoding: base64
Decode the transfer encoding and serve the contents as a regular http file.
Webmail implemented in PHP
RoundCube is a webmail implemented in PHP you can have a look how they do this: https://github.com/roundcube/roundcubemail/blob/master/program/lib/Roundcube/rcube_washtml.php
Note: My code it is not based in this solution.

Swift Mailer - multiple recipients not working

I have a problem with Swift Mailer, It seems easy, but I'm strugling with it for hours.
I need to send an email to multiple recipients.
This is a string I begin with (the content of $email->getRecipients() ):
// Just an example
first#gmail.com, second#gmail.com
First I remove all non-visible characters:
$string = preg_replace('/[\x00-\x1F\x7F]/u', '', $email->getRecipients());
Then I add surranding quotes:
$addQuotes = "'" . str_replace(",", "','", $string) . "'";
And remove empty spaces:
$recipients = str_replace(' ', '', $addQuotes);
Which gives me:
'first#gmail.com','second#gmail.com'
If I paste the string manually:
->setTo(['first#gmail.com','second#gmail.com'])
It works. But when I try to put variable like this:
$array = explode(',', $recipients);
...
->setTo($array)
Emails are not being sent.
When I do this:
->setTo([$recipients])
I get the error Address in mailbox given ['...','...'] does not comply with RFC 2822, 3.6.2.
I also tried:
foreach($array as $recipient) {
$message->setTo($recipient);
$this->get('mailer')->send($message);
}
Not working! But again, if I paste string directly, it works:
foreach($array as $recipient) {
$message->setTo('first#gmail.com');
$this->get('mailer')->send($message);
}
The code:
private function sendEmail($email)
{
//$email->getRecipients() = 'first#gmail.com, second#gmail.com'
$string = preg_replace('/[\x00-\x1F\x7F]/u', '', $email->getRecipients());
$addQuotes = "'" . str_replace(",", "','", $string) . "'";
$recipients = str_replace(' ', '', $addQuotes);
$array = explode(',', $recipients);
$message = \Swift_Message::newInstance()
->setSubject($email->getSubject())
->setFrom($email->getSender())
->setTo($array)
->setBody(
$this->renderView(
'Emails/default.html.twig',
array('body' => $email->getBody())
),
'text/html'
);
//foreach($array as $recipient) {
// $message->setTo($recipient);
// $this->get('mailer')->send($message);
//}
$this->get('mailer')->send($message);
}

JSON encoding headers using Sendgrid

I am trying to change the filter status for the 'subscriptiontrack' using sendgrid. I think I am sending the headers incorrectly, but not totally sure. Working inside a symfony 1.4 framework.
First I create an object of the header settings
$hdr = new SmtpApiHeader();
$hdr->addFilterSetting('subscriptiontrack', 'enable', 0);
$hdr->as_string();
which sets the filter settings and encodes the string
Then I send it off the email class
sendTestEmail::sendEmail($contents, $mailFrom, $testGroup, $subject, $hdr);
SvaSmtpApiHeader.class.php
class SmtpApiHeader
{
function addFilterSetting($filter, $setting, $value)
{
if (!isset($this->data['filters'])) {
$this->data['filters'] = array();
}
if (!isset($this->data['filters'][$filter])) {
$this->data['filters'][$filter] = array();
}
if (!isset($this->data['filters'][$filter]['settings'])) {
$this->data['filters'][$filter]['settings'] = array();
}
$this->data['filters'][$filter]['settings'][$setting] = $value;
}
function asJSON()
{
$json = json_encode($this->data);
// Add spaces so that the field can be folded
$json = preg_replace('/(["\]}])([,:])(["\[{])/', '$1$2 $3', $json);
return $json;
}
function as_string()
{
$json = $this->asJSON();
$str = "X-SMTPAPI: " . wordwrap($json, 76, "\n ");
return $str;
}
}
myEmail.class.php
<?php
class sendTestEmail
{
public static function sendEmail($contents, $mailFrom, $mailTo, $subject, $sgHeaders = null, $attachments = null)
{
try {
/*
* Load connection for mailer
*/
$connection = Swift_SmtpTransport::newInstance('smtp.sendgrid.net', 465, 'ssl')->setUsername(sfconfig::get('app_sendgrid_username'))->setPassword(sfconfig::get('app_sendgrid_password'));
// setup connection/content
$mailer = Swift_Mailer::newInstance($connection);
$message = Swift_Message::newInstance()->setSubject($subject)->setTo($mailTo);
$message->setBody($contents, 'text/html');
// if contains SMTPAPI header add it
if (null !== $sgHeaders) {
$message->getHeaders()->addTextHeader('X-SMTPAPI', $sgHeaders);
}
// update the from address line to include an actual name
if (is_array($mailFrom) and count($mailFrom) == 2) {
$mailFrom = array(
$mailFrom['email'] => $mailFrom['name']
);
}
// add attachments to email
if ($attachments !== null and is_array($attachments)) {
foreach ($attachments as $attachment) {
$attach = Swift_Attachment::fromPath($attachment['file'], $attachment['mime'])->setFilename($attachment['filename']);
$message->attach($attach);
}
}
// Send
$message->setFrom($mailFrom);
$mailer->send($message);
}
catch (Exception $e) {
throw new sfException('Error sending email out - ' . $e->getMessage());
}
}
}
The email is getting sent properly, but the unsubscribe option is still showing up at the bottom. Is this an issue with the header object or a problem with encoding for the header? Is the variable is still an object when getting added to the headers?
You're misunderstanding how JSON encoding works. Let's take a look at your as_string method:
function as_string()
{
$json = $this->asJSON();
$str = "X-SMTPAPI: " . wordwrap($json, 76, "\n ");
return $str;
}
This would output something to the effect of:
X-SMTPAPI: { "filters": { "subscriptiontrack": { "settings": { "enable": 0 } } } }
You should note that this isn't valid JSON because it is prefixed with "X-SMTPAPI". Instead, you should be calling asJSON, but SwiftMailer doesn't know that.
Try switching the header line to:
$message->getHeaders()->addTextHeader('X-SMTPAPI', $sgHeaders->asJSON());
If that doesn't work, can you give us a dump of:
$headers = $message->getHeaders();
echo $headers->toString();
And have you thought about using the official PHP library instead? https://github.com/sendgrid/sendgrid-php

PHP file_get_contents then replace string in a function

**User_Tpl.html**
<html><head></head>
<body>
Hello {NAME},
Business name : {BUSINESS_NAME}.
Tel : {TELEPHONE}.
Mob : {MOBILE}.
</body>
</html>
function mailFooter($content) {
$sBusiness = 'Business name';
$sTelp = '0';
$sMobile = '0';
$content = str_replace('{BUSINESS_NAME}', $sBusiness, $content);
$content = str_replace('{TELEPHONE}', $sTelp, $content);
$content = str_replace('{MOBILE}', $sMobile, $content);
return $content;
}
$content = file_get_contents('page/email/User_Tpl.html');
$content = str_replace('{SUBJECT}', $subject, $content);
$content = str_replace('{NAME}', $ownerName, $content);
**mailerFooter($content);**
// always return {BUSINESS_NAME}, {TELEPHONE}
$mail->AddAddress( $email );
$mail->SetFrom($name );
$mail->AddReplyTo( $reply );
$mail->Subject = trim($subject);
$mail->MsgHTML( trim($content) );
$mail->IsHTML(true);
$mail->Send();
im using PHPMailer as Mailer library and how to replace those {strings} inside the mailFooter() function.
use array
$content ='
<html><head></head>
<body>
Hello {NAME},
Business name : {BUSINESS_NAME}.
Tel : {TELEPHONE}.
Mob : {MOBILE}.
</body>
</html>';
$search= array ('{BUSINESS_NAME}','{TELEPHONE}','{MOBILE}');
$replace=array($sBusiness,$sTelp,$sMobile);
$content =str_replace($search,$replace,$content);
private arr = array(
"{title}" => "Home page",
"{email}" => "my#mail.com",
...
);
private $content = "Title for my site - {title}, if you interesting my email addres -> {email}"
$this->content = strtr($this->content, $this->arr);
echo $this->content;
This return -> "Title for my site - Home page, if you interesting my email addres -> my#mail.com"

Categories