i want to send a email when register a user. i'm using the xampp, codeigniter and phpMailer. when i submit the registration form it was an error called
Message was not sent
PHPMailer Error: SMTP connect() failed. https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting
Registration Successfully !
here is my code(controller)
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
session_start(); //we need to start session in order to access it through CI
//The controller class is extends CI_Contoller
Class User_Authentication extends CI_Controller {
public function __construct() {
parent::__construct();
// Load form helper library
$this->load->helper('form');
// Load form validation library
$this->load->library('form_validation');
$this->load->library('my_phpmailer');
// Load session library
$this->load->library('session');
// Load database
$this->load->model('login_database');
}
// Show login page
public function index() {
$this->load->view('user_site/login_form');
}
// Show registration page
public function user_registration_show() {
$this->load->view('user_site/registration_form');
}
// Validate and store registration data in database
public function new_user_registration() {
// Check validation for user input in SignUp form
$this->form_validation->set_rules('firstname', 'First Name', 'trim|required|xss_clean');
$this->form_validation->set_rules('lastname', 'Last Name', 'trim|required|xss_clean');
$this->form_validation->set_rules('email', 'Email', 'trim|required|xss_clean');
$this->form_validation->set_rules('password', 'Password', 'trim|required|xss_clean|md5');
if ($this->form_validation->run() == FALSE) {
$this->load->view('user_site/registration_form');
// $this->load->view('register');
} else {
$data = array(
'firstname' => $this->input->post('firstname'),
'lastname' => $this->input->post('lastname'),
'email' => $this->input->post('email'),
'password' => $this->input->post('password'),
'address' => $this->input->post('address'),
'contact_no' => $this->input->post('contact_no')
);
$result = $this->login_database->registration_insert($data);
if ($result == TRUE) {
$data['message_display'] = 'Registration Successfully !';
$mail = new PHPMailer();
$mail->IsSMTP();
$mail->Mailer = 'smtp';
$mail->SMTPAuth = true;
$mail->Host = 'smtp.gmail.com'; // "ssl://smtp.gmail.com" didn't worked
$mail->Port = 465;
$mail->SMTPSecure = 'ssl';
// or try these settings (worked on XAMPP and WAMP):
// $mail->Port = 587;
// $mail->SMTPSecure = 'tls';
$mail->Username = "ashik#gmail.com";
$mail->Password = "zswedfr";
$mail->IsHTML(true); // if you are going to send HTML formatted emails
$mail->SingleTo = true; // if you want to send a same email to multiple users. multiple emails will be sent one-by-one.
$mail->From = "ashik#gmail.com";
$mail->FromName = "ABC";
$address = $_POST['email'];
$mail->AddAddress($address, "Guest");
$mail->Subject = "ABC Email validation ";
$mail->Body ="ABC Email validation";
if(!$mail->Send()){
echo "Message was not sent <br />PHPMailer Error: " . $mail->ErrorInfo;
}else{
echo "sucfdt " ;
}
$this->load->view('user_site/login_form', $data);
} else {
$data['message_display'] = 'Email already exist!';
//$this->load->view('user_site/registration_form', $data);
$this->load->view('register');
}
}
}
this is the php file in library
<?php
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class My_PHPMailer {
public function My_PHPMailer() {
require_once('PHPMailer/PHPMailerAutoload.php');
}
}
This code give the error that authentication failure in gmail server. It is because, gmail is assuming that the login computer/location is changed, and so it is auspicious. If you login to your gmail and look in security, recently logged devices, you can see a popup showing that login blocked from your server address. Check your access status here
If you enable it, this will work. Go to this link for unlocking
see this below thread. You can refer this too.
PHPMailer - SMTP ERROR: Password command failed when send mail from my server
Make a file email.php in application/config/ folder :
And these contents into it :
$config['protocol'] = 'smtp';
$config['smtp_host'] = 'ssl://smtp.gmail.com'; //change this
$config['smtp_port'] = '465';
$config['smtp_user'] = ''; //change this
$config['smtp_pass'] = ''; //change this
$config['mailtype'] = 'html';
$config['charset'] = 'iso-8859-1';
$config['wordwrap'] = TRUE;
$config['newline'] = "\r\n";
Related
I am working on a basic blog application in Codeigniter 3.1.8 and Bootstrap 4.
I have added a registration and login system to this application. I am current working on a password reset system.
I was able to do these 2 things separately:
Send a password reset email containing dummy text.
Create a valid password reset link.
I was unable however, to send the email once the reset link was inserted into the email body.
Here is he controller:
class Newpassword extends CI_Controller {
public function __construct()
{
parent::__construct();
}
private $sender_email = "noreply#yourdomain.com";
private $sender_name = "Razvan Zamfir";
private $user_email = '';
private $subject = 'Pasword reset link';
private $reset_token = '';
private $reset_url = '';
private $reset_link = '';
private $body = '';
public function index() {
// Display form
$data = $this->Static_model->get_static_data();
$data['pages'] = $this->Pages_model->get_pages();
$data['tagline'] = 'Reset your password';
$data['categories'] = $this->Categories_model->get_categories();
// Form validation rules
$this->form_validation->set_rules('email', 'Email', 'required|trim|valid_email');
$this->form_validation->set_error_delimiters('<p class="error-message">', '</p>');
if(!$this->form_validation->run()) {
$this->load->view('partials/header', $data);
$this->load->view('auth/passwordreset');
$this->load->view('partials/footer');
} else {
if ($this->Usermodel->email_exists()) {
//Get user email
$this->user_email = $this->input->post('email');
//create token
$this->reset_token = md5(str_shuffle($this->user_email));
//create url
$this->reset_url = base_url('changepasword/') . $this->user_email . '/'. $this->reset_token;
//create reset link
$this->reset_link = 'password reset link';
echo $this->reset_link;die();
$this->body = "Here is your $this->reset_link. \n\nAfter clicking it you will be redirected to a page on the website where you will be able to set a new pasword.";
// Send mail and rediect
$this->sendResetMail();
} else {
$this->session->set_flashdata('email_non_existent', "The email you provided does not exist in our database");
}
redirect('newpassword');
}
}
public function sendResetMail() {
// Loading the Email library
$config['protocol'] = 'sendmail';
$config['charset'] = 'utf-8';
$config['mailtype'] = 'html';
if(!$this->load->is_loaded('email')){
$this->load->library('email', $config);
} else {
$this->email->initialize($config);
}
// Build the body and meta data of the email message
$this->email->from($this->sender_email, $this->sender_name);
$this->email->to($this->user_email);
$this->email->subject($this->subject);
$this->email->message($this->body);
if($this->email->send()){
$this->session->set_flashdata('reset_mail_confirm', "A pasword reset link was send to the email address $this->user_email");
} else{
$this->session->set_flashdata('reset_mail_fail', "Our atempt to send a pasword reset link to $this->user_email has failed");
}
}
}
I have inspected the link, it is valid and the value of the href attribute is as intended, but once I remove echo $this->reset_link;die() I see the attempt to send the email failing:
Where is my mistake?
The email not sending issue can be from multiple reasons:
Codeigniter 3 email library is not configured correctly
test: use built in email() in php and test if that's working
php not configured correctly to send email
server is not configured for handing over emails
DNS has external mx records and local email is not forwarded out from the server
test: use external SMTP server (free gmail is fine) and configure like this the ci3 library https://forum.codeigniter.com/thread-75525-post-371979.html#pid371979
$config['protocol'] = 'smtp';
$config['smtp_host'] = 'ssl://smtp.googlemail.com';
$config['smtp_user'] = 'your_email';
$config['smtp_pass'] = 'your_password';
$config['smtp_port'] = 465;
$config['charset'] = 'utf-8';
$config['mailtype'] = 'html';
$config['newline'] = "\r\n";
if this is not working, check what's the cause by using
if ($this->email->send(FALSE))
{
echo $this->email->print_debugger();
}
server cannot access remote ports firewalls are not opened for this
test: disable firewall or selinux and test again
Are you running it locally? If so this might be the cause of the error. Can't send emails from local machines. If not check with your hosting company if it allows you to send mails via php. Most shared hostings disable this option and sell SMTP service to allow you to send emails
Have you tried loading a view into your email function? Then you could pass the content to that file and send a html email
This is what woked for me:
public function sendResetMail()
{
// Email settings
$config['protocol'] = 'sendmail';
$config['smtp_host'] = 'mail.mydomain.com';
$config['smtp_user'] = 'myemail#mydomain.com';
$config['smtp_pass'] = '******';
$config['smtp_port'] = 465;
$config['charset'] = 'utf-8';
$config['mailtype'] = 'html';
$config['newline'] = "\r\n";
if (!$this->load->is_loaded('email')) {
$this->load->library('email', $config);
} else {
$this->email->initialize($config);
}
// Build the body and meta data of the email message
$this->email->from($this->sender_email, $this->sender_name);
$this->email->to($this->user_email);
$this->email->subject($this->subject);
$this->email->message($this->body);
if ($this->email->send()) {
$this->session->set_flashdata('reset_mail_confirm', "A pasword reset link was send to the email address $this->user_email");
} else {
$this->session->set_flashdata('reset_mail_fail', "Our atempt to send a pasword reset link to $this->user_email has failed");
}
}
I am trying to send mass emails via Codeigniter email library. However, only the first few emails are sent successfully.
Here is my Mail_model
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Mail_model extends CI_Model{
public function __construct(){
parent::__construct();
$this->load->library('email');
}
public function send_mail($email, $firstname, $data){
$subject = $data['subject'];
$message = 'Dear '.$firstname.',<br /><br />'.$data['message'].'<br />'.DOMAIN_NAME;
//configure email settings
$config['protocol'] = 'smtp';
$config['smtp_timeout'] = 5;
$config['smtp_host'] = SMTP_HOST; //smtp host name
$config['smtp_port'] = SMTP_PORT; //smtp port number
$config['smtp_user'] = FROM_EMAIL;
$config['smtp_pass'] = FROM_PASSWORD; //$from_email password
$config['mailtype'] = 'html';
$config['charset'] = 'utf-8';
$config['wordwrap'] = TRUE;
$config['newline'] = "\r\n"; //use double quotes
$config['validation'] = TRUE;
$this->email->initialize($config);
//send mail
$this->email->from(FROM_EMAIL, DOMAIN_NAME);
$this->email->to($email);
$this->email->subject($subject);
$this->email->message($message);
//echo json_encode($this->email->print_debugger());
$this->email->send();
}//end method send_mail
}//end class
Here is the bit of code from my controller that I am calling send_mail function from the model
$customers = $this->customer_model->get_customers();
foreach($customers as $customer){
$this->mail_model->send_mail($customer['email'], $customer['firstname'], $this->input->post());
sleep(10);
}
I added sleep(10) at the end of the loop to see if everything will work fine but it does not help. I am using Gmail.
Here is my Main function
The user register successfully but don't receive any email.
public function register(){
$this->load->view("Home/home_header");
if(isset($_POST["user_register"])){
$this->form_validation->set_rules('name', 'First Name', 'alpha|htmlspecialchars|trim|required');
$this->form_validation->set_rules('username', 'Last Name', 'htmlspecialchars|trim|required');
$this->form_validation->set_rules('email', 'Email', 'valid_email|trim|required');
$this->form_validation->set_rules('confirm-mail', 'Confirm Email', 'valid_email|trim|required|matches[email]');
$this->form_validation->set_rules('password', 'Password', 'required');
$this->form_validation->set_rules('confirm-password', 'Confirm Password', 'required|matches[password]');
$this->form_validation->set_rules('address', 'Address', 'htmlspecialchars|trim|required');
$this->form_validation->set_rules('country', 'Country', 'required');
$this->form_validation->set_rules('male-female', 'Gender', 'required');
if($this->form_validation->run() == TRUE){
$status = 0;
$data = array();
$data["first-name"] = $_POST["name"];
$data["username"] = $_POST["username"];
$data["mail"] = $_POST["email"];
$data["confirm-mail"] = $_POST["confirm-mail"];
$data["password"] = hash('md5',$_POST["password"]);
$data["confirm-password"] = hash('md5',$_POST["confirm-password"]);
$data["address"] = $_POST["address"];
$data["country"] = $_POST["country"];
$data["male-female"] = $_POST["male-female"];
$data["status"] = $status;
$email = $_POST["email"];
$saltid = md5($email);
if($this->db->insert("register",$data)){
if( $this->User_functions->sendmail($email,$saltid)){
//echo 'Succesful';
redirect(base_url().login);
}else{
echo "Sorry !";
}
}
}
}
$this->load->view("Home/user_registration");
$this->load->view("Home/home_footer");
}
And Here's the mail function. I am getting user email from the input and store the user record to the database. Record stores successfully and page redirects to the login page. But the user don't get email on registration. Help me to resolve this issue.
function sendmail($email,$saltid){
// configure the email setting
$config['protocol'] = 'smtp';
$config['smtp_host'] = 'ssl://smtp.gmail.com'; //smtp host name
$config['smtp_port'] = '465'; //smtp port number
$config['smtp_user'] = '*******#gmail.com';
$config['smtp_pass'] = '***********'; //$from_email password
$config['mailtype'] = 'html';
//$config['charset'] = 'iso-8859-1';
//$config['wordwrap'] = TRUE;
$config['newline'] = "\r\n"; //use double quotes
//$this->email->initialize($config);
$this->load->library('email', $config);
$url = base_url()."user/confirmation/".$saltid;
$this->email->from('gulfpro354#gmail.com', 'GulfPro');
$this->email->to($email);
$this->email->subject('Please Verify Your Email Address');
$message = "<html><head><head></head><body><p>Hi,</p><p>Thanks for registration with DGaps.</p>
<p>Please click below link to verify your email.</p>".$url."<br/><p>Sincerely,</p><p>DGaps Team</p></body></html>";
$this->email->message($message);
return $this->email->send();
}
If I used any wrong code for this, also highlight that code.
Thanks
Ammar Khaliq
Please use :
echo $this->email->print_debugger();
after $this->email->send(); by remove return
It will show you the reason why you are not able to send an email
I have used this method of email.
public function sendmail($user_id, $email){
require("plugins/mailer/PHPMailerAutoload.php");
$mail = new PHPMailer;
$mail->SMTPOptions = array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
);
//$mail->SMTPDebug = 2; // Enable verbose debug output
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'smtp.gmail.com'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'example#gmail.com'; // SMTP username
$mail->Password = 'password'; // SMTP password
$mail->SMTPSecure = 'ssl'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 465; // TCP port to connect to
//Recipients
$from = "example#gmail.com";
$from_label = "ABC";
$subject = "Please verify your email address.";
$url = base_url()."user/".$user_id."/".md5($user_id);
$message = "<p>Hi,</p><p>Thanks for registration with Portfolio Times.</p>
<p>Please click below link to verify your email.</p>".$url."<br/><p>Sincerely,</p><p>DGaps Team</p>";
$mail->setFrom($from,$from_label);
$mail->addAddress($email);
$mail->isHTML(true);
$mail->Subject = $subject;
$mail->Body = $message;
$mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
//$mail->SMTPDebug = 2;
if( !$mail->send()){
echo 'Mailer Error: ' . $mail->ErrorInfo;
} else {
echo "<div class='alert alert-success pull-right' style='width:400px' align='center'>".'×'."Email Sent Successfully...</div>";
//return true;
}
}
I am trying to send forgot password link to gmail. but can't get success.
Here is my little code. I have my config file here. If any changes needed then please suggest. I am using two gmail account to send mail from one gmail account to other gmail account.
Here is my config file email.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
$config = Array(
$config['protocol'] = 'smtp',
$config['smtp_host'] = 'ssl://smtp.gmail.com',
$config['smtp_port'] = '465',
$config['smtp_timeout'] = '7',
$config['smtp_user'] = 'xyz#gmail.com',
$config['smtp_pass'] = '123',
$config['charset'] = 'utf-8',
$config['newline'] = "\r\n",
$config['mailtype'] = 'text', // or html
$config['validation'] = TRUE // bool whether to validate email or not
);
Here is my code for deliver mail.
if($this->form_validation->run())
{
//echo 1;
//echo validation_errors();
$this->load->library('email');
$reset_key = md5(uniqid());
$this->load->model('User_Model');
if($this->User_Model->update_reset_key($reset_key))
{
$this->email->from('xyz#gmail.com', 'data-+-');
$this->email->to($this->input->post('email'));
$this->email->subject('Reset you account password at Mahesh Makwana');
$message = "<p><h4>You or someone request to reset your password.</h4></p>";
$message.="<a href='".base_url(). "reset_password/".$reset_key."'>Click here to reset your password</a>";
$this->email->message($message);
if($this->email->send())
{
echo 'Kindly check your email '.$this->input->post('email').' to reset your password';
}
else
{
echo 'Cannot send email! Kindly contact to our customer service to help you.!';
}
}
else{
echo 1;
}
}
else
{
//echo 0;
//echo validation_errors();
$this->load->view('include/forgetpassword');
}
Nothing wrong in your code. Its might be because of google security. Try to allow access for 'Less secure apps' in google account settings after logging in to your account
https://www.google.com/settings/security/lesssecureapps
Manage your configuration setting like below:
$config['protocol'] = 'smtp';
$config['smtp_host'] = 'ssl://smtp.gmail.com';
$config['smtp_port'] = '465';
$config['smtp_timeout'] = '7';
$config['smtp_user'] = 'xyz#gmail.com';
$config['smtp_pass'] = 'xxxxx';
$config['charset'] = 'utf-8';
$config['newline'] = "\r\n";
$config['mailtype'] = 'text' // or html
$config['validation'] = TRUE; // bool whether to validate email or not
Then after loading email library set configuration using $this->email->initialize($config);
$this->load->library('email');
$this->email->initialize($config);
I am trying to email a basic contact form using PHPMailer.
This form works for me:
<?php
$first_name = $_POST['first-name'];
$last_name = $_POST['last-name'];
$email = $_POST['email'];
$message = nl2br($_POST['message']);
require 'PHPMailerAutoload.php';
$mail = new PHPMailer;
//$mail->SMTPDebug = 3; // Enable verbose debug output
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = ''; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = ''; // SMTP username
$mail->Password = ''; // SMTP password
$mail->SMTPSecure = 'tls'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 587;
$mail->addReplyTo( $email, $first_name );
$mail->addAddress( $email, $first_name );
$mail->addAddress( 'blah#fake.org', 'Staff' );
$mail->From = 'blah#fake.org';
$mail->FromName = 'Staff';
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = 'Hotel Room Request';
$mail->Body = $message;
$mail->AltBody = 'To view the message, please use an HTML compatible email viewer!';
if(!$mail->send()) {
header('location: a_url_here');
} else {
header('location: a_url_here');
}
Now, I'm trying to combine it with error-checking. Don't know how to combine it and still make it work. This is what I have so far, and it blanks out upon submittal. I wasn't sure where to put check_input function, so I put it in the else part at the bottom. How do I make this form functional so not only does it validate user's input but email it out?
<?php
$first_name = check_input($_POST['first-name'], "Please enter your name");
$last_name = check_input($_POST['last-name'], "Please enter your last name");
$email = check_input($_POST['email'], "Please enter your email address");
$message = check_input(nl2br($_POST['message']), "Please enter your message");
require 'PHPMailerAutoload.php';
$mail = new PHPMailer;
//$mail->SMTPDebug = 3; // Enable verbose debug output
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = ''; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = ''; // SMTP username
$mail->Password = ''; // SMTP password
$mail->SMTPSecure = 'tls'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 587;
$mail->addReplyTo( $email, $first_name );
$mail->addAddress( $email, $first_name );
$mail->addAddress( 'blah#fake.org', 'Staff' );
$mail->From = 'blah#fake.org';
$mail->FromName = 'Staff';
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = 'Hotel Room Request';
$mail->Body = $message;
$mail->AltBody = 'To view the message, please use an HTML compatible email viewer!';
if(!$mail->send()) {
header('location: a_url_here');
} else {
function check_input($data, $problem = ' ')
{
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
if ($problem && strlen($data) == 0)
{
show_error($problem);
}
return $data;
}
}
?>
Create so-called validator class:
class Validator {
// set of rules for validator
// syntax: <field-name> => '<list-of-rules, joined-with-pipe>',
protected $rules = [
'first-name' => 'required',
'last-name' => 'required',
'message' => 'required',
'email' => 'required|email',
];
// message to show if concrete field-rule failed
// ":field" will be replaced with field actual name
protected $messages = [
'required' => 'Field :field is required',
'nonzero' => 'Field :field must not be zero'
'email' => 'Field :field must represent an emai address'
];
protected $errors;
// call this to validate provided $input
function validate($input) {
$errors = [];
// for each defined field-ruleset
foreach ($this->rules as $field => $rules) {
$rules = explode('|', $rules);
// for each rule
foreach ($rules as $rule)
// call function with name "checkNameofrule"
if (!$this->{"check" . ucfirst($rule)}($input, $field))
// memorize error, if any
$errors[$field][] = $this->error($field, $rule);
}
// validation passed if there are no errors
return !($this->errors = $errors);
}
function errors() {
return $this->errors;
}
function error($field, $error) {
return str_replace(':field', $field, $this->messages[$field]);
}
// check for required fields
function checkRequired($input, $field) {
if (!isset($input[$field]))
return false;
return trim(htmlspecialchars(stripslashes($input[$field]))) != '';
}
// check for valid email
function checkEmail($input, $field) {
return !!preg_match('#.+#[^.]+\..+#', #$input[$field]);
}
// other custom checks
function checkNonzero($input, $field) {
return intval(#$input[$field]) != 0;
}
}
And use it like this:
$validator = new Validator();
// validating...
if (!$validator->validate($_POST)) {
// looks like there are errors in input
echo "<div class=\"errors\">";
echo "<b>Looks like you have errors in input:</b><br />";
foreach ($validator->errors() as $field => $errors) {
foreach ($errors as $error)
echo "<p>{$error}</p>";
}
echo "</div>";
} else {
// input had passed validation, send email...
require 'PHPMailerAutoload.php';
$mail = new PHPMailer;
...
if(!$mail->send()) {
header('location: a_url_here');
} else {
header('location: a_url_here');
}
}
You should not validate and render the form in one file. It leads to poor maintainability and mixes responsibilities in a nasty way. Try structuring your project like so:
form.php
validate-and-send.php
The form contains <form action=validate-and-send.php ...><input ....
The other file contains logic for validating and sending. Something like this:
<?php
$email = filter_var($_REQUEST['email'], FILTER_VALIDATE_EMAIL);
if ($email) {
....
}
if (/*all fields valid*/) {
// phpmailer code
} else {
// redirect back to form
}
The tricky part is redirect back to form. You can either redirect with a header and set all valid fields through get-parameters Location form.php?name=validname or you can stuff them in $_SESSION and output them in the form from session.
Taking it one step farther would be submitting via AJAX and responding with the validation result as JSON, for example. So the flow would be like
1. form.submit() -> ajax -> validate-and-send.php
2a. validate-and-send.php -> "OK" -> form.php
2b. validate-and-send.php -> JSON: { errors: [ {reason: "bad name"}, {reason: "bad email"}]}
-> form.php
3. Display what happened with JS.