I'm trying to use php sendgrid to send emails from a contact form. I only need the simplest implementation and followed the basic steps indicated here: https://github.com/sendgrid/sendgrid-php
Here's my code:
require_once 'sendgrid-php/lib/SendGrid.php';
require_once 'unirest-php/lib/Unirest.php';
function spamcheck($field) {
$field = filter_var($field, FILTER_SANITIZE_EMAIL);
if (filter_var($field, FILTER_VALIDATE_EMAIL)) {
return TRUE;
} else {
return FALSE;
}
}
if (isset($_REQUEST['email'])) {
$mailcheck = spamcheck($_REQUEST['email']);
if ($mailcheck == FALSE) {
echo "Invalid Input";
} else {
$email = $_REQUEST['email'];
$name = $_REQUEST['name'];
$company = $_REQUEST['company'];
$message = $_REQUEST['message'];
$subject = "This is the subject";
$recipient = "test#email.com"; // Not the real value
$username = 'test'; // Not the real value
$password = '1234'; // Not the real value
$sendgrid = new SendGrid($username, $password);
$mail = new SendGrid\Email();
$body = "Name: " . $name . "\n" .
"Company: " . $company . "\n" .
"Message: " . $message;
$mail->addTo($recipient)->
setFrom($email)->
setSubject($subject)->
setText($message);
$sendgrid->smtp->send($mail);
echo 'SUCCESS';
}
} else {
echo "Fail";
}
And I'm getting this error:
<br />
<b>Fatal error</b>: Class 'SendGrid\Email' not found in <b>/usr/local/www/vhosts/.../intl/mail.php</b> on line <b>27</b><br />
Also, when I try to add this to my code (As indicated in the above link):
SendGrid::register_autoloader();
I get this error:
<br />
<b>Warning</b>: require_once(swift_required.php): failed to open stream: No such file or directory in <b>/usr/local/www/vhosts/.../intl/sendgrid- php/lib/SendGrid/Smtp.php</b> on line <b>25</b><br />
<br />
<b>Fatal error</b>: require_once(): Failed opening required 'swift_required.php' (include_path='.:/usr/local/share/pear') in <b>/usr/local/www/vhosts/.../intl/sendgrid- php/lib/SendGrid/Smtp.php</b> on line <b>25</b><br />
^ Based on that, I won't be using swift mailer so it might not be related.
What am I missing?
*PHP Version 5.4.21
*SendGrid Version 1.1.6
I did not install swiftmailer, but I did install smtpapi-php and unirest-php
https://github.com/Mashape/unirest-php
https://github.com/sendgrid/smtpapi-php
My test code looks like this:
require_once ('../includes/sendgrid-php/lib/SendGrid.php');
require_once ('../includes/smtpapi-php/lib/Smtpapi.php');
require_once ('../includes/unirest-php/lib/Unirest.php');
SendGrid::register_autoloader();
Smtpapi::register_autoloader();
$sendgrid = new SendGrid('user', 'pass');
$email = new SendGrid\Email();
$email->addTo( $to)->
setFrom($from)->
setSubject($subject)->
setText('Test')->
setHtml($html);
$x = $sendgrid->send($email);
var_dump($x );
And it works on php 5.4
Since you are using the SMTP sending method:
$sendgrid->smtp->send($mail);
You need to install swiftmailer. Instructions for that are here: https://github.com/sendgrid/sendgrid-php#optional
Your other option is to send using web - which is actually what we recommend at SendGrid now. It's faster than the chatty SMTP protocol.
$sendgrid->web->send($mail);
Related
I am using send grid to email to the server webmail. Following are my code. I wrote this code by following the tutorials. But I get error :
Warning: rawurlencode() expects parameter 1 to be string, object given in /home/cwtestco/public_html/demo/active-fit-club/sendgrid-php/vendor/guzzle/guzzle/src/Guzzle/Http/QueryString.php on line 237
Warning: Cannot modify header information - headers already sent by (output started at /home/cwtestco/public_html/demo/active-fit-club/sendgrid-php/vendor/guzzle/guzzle/src/Guzzle/Http/QueryString.php:237) in /home/cwtestco/public_html/demo/active-fit-club/index.php on line 53
Code :
if($res != false){
require_once ($_SERVER['DOCUMENT_ROOT'].'/demo/active-fit-club/sendgrid-php/vendor/autoload.php');
require_once ($_SERVER['DOCUMENT_ROOT'].'/demo/active-fit-club/sendgrid-php/lib/SendGrid.php');
require_once ($_SERVER['DOCUMENT_ROOT'].'/demo/active-fit-club/sendgrid-php/lib/SendGrid/Exception.php');
$message = "Name : $name <br> Email : $email <br> Mobile : $mobile";
$sendgrid = new SendGrid('myapikey');
$email = new SendGrid\Email();
$email
->addTo("info#abc.co.uk")
->setFrom($email)
->setSubject("Contact mail")
->setHtml($message);
try {
$sendgrid->send($email);
$_SESSION['success'] = true;
header("location:url");
exit;
} catch(\SendGrid\Exception $e) {
// echo $e->getCode();
// foreach($e->getErrors() as $er) {
// echo $er;
// }
header("location:url");
exit;
}
}
Try moving setting the header before setting the SESSION variable and set $_SESSION['success'] to be 'true' instead of true:
try {
$sendgrid->send($email);
header("location:url");
$_SESSION['success'] = 'true';
exit;
}
im using the below code and its working.
$url = 'https://api.sendgrid.com/';
$apiKey = 'SENDGRID_API_KEY';
//api library from sendgrid
require_once "sendgrid/sendgrid-php.php";
$sendgrid = new SendGrid($apiKey);
$email = new SendGrid\Email();
$email
->addTo("to#example.com")
->setFromName("Fromname")
->setFrom("from#example.com")
->setSubject("your subject goes here")
->setText('')
->setHtml("your email html content goes here");
if($sendgrid->send($email))
echo "Mail sent";
else
echo "Failed";
you can get the library files from https://github.com/sendgrid/sendgrid-php
I am using PHPMailer to send emails from my local host.
I have written a function which is supposed to send emails to registered users who have chosen the option to receive them. (i.e. newsletter subscription, etc)
function email_users($subject, $body) {
include('core/db/db_connection.php');
$sql = "SELECT email, first_name FROM `_users` WHERE allow_email = 1";
$query = mysqli_query($dbCon, $sql);
while (($row = mysqli_fetch_assoc($query)) !== false) {
$body = "Hello ". $row['first_name'] . ", <br><br>" . $body;
email($row['email'], $subject, $body);
}
}
The code that is calling the function:
if (isset($_GET['success']) === true && empty($_GET['success']) === true) {
?>
<h3 class="email_success">Emails have been sent</h2>
Go back to the admin page
<?php
} else {
if (empty($_POST) === false) {
if (empty($_POST['subject']) === true) {
$errors[] = 'A message subject is required.';
}
if (empty($_POST['body']) === true) {
$errors[] = 'A body message is required.';
}
if (empty($errors) === false) {
echo output_errors($errors);
} else {
email_users($_POST['subject'], $_POST['body']);
header('Location: email_users.php?success');
exit();
}
}
// generate email form otherwise
Any idea why I'm getting this error?
Fatal error: Cannot redeclare PHPMailerAutoload()
I would also like to point out that even with this error, the function still works and the emails are being sent...
EDIT: As requested, please see below the function using PHPMailer:
function email($user, $subject, $body) {
require 'phpmailer/PHPMailerAutoload.php';
$mail = new PHPMailer;
/* $mail -> Host,username,password and other misc stuff
$mail->Subject = $subject;
$mail->Body = $body;
$mail->AltBody = $body; etc */
}
If you use
require 'phpmailer/PHPMailerAutoload.php';
in your function, but you call the function 2 times, it will redeclare the class. Simply use require_once() instead.
require_once('phpmailer/PHPMailerAutoload.php');
After much testing, the solution I have found is adding the header redirect into the function and removing it from the calling code:
function email_users($subject, $body) {
include('core/db/db_connection.php');
$sql = "SELECT email, first_name FROM `_users` WHERE allow_email = 1";
$query = mysqli_query($dbCon, $sql);
while (($row = mysqli_fetch_assoc($query)) !== false) {
$body = "Hello ". $row['first_name'] . ", <br><br>" . $body;
email($row['email'], $subject, $body);
header('Location: email_users.php?success');
}
}
Also, as pointed out by honerlawd, require_once is needed in order for this to work, otherwise it will send an email only to the first account found in the database. Without redirecting to the email_users.php?success, this will cause an infinite loop, no matter if I call require_once or require.
Would this be the correct approach or is it just a temporary messy fix?
Currently I have an old script that parses emails, as seen here:
// Accessing the mailbox
$mailbox = imap_open("{imap.gmail.com:993/imap/ssl/novalidate-cert}INBOX", $mailbox, $mailboxPassword);
// Retrieving only unread messages
$mail = imap_search($mailbox, 'UNSEEN');
// If no new messages found aborting the script
if(empty($mail)) die('No unread emails found!');
$total_found = 0;
$skipped = 0;
// Now we loop through messages
foreach ($mail as $key => $val) {
// process everything
}
This works fine other than some encoding issues with Russian (Cyrillic) characters and a few other issues. While I could hunt down all these issues individually, it seems like there are already great mail parsing classes out there. I found this, which I'd like to use as it sounds like this gets suggested often.
The example code provided is with the parser is below.
<?php
require_once('MimeMailParser.class.php');
$path = 'path/to/mail.txt';
$Parser = new MimeMailParser();
$Parser->setPath($path);
$to = $Parser->getHeader('to');
$from = $Parser->getHeader('from');
$subject = $Parser->getHeader('subject');
$text = $Parser->getMessageBody('text');
$html = $Parser->getMessageBody('html');
$attachments = $Parser->getAttachments();
?>
However it seems to need a reference to $path which is confusing me as the emails are not stored in a folder, there pulled from IMAP. Would I add $path = $mail; in the foreach block? If not, what format do I supply the email to the parser in? Do I have to use the same script I already have and save it to a folder?
All the emails are being retrieved from Gmail. I used IMAP but could use POP instead if IMAP wont work.
Based on the suggested answer i tried this code but its just looping through x unread emails and displaying blank data for everything, headers and body?
// Accessing the mailbox
$mailbox = imap_open("{imap.gmail.com:993/imap/ssl/novalidate-cert}INBOX", $mailbox, $mailboxPassword);
// Retrieving only unread messages
$mail = imap_search($mailbox, 'UNSEEN');
// If no new messages found aborting the script
if(empty($mail)) die('No unread emails found!');
$total_found = 0;
$skipped = 0;
// Now we loop through messages
foreach ($mail as $email) {
$Parser = new MimeMailParser();
$Parser->setText($mail);
echo "-----------------------------Start Of Email---------------------------------";
echo "<br /><br /><br /><br />";
$to = $Parser->getHeader('to');
echo "To: " . $to . "<br />";
$from = $Parser->getHeader('from');
echo "From: " . $from . "<br />";
$subject = $Parser->getHeader('subject');
echo "Subject: " . $subject . "<br /><br /><br />";
//$text = $Parser->getMessageBody('text');
$html = $Parser->getMessageBody('html');
echo "Body: " . "<br /><br />" . $html . "<br />";
//$attachments = $Parser->getAttachments();
echo "<br /><br /><br /><br />";
echo "-----------------------------End Of Email---------------------------------";
}
That class has another function to set the message content directly. Just call $Parser->setText($mail) where $mail is the message content in your IMAP foreach loop.
Ok, my problem is that when i try to make my confirm link with the random code that i already created, it wont pass to the Confirmation mail. However the confirm code, still inserts to the database without problems. This is my code:
function NewUser()
{
$user = $_POST['user'];
$pass = $_POST['pass'];
$confirm = md5(uniqid(rand(), true));
$success = "INSERT INTO members(user,pass,'$confirm')";
$data = mysql_query ($success)or die(mysql_error());
if($data)
{if($data)
{
SendUserConfirmationEmail($confirm);
echo "<div class ='verdanacenter'><img src='img/bienvenido.png' title='Enhorabuena'/><br><br><br><font face ='verdana'>Welcome <b>$name $lname</b> !!!<br>Success.<br><br>Soon u will receive a confirmation msg to <b>$email</b>";
}
else
{
echo "<div class ='verdanacenter'><img src='img/alerta.png' title='Error'/><br><br><br><font face ='verdana'>Fatal Error !!!";
}
}
function SendUserConfirmationEmail($confirmcode)
{
require 'PHPMailerAutoload.php';
$mail = new PHPMailer();
$mail->isSendmail();
$mail->setFrom('info#rene.org', 'Rene');
$mail->addAddress($_POST['email'],$_POST['name']);
$mail->Subject = 'Welcome';
$mail->IsHTML(true);
$confirmcode = $confirm;
$mail->Body = '<p align="left"> Welcome <b>'.$_POST['name'].'</b>,</p><p align="justify">This is ur confirmation code:</p>
<p align="left">CONFIRMAR,</p>
<p align="left">Regards,<br>
Admin.<br>
www.rene.org</p>';
if (!$mail->send()) {
echo "Mailer Error: " . $mail->ErrorInfo;
} else {
echo "Message sent!";
}
}
The thing is that, when i register, i receive the email, but without the random code ($confimcode). It appears: "http://www.rene.org/confirmar.php?code=" instead of "http://www.rene.org/confirmar.php?code=A23B45423545V6764542543" What am i missing guys? PLEASE HELP.
This is called scope.
The function can't see variables from outside of itself. To pass that code to the function you include it in a parameter:
function SendUserConfirmationEmail($confirmcode){
...
when you call the function you pass your variable:
SendUserConfirmationEmail($confirm);
Anywhere inside your function, that value will be available as $confirmcode
Edit: Also just noticed you have a function inside a function. Don't do that, just make them separate.
I have a contact form, but the messages are not sending to the email I have declared. This is the submit.php file:
<?php
/* config start */
$emailAddress = 'xxxxxxx#hotmail.com';
/* config end */
require "../php/class.phpmailer.php";
session_name("fancyform");
session_start();
foreach($_POST as $k => $v)
{
if(ini_get('magic_quotes_gpc'))
$_POST[$k] = stripslashes($_POST[$k]);
$_POST[$k] = htmlspecialchars(strip_tags($_POST[$k]));
}
$err = array();
if(!checkLen('name'))
$err[] = 'The name field is too short or empty!';
if(!checkLen('email'))
$err[] = 'The email field is too short or empty!';
elseif(!checkEmail($_POST['email']))
$err[] = 'Your email is not valid!';
if(!checkLen('subject'))
$err[] = 'You have not selected a subject!';
if(!checkLen('message'))
$err[] = 'The message field is too short or empty!';
if((int)$_POST['captcha'] != $_SESSION['expect'])
$err[] = 'The captcha code is wrong!';
if(count($err))
{
if($_POST['ajax'])
{
echo '-1';
}
else if($_SERVER['HTTP_REFERER'])
{
$_SESSION['errStr'] = implode('<br />', $err);
$_SESSION['post'] = $_POST;
header('Location: '.$_SERVER['HTTP_REFERER']);
}
exit;
}
$msg =
'Name: '.$_POST['name'].'<br />
Email: '.$_POST['email'].'<br />
IP: '.$_SERVER['REMOTE_ADDR'].'<br /><br />
Message:<br /><br />
'.nl2br($_POST['message']).'
';
$mail = new PHPMailer();
$mail->IsMail();
$mail->AddReplyTo($_POST['email'], $_POST['name']);
$mail->AddAddress($emailAddress);
$mail->SetFrom($_POST['email'], $_POST['name']);
$mail->Subject = "A new ".mb_strtolower($_POST['subject'])." from ".$_POST['name']." | contact form feedback";
$mail->MsgHTML($msg);
$mail->Send();
unset($_SESSION['post']);
if($_POST['ajax'])
{
echo '1';
}
else
{
$_SESSION['sent'] = 1;
if($_SERVER['HTTP_REFERER'])
header('Location: '.$_SERVER['HTTP_REFERER']);
exit;
}
function checkLen($str, $len = 2)
{
return isset($_POST[$str]) && mb_strlen(strip_tags($_POST[$str]), "utf-8") > $len;
}
function checkEmail($str)
{
return preg_match("/^[\.A-z0-9_\-\+]+[#][A-z0-9_\-]+([.][A-z0-9_\-]+)+[A-z]{1,4}$/", $str);
}
?>
If submit.php is opened in a browser, I get the following error message:
Warning: require(../php/class.phpmailer.php) [function.require]: failed to open stream:
No such file or directory in
/home/content/96/9227096/html/submit.php on line 10 Fatal error: require() [function.require]: Failed opening required
'../php/class.phpmailer.php'
(include_path='.:/usr/local/php5_3/lib/php') in
/home/content/96/9227096/html/submit.php on line 10
I was also told by my hosting server that I might need to add the following relay server in my code:(but I don't know where)
relay-hosting.secureserver.net
The statement require "../php/class.phpmailer.php"; means that the ../php/class.phpmailer.php file will be loaded and that if it can't be loaded then the script will terminate.
It is unable to load that script. That could be for any of a number of reasons. Maybe it's not there. Maybe the path you provided is wrong. Maybe it's a file permission issue. You'll have to figure that part out.
But since it can't load it, the script terminates with the error message.
I have encounter similiar problems on some hosting providers. Even if the path was good require did not include file and terminated whole script. You could write there a real path to your file, and maybe that will help. Since this problem I started to use
require(getcwd().'actual/path/relevant/to/index.php');
and starder to write apps in one class, similiar to Java or C# desktop apps.