I know - there are already discussions concerning this, but they all didn't help.
All I want is to send a simple html mail - with:
$this->load->library('email');
$this->email->from('me#myadress.de', 'My name');
$this->email->to('me#home.de');
$this->email->subject('Email Test');
$this->email->message('test'); # for test only - normally I load a html view
$this->email->send();
Works fine with the default configuration ($config['mailtype'] = 'text';), but when I change it to $config['mailtype'] = 'html'; - I just get
Unable to send email using PHP mail(). Your server might not be configured to send mail using this method.
The only answers I found was to use SMPT - but I would prefer a solution using sendmail. (I'm pretty sure sendmails supports html mails. ^^)
Any other hints? I've no idea how to debug this... the email-print looks ok to me.
If you want to send an html as a email, please check the below controller file
class Mail extends CI_Controller {
function __construct()
{
parent::__construct();
$this->load->helper(array('form', 'url'));
}
public function index()
{
$config = array(
'protocol' => 'smtp',
'smtp_host' => 'tls://smtp.gmail.com',
'smtp_port' => 465,
'smtp_user' => 'xxx#gmail.com',
'smtp_pass' => '*********',
'mailtype' => 'html',
'charset' => 'utf-8'
);
$this->load->library('email', $config);
$this->email->set_newline("\r\n");
$this->email->from('xxx#gmail.com');
$this->email->to("yyyy#gmail.com");
$this->email->subject('Test Email');
$body = $this->load->view('welcome_message',null,TRUE);
$this->email->message($body);
if (!$this->email->send()){
echo 'fail to load email';
}
else {
echo 'success to send email';
}
}
}
Where welcome_message is the html view file which you want to send as a mail body
Related
I am using yii2 default contact us page to get mail from user.. It is working fine but I am getting mail from email which I mention in code, to adminEmail which is also my email id.
here is code=>
public function sendEmail($email)
{
return Yii::$app->mailer->compose()
->setTo($email)
->setFrom([$this->email => $this->name])//want the data from email field..how to achieve that??
->setSubject($this->subject)
->setTextBody($this->body)
->send();
}
if I try like this ->setFrom([$this->email => $this->email]) in above code I get 2 email id in recieved email
1st $this->email is username which is mention in mailer of below code
2nd $this->email is email id which is filled in contact us form which I want.
in file- common\config\main-local.php
'mailer' => [
'class' => 'yii\swiftmailer\Mailer',
'useFileTransport' => false,
'transport' => [
'class' => 'Swift_SmtpTransport',
'host' => 'smtp.gmail.com',
'username' => 'pharmadarshu#gmail.com',
'password' => '*****',
'port' => '587',
'encryption' => 'tls',
],
but then I am unable to get name ? I want to receive all fields of contact us form i.e. name, email, subject, body ? I fact all are getting properly except email? can anyone help??
hope described properly my question..
If you are using the default ContactForm model you simply need to create a table in database.
It can have fields like name and email
Add the tableName method in your Contact form model
public static function tableName()
{
return '{{%contact_table name}}';
}
Then in Yii contact action after validation call the save method
/**
* Displays contact page.
*
* #return mixed
*/
public function actionContact()
{
$model = new ContactForm();
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
//save data
$model->save();
//end save
if ($model->sendEmail(Yii::$app->params['adminEmail'])) {
Yii::$app->session->setFlash('success', 'Thank you for contacting us. We will respond to you as soon as possible.');
} else {
Yii::$app->session->setFlash('error', 'There was an error sending email.');
}
return $this->refresh();
} else {
return $this->render('contact', [
'model' => $model,
]);
}
}
Add email to the body
public function sendEmail()
{
return Yii::$app
->mailer
->compose(
['html' => 'passwordResetToken-html', 'text' => 'passwordResetToken-text'],
['user' => $user]
)
->setFrom([Yii::$app->params['supportEmail'] => Yii::$app->name . ' robot'])
->setTo($this->email)//$this->email can be added to the message body
->setSubject('Password reset for ' . Yii::$app->name)
->send();
}
Is it possible to run a web action in a console controller?
In a web controller (yii\web\Controller) I have an action which I would like to run as a cron job. But if I try to run it in a console controller (yii\console\Controller):
Yii::$app->runAction('controller/action');
then I receive the following error message:
Error: Unknown command "controller/action".
Run a web action in a console controller:
Yii::$app->controllerNamespace = "app\controllers";
Yii::$app->runAction('controller/action');
Assign controllerNamespace before running the web action from console.
In addition, disable enableCsrfValidation for the web action:
public function beforeAction($action)
{
if ($action->id == 'action') {
$this->enableCsrfValidation = false;
}
return parent::beforeAction($action);
}
The 'action' ID could be replaced with your current web action ID.
Sorry, I did not understand the context of the question.
As #soju says, you should find a way to do it using CURL, but there is a way.
$config = \yii\helpers\ArrayHelper::merge(
require(Yii::getAlias('#common').'/config/main.php'),
require(Yii::getAlias('#common').'/config/main-local.php'),
require(Yii::getAlias('#frontend').'/config/main.php'),
require(Yii::getAlias('#frontend').'/config/main-local.php')
);
$web_application = new \yii\web\Application($config);
$web_application->runAction('/site/index',['param1' => 1,'param2' => 2]);
You should be aware that the controller works with their behaviors, then the AccessControl could prevent the execution
The solution with cURL.
In the web controller have to be disabled the CSRF validation:
public function beforeAction() {
if ($this->action->id == 'export') {
Yii::$app->controller->enableCsrfValidation = false;
}
return true;
}
The cURL commands in the console Controller can look e.g. like this:
$ch = curl_init();
$options = array(
CURLOPT_URL => $url,
CURLOPT_REFERER => $url,
CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_COOKIESESSION => true,
CURLOPT_COOKIEJAR => 'curl-cookie.txt',
CURLOPT_COOKIEFILE => '/var/www/yii/frontend/web/tmp',
CURLOPT_CONNECTTIMEOUT => 120,
CURLOPT_TIMEOUT => 120,
CURLOPT_MAXREDIRS => 10,
CURLOPT_USERAGENT => "Dark Secret Ninja/1.0",
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => "LoginForm[username]=".$username.
"&LoginForm[password]=".$password.
"&LoginForm[rememberMe]=1",
CURLOPT_SSL_VERIFYPEER => false,
);
curl_setopt_array( $ch, $options );
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); //get status code
if ( $httpCode != 200 ){
echo "Return code is {$httpCode} \n"
.curl_error($ch);
} else {
echo htmlspecialchars($response);
}
curl_close($ch);
I have a route group that looks like this:
Route::group(['prefix' => 'recipe','middleware'=>['auth.basic']], function (){
//Some things to do
});
When credentials are invalid Laravel outputs "Invalid credentials." How do I override this response with my own JSON response?
In AuthController, try this :
public function postLogin(Request $request)
{
$this->validate($request, [
'email' => 'required', 'password' => 'required',
]);
$credentials = [
'email' => $request->input('email'),
'password' => $request->input('password')
];
if (Auth::attempt($credentials, $request->has('remember')))
{
return redirect()->intended($this->redirectPath())
->with('success', 'You are successfully logged in');
}
return Response::json(array(
'success' => false,
'errors' => $this->getFailedLoginMessage(),
));
}
I just had a look at the Illuminate\Auth\SessionGuard. The method getBasicResponse() seems to be responsible for the response on a failed login attempt (with basic auth).
protected function getBasicResponse()
{
$headers = ['WWW-Authenticate' => 'Basic'];
return new Response('Invalid credentials.', 401, $headers);
}
How to actually overwrite it seems a little tricky though. You probably need to extend the SessionGuard Class and implement your own getBasicResponse() method. Thats the easy part, how to actually instantiate your own guard instead of the default one, I don't know yet.
I'm having an issue validation whether a submitted Email Address is Unique in the database.
When the User registers I need to validate whether the email address exists all of the other validation is working fine.
Is there a step missing when you are validating a using an Ajax form in Yii 2.
A User clicks on CTA to register on site/index
use yii\bootstrap\Modal;
use frontend\models\Register;
use yii\helpers\Html;
use yii\helpers\Url;
...
Modal::begin([
'id' => 'modal',
'size'=>'modal-lg',
'clientOptions' => ['backdrop' => 'static', 'keyboard' => FALSE],
]);
echo "<div id='modalContent'></div>";
Modal::end();
?>
<?= Html::button('Register', ['value' => Url::to(['register/create']), 'title' => 'Register', 'class' => 'btn btn-success','id'=>'modalButton']); ?>
This opens up a modal (register/create)
Model Register
class Register extends User
{
...
public function rules()
{
return [
['Email', 'filter', 'filter' => 'trim'],
['Email', 'required'],
['Email', 'email'],
['Email', 'unique', 'targetClass' => '\common\models\User', 'message' => 'This email address has already been taken.'],
];
}
public function signup()
{
$user = new User();
if ($this->validate()) {
$user->Email = $this->Email;
if ($user->save()) {
return $user;
}
} else {
return;
}
}
Register Controller
public function actionCreate()
{
$model = new Register(['scenario' => 'signup']);
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
Yii::$app->response->format = Response::FORMAT_JSON;
Yii::error($model);
return $model->validate();
}
if ($model->load(Yii::$app->request->post())) {
if ($user = $model->signup()) {
if (Yii::$app->getUser()->login($user)) {
return $this->goHome();
}
}
}
return $this->renderAjax('create', [
'model' => $model,
]);
}
The View file
<?php $form = ActiveForm::begin(['id'=> 'register', 'enableClientValidation'=>true, 'enableAjaxValidation'=>true, 'validateOnChange'=> true, 'validationUrl' => Url::to(['register/create'])] ); ?>
<div class="form-group">
<?= $form->field($model, 'Email') ?>
</div>
Javascript file
$script = <<< JS
$('body').on('beforeSubmit', 'form#register', function (event, jqXHR, settings) {
var form = $(this);
// return false if form still have some validation errors
if (form.find('.has-error').length) {
return false;
}
// submit form
$.ajax({
url: form.attr('action'),
type: 'GET',
data: form.serialize(),
success: function (response) {
// do something with response
$(document).find('#modal').modal('hide');
}
});
return false;
});
JS;
$this->registerJs($script);
I was facing a similar issue where my email field was not triggering the "unique" rule in the javascript validation, but the "unique" rule was getting triggered on the form submit.
It's awesome that you came up with a solution for your question that gets the job done, but I think what I just learned could also shed some insight on this question for others.
The key for me was learning/realizing that the "unique" validation rule must use a database lookup to verify if the user input is unique, thus it must use ajax. Other validation rules, such as "required" or "email" don't need ajax to validate. They just use javascript in the client to validate, so they are client validation, whereas the "unique" validator is actually ajax validation.
Note: my code below is not really addressing your code directly, but is intended to communicate the overall understanding and code structure that is needed to answer your question. Some of these steps you already have, but some are missing :)
First, you need a model with a field that requires a 'unique' rule, such as an email address for a user account.
In your Model
public function rules()
{
$rules = [
[['email'], 'unique'],
// ... and all your other rules ...
];
}
When using \yii\widgets\ActiveForm, client validation is enabled by default, but ajax validation is not.
So, next you need to directly turn on ajax validation in the view. This can be done either for the entire form, or just for a single field. The Yii2 Validation docs explain this best, but in my case, I chose to just enable ajax validation on my email field.
In your View
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($user, 'email', ['enableAjaxValidation' => true])->textInput();
//... other form fields and such here ...
<?php ActiveForm::end(); ?>
Next, you also need to handle the ajax validation in your controller, so your controller method could look something like this:
public function actionRegister()
{
$user = new User();
$post = Yii::$app->request->post();
$userLoaded = $user->load($post);
// validate for ajax request
if (Yii::$app->request->isAjax) {
Yii::$app->response->format = Response::FORMAT_JSON;
return ActiveForm::validate($user);
}
// vaidate for normal request
if ($userLoaded && $user->validate()) {
$user->save();
return $this->redirect(['view', 'id' => $user->id]);
}
// render
return $this->render('create', ['user' => $user]);
}
And then here's the catch ... everything above is what you would need when working with a normal (non-ajax) form. In your question, you are working on a form in a modal window that is being submit via ajax, so the above controller method will not work. With ajax forms, it becomes pretty tricky to handle the ajax form validation and the ajax form submit in the same controller method.
As usual, Yii has this all figured out for us, and the validationUrl form parameter will save the day. All you have to do is create a new method in your controller that is specifically for ajax validation, and reference the controller/action URL in your form. Something like this should do the trick:
In your View
<?php $form = ActiveForm::begin([
'id' => 'form-id', // always good to set a form id, especially when working with ajax/pjax forms
'validationUrl' => ['user/validate-email'], //['controller/action'],
]); ?>
In your Controller
public function actionRegister()
{
$user = new User();
$post = Yii::$app->request->post();
// vaidate for normal request
if ($user->load($post) && $user->validate()) {
$user->save();
return $this->redirect(['view', 'id' => $user->id]);
}
// render
return $this->render('create', ['user' => $user]);
}
public function actionValidateEmail()
{
// validate for ajax request
if (Yii::$app->request->isAjax) {
Yii::$app->response->format = Response::FORMAT_JSON;
$user = new User();
$post = Yii::$app->request->post();
$user->load($post);
return ActiveForm::validate($user);
}
}
Cheers!
I managed to solve this myself by using Javascript to make an Ajax request and PHP to receive the quest and check whether the Email already exists in the database.
function checkEmail(){
var email_check;
// Get the value of the email input field
var input_value = document.getElementById('register-email').value;
// Send the value to a PHP page to check
$.ajax({
url: 'checkemail.php/',
type: 'POST',
data: {
email_check: input_value
},
success: function(response) {
// If we have a repsonse we need to check whether it is True or False
email_check = response;
if (email_check == 1) {
// If True add error class
$('.field-register-email').addClass('has-error');
$('.field-register-email .help-block').text('The email supplied has already been used');
} else {
$('.field-register-email').removeClass('has-error');
$('.field-register-email .help-block').text(' ');
}
}
});
};
This will send a POST request to the checkemail.php which will check whether the email address is in the database
Im trying to send an email not using templates, the email is sent with the right subject but the message is always blank.
public function sendEmail($token = null, $recipient = null)
{
$path = "http://$_SERVER[HTTP_HOST]";
$controller = "/users/activate/";
$message = $path . $controller . $token;
$Email = new Email();
$Email->profile(['from' => 'xxxxxxxxxxxxx#gmail.com', 'transport' => 'default']);
$Email->to($recipient);
$Email->subject('Verification Email');
$Email->message('test');
//$Email->message($message);
if ( !$Email->send() ) {
$response = array('success' => false, 'message' => __('Error sending email', true),);
$this->sendResponse($response);
}
}
I've tried both a variable or plain text and it keeps sending the emails blank.
Any example of how to assign the message properly?
I kept testing and this is the correct way t assign the message to a simple email:
$Email->send($message);