I have a problem here. I created a Contact form in my webpage, which includes: name, surname, email and description. When I submit my form, the email sends, but the senders email is my email. F.e:
http://imageshack.com/a/img922/801/eVyutz.png
my.email#gmail.com shows not the email, which user entered in a form, but mine. And after that when I click Reply button and type a message back, I send it to myself. Why?
Here is what I did:
My mailer:
'mailer' => [
'class' => 'yii\swiftmailer\Mailer',
'useFileTransport' => false,
'transport' => [
'class' => 'Swift_SmtpTransport',
'host' => 'smtp.gmail.com',
'username' => 'my.email#gmail.com',
'password' => 'password',
'port' => '465',
'encryption' => 'ssl',
'streamOptions' => [ 'ssl' =>
[ 'allow_self_signed' => true,
'verify_peer' => false,
'verify_peer_name' => false,
],
]
],
],
My actionContact():
public function actionContact()
{
$model = new Contact();
$model->scenario = Contact::SCENARIO_CREATE;
if ($model->load(Yii::$app->request->post()) && $model->save()) {
if ($model->sendEmail(Yii::$app->params['adminEmail'])) {
Yii::$app->getSession()->setFlash('success', Yii::t('app', 'Success'));
}
else {
Yii::$app->getSession()->setFlash('error', Yii::t('app', 'Failed'));
}
return $this->refresh();
} else {
return $this->render('contact', [
'model' => $model,
]);
}
}
And my model function:
public function sendEmail($email)
{
return Yii::$app->mailer->compose()
->setTo($email)
->setFrom([$this->email => $this->name." ".$this->surname])
->setSubject($this->subject)
->setTextBody($this->text)
->send();
}
Please help me to solve this, what is wrong? Thank you for any help!
I guess there will be something wrong with $email variable. Because when I use setFrom to email, it shows just my email.
could be you have not assigned a proper value for $this->email (try check for this eg: with var_dump($this->email) and for $this->name and $this->username)
you could use a proper param assigned in param.php
<?php
return [
'adminEmail' => 'my_mail#my_domain.com',
];
.
public function sendEmail($email)
{
return Yii::$app->mailer->compose()
->setTo($email)
->setFrom([\Yii::$app->params['adminEmail'] => $this->name." ".$this->surname])
// ->setFrom([\Yii::$app->params['adminEmail'] => 'try fixed test if $this->name and username not work'])
->setSubject($this->subject)
->setTextBody($this->text)
->send();
}
Related
I made the validation in the config / validation.php with references from the official documentation https://codeigniter4.github.io/userguide/libraries/validation.html like this:
class Validation
{
....
public $user = [
'name' => [
'rules' => 'required'
],
'email' => [
'rules' => 'valid_email|required',
'errors' => [
'valid_email' => 'E-mail is not valid',
'required' => 'E-mail is required'
]
]
];
}
and then I call it on my controller like this:
....
class User extends ResourceController
{
public function create()
{
$name = $this->request->getPost('name');
$email = $this->request->getPost('email');
$country = $this->request->getPost('country');
$province = $this->request->getPost('province');
$city = $this->request->getPost('city');
$day_of_birth = $this->request->getPost('day_of_birth');
$password = $this->request->getPost('password');
$phone_number = $this->request->getPost('phone_number');
$photo = $this->request->getPost('photo');
$data = [
'name' => $name,
'email' => $email,
'country' => $country,
'province' => $province,
'city' => $city,
'day_of_birth' => $day_of_birth,
'password' => $password,
'phone_number' => $phone_number,
'photo' => $photo
];
$validate = $this->validation->run($data,'user');
$errors = $this->validation->getErrors();
if($errors){
return $this->fail($errors);
}
return $this->respond($data);
}
}
when i tested it using postman, I get a return like this:
the validation works fine if I do it in the controller, but I want to declare the validation in validation.php, someone please help me, whatever I write in validation.php then i call using $this->validation->run($data,'name') always returns the same
You have not added the error message in the name required validation so maybe it's the problem so you must add an error message to the name.
Because validation in the message is important . Without any error messages, how can the user know what is the problem in the form.
Here is the customized function or sample of validation. change your function be like.
class Validation
{
public $user = [
'name' => [
'rules' => 'required',
'errors' => [
'required' => 'Name is required.'
]
],
'email' => [
'rules' => 'required|valid_email',
'errors' => [
'valid_email' => 'E-mail is not valid',
'required' => 'E-mail is required'
]
],
];
}
I try to return blank body in my rest controller, but instead it returns 'null'.
I already tried to use in the last line of script
\Yii::$app->response->setStatusCode(200);
and get the same result.
I use advanced template and custom rest logic.
Controller extends yii\rest\Controller
There is my configurations in main.php file
return [
'id' => 'app-api',
'basePath' => dirname(__DIR__),
'controllerNamespace' => 'api\controllers',
'bootstrap' => ['log'],
'modules' => [],
'components' => [
'request' => [
'parsers' => [
'application/json' => 'yii\web\JsonParser',
],
],
'user' => [
'identityClass' => 'common\models\User',
'enableAutoLogin' => false,
'enableSession' => false,
],
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
'GET add' => 'api/add',
'GET feed' => 'api/feed',
'GET remove' => 'api/remove',
],
],
],
'params' => $params,
];
Here is my action
public function actionAdd()
{
try
{
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
$request = \Yii::$app->request;
$id = $request->get('id');
$user = $request->get('user');
$secret = $request->get('secret');
if(!$id || !$user || !$secret)
{
$this->setStatus(500);
return [
'error' => 'missing parameter'
];
}
if(!$this->checkSecret($secret, [$id, $user]))
{
$this->setStatus(500);
return [
'error' => 'access denied'
];
}
$existing = Subscribers::find()->where(['user' => $user])->count();
if($existing)
{
$this->setStatus(500);
return [
'error' => 'user already exists in database'
];
}
$subscriber = new Subscribers();
$subscriber->user = $user;
//$subscriber->save();
/*
* expected 200 OK and blank body
* returns 200 OK and 'null'
*/
return \Yii::$app->response->setStatusCode(200)->send();
}catch (\Exception $exception)
{
$this->setStatus(500);
return [
'error' => 'internal error'
];
}
}
I don't have any behaviors, maybe I should?
Empty string is invalid JSON, so returning response with empty body and content-type: application/json header is incorrect. You may want to use Response::FORMAT_RAW instead of Response::FORMAT_JSON in that case:
Yii::$app->response->format = Response::FORMAT_RAW;
return;
This will return empty body with content-type: text/html header.
But if you really want to pretend that your response is JSON and return empty body, you may set $content property directly - this will skip formatting of response:
Yii::$app->response->format = Response::FORMAT_JSON;
Yii::$app->response->content = '';
return;
I have a test in php that fails now that I use the create method. When using this controller function online it works fine but the test fails. This is the test
public function testSendContactMail()
{
$response = $this->call('POST','/contact-us',[
'name' => '',
'phone' => '',
'email' => '',
'message' => '',
'contact' => '',
'help' => '$request->input()',
'list' => '$request->input()'
]);
$response->assertStatus(201);
}
This is the controller function being called with the route
public function sendMail(Request $request){
$contact = EmailMessage::create([
'first_name' => $request->input('firstName'),
'last_name' => $request->input('lastName'),
'phone_number' => $request->input('phone'),
'email' => $request->input('email'),
'message' => $request->input('message'),
'contact_preference' => $request->input('contact'),
'help_you_with' => $request->input('help'),
'email_list' => ($request->input('toList'))? true : false,
]);
if($contact){
Mail::to('test#test.com')
->queue(new ContactUs($contact));
Mail::to($contact->email)
->queue(new ContactUs($contact));
return Response::json([], 201); // Status code here
}else{
return Response::json([], 500);
}
}
This is the data I pass to the controller:
{
firstName: this.contactForm.firstName,
lastName: this.contactForm.lastName,
phone: this.contactForm.phoneNunber,
email: this.contactForm.email,
message: this.contactForm.message,
help: this.contactForm.help,
list: this.contactForm.mailingList,
contact: this.contactForm.contact
}
Not sure what is going on
With the code below my emails would send fine in dev mode. Now that I've put my App into production mode when I try to trigger one of the actions to send an email the page just loads and loads until I get the CakePHP error. The data still goes into the database however.
'EmailTransport' => [
'default' => [
'className' => 'Mail',
// The following keys are used in SMTP transports
'host' => 'localhost',
'port' => 25,
'timeout' => 30,
'username' => 'user',
'password' => 'secret',
'client' => null,
'tls' => null,
'url' => env('EMAIL_TRANSPORT_DEFAULT_URL', null),
],
'mailjet' => [
'host' => 'in-v3.mailjet.com',
'port' => 587,
'timeout' => 60,
'username' => 'removed',
'password' => 'removed',
'className' => 'Smtp'
],
],
public function register()
{
$user = $this->Users->newEntity();
if ($this->request->is('post')) {
$user = $this->Users->patchEntity($user, $this->request->data);
$user->role = 'user';
$user->email_verified = '0';
$user->email_token = Security::hash($user->username + microtime(), 'sha1', true);
$user->email_token_expires = strtotime('now');
$user->email_token_expires = strtotime('+1 hour');
if ($result = $this->Users->save($user)) {
$this->Users->lastLogin($user['id']);
$authUser = $this->Users->get($result->id)->toArray();
$this->Auth->setUser($authUser);
$email = new Email();
$email->template('confirm')
->transport('mailjet')
->emailFormat('both')
->viewVars(['token' => $user->email_token])
->to($this->Auth->user('email'))
->from(['removed' => 'Welcome, ' . $user->username . '!'])
->subject('Please confirm your email!')
->send();
$this->Flash->success('You have successfully registered. Check your email to confirm email.');
return $this->redirect(['action' => 'profile']);
} else {
$this->Flash->error('The user could not be saved. Please, try again.');
}
}
$this->set(compact('user', 'userEmail', 'token'));
$this->set('_serialize', ['user']);
}
What could it be?
Error:
Connection timed out
Cake\Network\Exception\SocketException
Last time I got this error, the smtp address was blocked in my production server.
After whitelisting the smtp address everything was fine.
How to prevent users log in without mail confirmation?
The database set correct. When user confirms the registration by clicking the link in the received message, the value "confirmed" changes from 0(default) to 1. Of course boolean type. I need "else if" statement to work, but I can't figure out how. Here is my code:
public function postSignin(Request $request)
{
$this->validate($request, [
'email' => 'required',
'password' => 'required'
]);
if (!Auth::attempt($request->only(['email', 'password']),
$request->has('remember')))
{
return redirect()->back()->with(notify()->flash("Ooops..", "error", [
'timer' => 5000,
'text' => 'Could not sign in with those details',
]));
}
else if ((Auth::attempt($request->only(['email', 'password'])))&&('confirmed'===0))
{
return redirect()->back()->with(notify()->flash("Ooops..", "error", [
'timer' => 5000,
'text' => 'Activate your account',
]));
}
else
{
return redirect()->route('home');
}
}
public function postSignin(Request $request)
{
$this->validate($request, [
'email' => 'required',
'password' => 'required'
]);
// This line will always log the user **in** if the account is confirmed or not.
if (!Auth::attempt($request->only(['email', 'password']),
$request->has('remember')))
{
return redirect()->back()->with(notify()->flash("Ooops..", "error", [
'timer' => 5000,
'text' => 'Could not sign in with those details',
]));
}
else if (!Auth::attempt(["email"=>$request->input("email"),"password"=>$request->input('password'),"confirmation"=>1])
{
return redirect()->back()->with(notify()->flash("Ooops..", "error", [
'timer' => 5000,
'text' => 'Activate your account',
]));
}
else
{
return redirect()->route('home');
}
}