Send email and get reply in laravel form - laravel

I'm succeed to send mail from contact form, and now my requirement is to get automated success reply to the users input email address when submitting the form. please help me on this
ContactUsController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use App\Mail\ContactUs;
class ContactUsController extends Controller
{
function index()
{
return view('home/contactus');
}
function send(Request $request)
{
$this->validate($request,[
'name' => 'required',
'email' => 'required|email',
'subject' => 'required',
'message' => 'required'
]);
$data = array(
'name' => $request->name,
'email' => $request->email,
'subject' => $request->subject,
'message' => $request->message
);
\Mail::to('xxx#mail.com')->send(new ContactUs($data));
return back()->with('success', 'Thanks for contacting us! We will get back to you soon.');
}
}
ContactUs
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
class ContactUs extends Mailable
{
use Queueable, SerializesModels;
public $data;
public function __construct($data)
{
$this->data = $data;
}
public function build()
{
return $this->from('xxxx#mail.com')
->subject('Customer Feedback')
->view('dynamic_email_template')
->with('data', $this->data);
}
}
Form
<div class="form">
<h4>Send us a message</h4>
#if (count($errors) > 0)
<div class="alert alert-danger">
<button type="button" class="close" data- dismiss="alert">×</button>
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
#if ($message = Session::get('success'))
<div class="alert alert-success alert-block">
<button type="button" class="close" data- dismiss="alert">×</button>
<strong>{{ $message }}</strong>
</div>
#endif
<form method="post" action="{{url('contactus/send')}}" autocomplete="off">
{{ csrf_field() }}
<div class="form-group">
<input type="text" name="name" for="name" class="form-control" id="name" placeholder="Your Name" data-rule="minlen:4" data-msg="Please enter at least 4 chars" />
<div class="validation"></div>
</div>
<div class="form-group">
<input type="email" class="form-control" name="email" for="email" id="email" placeholder="Your Email" data-rule="email" data-msg="Please enter a valid email" />
<div class="validation"></div>
</div>
<div class="form-group">
<input type="text" class="form-control" name="subject" for="subject" id="subject" placeholder="Subject" data-rule="minlen:4" data-msg="Please enter at least 8 chars of subject" />
<div class="validation"></div>
</div>
<div class="form-group">
<textarea class="form-control" name="message" for="message" rows="5" data-rule="required" data-msg="Please write something for us" placeholder="Message"></textarea>
<div class="validation"></div>
</div>
<div class="text-center">
<button type="submit" name="send" title="Send Message">Send Message</button>
</div>
</form>
</div>
dynamic_email_template
<p>Hi, This is {{ $data['name'] }} "{{ $data['email'] }}"</p> </br>
<p>{{ $data['subject'] }}</p> </br>
<p>I have some query like "{{ $data['message'] }}".</p> </br>
<p>It would be appriciative, if you gone through this feedback.</p>

You need to create email template same like your view file, lets say contact_us_email.blade.php. In this file add this content
contact_us_email.blade.php
<html>
<body>
<h2>Hi, This is {{ $data['name'] }} "{{ $data['email'] }}"</h2><br>
<p>Subject: {{ $data['subject'] }}</p> <br>
<p>I have some query like <b>"{{ $data['message'] }}"</b>. <br>
<p>It would be appriciative, if you gone through this feedback.</p>
</body>
</html>
NOTE: Add css or styling according to your need. this is basic html
Edit: To send confirmation email to user
For success confirmation to user, you can create another email template like
contact_us_thank_you_email.blade.php
<html>
<body>
<h2>Hello, {{ $data['name'] }} "{{ $data['email'] }}"</h2><br>
<p>Thank You for your interest...blah blah blah</p> <br>
<p>Our team will contact you soon</p> <br>
</body>
</html>
Now in your ContactUsController, replace
\Mail::to('xxx#mail.com')->send(new ContactUs($data));
with
Mail::send('contact_us_email', $data, function ($message) use ($data) {
$message->from('xxx#mail.com', 'xxx');
$message->to('xxx#mail.com')->subject($data['subject']);
});
Mail::send('contact_us_thank_you_email', $data, function ($message) use ($data) {
$message->from('xxx#mail.com', 'xxx');
$message->to($data['email'])->subject('Thank you for the interest');
});
And I think you are good to go with this. I hope this is what you are asking for.

Related

Laravel 8 validation doesn't work and it redirects me to "419|page expired"

I'm just new to laravel and I couldn't understand why the error message of validation won't display and it redirect instead to "419|page expired" , even after following a video tutorial and the laravel documentation.
*This is the html code
<form action="{{ route('registerPost') }}" method="post">
<!-- full name div -->
<div class="flex mt-2 gap-2">
<div class="w-1/2">
<label for="">First Name</label><br>
<input id="firstName" class="w-full px-2 py-1 border border-gray-300 rounded-md focus:outline-none focus:border-green-500" type="text" name="firstName" value="">
</div>
#error('firstName')
<div class="text-sm text-red">{{ $message }}</div>
#enderror
<div class="w-1/2">
<label for="">Last Name</label><br>
<input class="w-full px-2 py-1 border border-gray-300 rounded-md focus:outline-none focus:border-green-500" type="text" name="lastName" value="">
</div>
</div>
*The route
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\createController;
Route::get('/', function () {
return view('logIn');
});
Route::get('/register', [createController::class, 'index'])->name('register');
Route::post('/register', [createController::class, 'store'])->name('registerPost');
*Controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class createController extends Controller
{
public function index(){
return view('register');
}
public function store(Request $request)
{
$validated = $request->validate([
'firstName' => 'required|max:30',
'lastName' => 'required|max:30',
'email' => 'required|max:30',
'username' => 'required|max:30',
'password' => 'required|max:30'
]);
}
}
try to add .
{{ csrf_field() }}
Add #csrf
Or
{{ csrf_field() }}
into the form tag

multiple field validation using livewire ? name.0.required is working but name.*.required is not working. Please provide me solution

I want to validate all field. But It is validating only first field. Append field is not validating
multiple fields validation using livewire? name.0.required is working but name.*.required is not working.
<?php
namespace App\Http\Livewire;
use Livewire\Component;
class Test extends Component
{
public $name;
public $inputs = [];
public $i = 1;
public function add($i)
{
$i = $i + 1;
$this->i = $i;
array_push($this->inputs ,$i);
}
public function remove($i)
{
unset($this->inputs[$i]);
}
public function store()
{
$validatedDate = $this->validate([
'name.0' => 'required',
'name.*' => 'required',
],
[
'name.0.required' => 'name field is required',
'name.*.required' => 'name field is required',
]
);
session()->flash('message', 'Name Has Been Created Successfully.');
}
public function render()
{
return view('livewire.test');
}
}
<div>
<form class="offset-md-3">
#if (session()->has('message'))
<div class="alert alert-success">
{{ session('message') }}
</div>
#endif
<div class="add-input">
<div class="row">
<div class="col-md-5">
<div class="form-group">
<input type="text" class="form-control" placeholder="Enter Name" wire:model="name.0">
#error('name.0') <span class="text-danger error">{{ $message }}</span>#enderror
</div>
</div>
<div class="col-md-2">
<button class="btn text-white btn-info btn-sm" wire:click.prevent="add({{$i}})">Add</button>
</div>
</div>
</div>
#foreach($inputs as $key => $value)
<div class=" add-input">
<div class="row">
<div class="col-md-5">
<div class="form-group">
<input type="text" class="form-control" placeholder="Enter Name" wire:model="name.{{ $value }}">
#error('name.'.$value) <span class="text-danger error">{{ $message }}</span>#enderror
</div>
</div>
<div class="col-md-2">
<button class="btn btn-danger btn-sm" wire:click.prevent="remove({{$key}})">remove</button>
</div>
</div>
</div>
#endforeach
<div class="row">
<div class="col-md-12">
<button type="button" wire:click.prevent="store()" class="btn btn-success btn-sm">Save</button>
</div>
</div>
</form>
</div>
This is my full code use to create multi field using livewire. I am not able to validate appended field so I need help to solve this problem. This validate first field name.0 other append field name.* does not validate.
You should use $key instead $value.
Like this:
wire:model="name.{{ $key }}"

How in laravel-livewire set flash message with validation erros

With laravel 7 /livewire 1.3 app in login form I got errors on invalid form with code:
public function submit()
{
$loginRules= User::getUserValidationRulesArray();
$this->validate($loginRules);
and shows error message near with any field
I want on login fail to add flash message and reading at
https://laravel.com/docs/7.x/validation
I try to make :
$request = request();
$loginRules= User::getUserValidationRulesArray('login');
$validator = Validator::make($request->all(), $loginRules);
if ($validator->fails()) {
session()->flash('danger_message', 'Check your credentials !');
return redirect()->to('/login');
}
I got flash message, but validation errors for any field is lost.
If I try to make :
$request = request();
$loginRules= User::getUserValidationRulesArray('login');
$validator = Validator::make($request->all(), $loginRules);
if ($validator->fails()) {
session()->flash('danger_message', 'Check your credentials !');
return redirect('/login')
->withErrors($validator)
->withInput();
}
and I got error :
Method Livewire\Redirector::withErrors does not exist.
in routes/web.php I have :
Route::livewire('/login', 'login')->name('login');
MODIFIED :
In component app/Http/Livewire/Login.php :
<?php
namespace App\Http\Livewire;
use App\User;
use Illuminate\Support\Facades\Validator;
use Livewire\Component;
use Auth;
use DB;
use App\Config;
use Cartalyst\Sentinel\Laravel\Facades\Sentinel;
class Login extends Component
{
public $form= [
'email'=>'admin#mail.com',
'password'=> '111111',
];
private $view_name= 'livewire.auth.login';
public function submit()
{
$request = request();
$loginRules= User::getUserValidationRulesArray('login');
$validator = Validator::make($request->all(), $loginRules);
if ($validator->fails()) {
session()->flash('danger_message', 'Check your credentials !');
return;
// return redirect()->to('/login');
}
$user = Sentinel::findByCredentials(['email' => $this->form['email']]);
if (empty($user)) {
session()->flash('danger_message', 'User "' . $this->form['email'] . '" not found !');
...
and template resources/views/livewire/auth/login.blade.php :
<article >
#include('livewire.common.alert_messages')
<form class="form-login" wire:submit.prevent="submit">
<div class="card">
#if ($errors->any())
Check your login credentials
#endif
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
<div class="card-body card-block">
<h3 class="card-header">
<span class="spinner-border" role="status" wire:loading>
<span class="sr-only">Loading...</span>
</span>
Login
</h3>
<h4 class="card-subtitle">Use your credentials</h4>
<dl> <!-- email FIELD DEFINITION -->
<dt>
<label class="col-form-label" for="email">Email:<span class="required"> * </span></label>
</dt>
<dd>
<input
wire:model.lazy="form.email"
name="email"
id="email"
class="form-control"
placeholder="Your email address"
autocomplete=off
>
#error('form.email')
<div class="validation_error">{{ clearValidationError($message,['form.'=>'']) }}</div> #enderror
</dd>
</dl> <!-- <dt> email FIELD DEFINITION -->
<dl> <!-- password FIELD DEFINITION -->
<dt>
<label class="col-form-label" for="password">Password:<span class="required"> * </span></label>
</dt>
<dd>
<input type="password"
wire:model.lazy="form.password"
id="password"
name="password"
class="form-control"
placeholder="Your password"
autocomplete=off
>
#error('form.password')
<div class="validation_error">{{ clearValidationError($message,['form.'=>'']) }}</div> #enderror
</dd>
</dl> <!-- <dl> password FIELD DEFINITION -->
</div> <!-- <div class="card-body card-block"> -->
<section class="card-footer row_content_right_aligned">
<button type="reset" class="btn btn-secondary btn-sm m-2">
Reset
</button>
<button type="submit" class="btn btn-primary btn-sm m-2 ml-4 mr-4 action_link">
Submit
</button>
</section>
</div> <!-- <div class="card"> -->
</form>
</article>
Which way is valid ?
Thanks in advance!
Before render method you can check if errorBag has items:
public function render()
{
if(count($this->getErrorBag()->all()) > 0){
$this->emit('error:example');
}
return view('livewire-component-view');
}
The beauty of Livewire is that you don't necessarily need to redirect to flash a message, you can display messages by setting properties on your component, and conditionally rendering them in your view. In this particular case, there's already logic readily available, you just have to check the errors-object being exposed by the validation.
In your view, all you have to do is check #if ($errors->any()) - if that's true, display your message. This is a Laravel feature, which Livewire implements. When any validation fails, an exception is thrown and intercepted, and the $errors variable gets exposed to your view. This means that whenver you do $this->validate(), and the validation fails, you can access the errors within $errors.
<div>
#if ($errors->any())
Check your login credentials
#endif
<form wire:submit.prevent="submit">
<input type="text" wire:model="email">
#error('email') <span class="error">{{ $message }}</span> #enderror
<input type="password" wire:model="password">
#error('password') <span class="error">{{ $message }}</span> #enderror
<button type="submit">Submit</button>
</form>
</div>
Use the $rules attribute to declare the rules, validate those rules with $this->validate() and Livewire will do most of the work for you. You do not need to return any redirects, or use session()->flash(). The session-state will not be flashed, because you don't perform a new page load.
class Login extends Component
{
public $form = [
'email' => 'admin#mail.com',
'password' => '111111',
];
protected $rules;
private $view_name = 'livewire.auth.login';
public function submit()
{
$this->rules = User::getUserValidationRulesArray('login');
$this->validate();
// No need to do any more checks, $errors will now be updated in your view as the exception is thrown
// Proceed with submitting the form

ReflectionException (-1) Class App\Http\Controllers\AnswersController does not exist

I want to save data in a database using the form
I tried to use a form with input text, radios ... and controller to save data in a database with post method
Controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Auth;
use App\Survey;
use App\Answer;
use App\Http\Requests;
class Answerscontroller extends Controller
{
public function store(Request $request, Survey $survey)
{
$request->validate([
'answer'=>'required'
]);
$answers = new Answer([
'answer' => $request->get('answer'),
'commentaire' => $request->get('commentaire'),
'user_id' => auth()->id(),
'last_ip' => request()->ip(),
'survey_id' => $survey->id
]);
$answers->save();
return redirect('/survey')->with('success', 'Stock has been added');
}
}
View:
{!! Form::open(array('action'=>array('AnswersController#store', $survey->id))) !!}
#forelse ($survey->questions as $key=>$question)
<p class="flow-text">Question {{ $key+1 }} - {{ $question->title }}</p>
#if($question->question_type === 'text')
<div class="form-group">
<div class="input-field col s12">
<input id="answer" type="text" name="{{ $question->id }}[answer]">
<label for="answer">Answer</label>
</div>
</div>
#elseif($question->question_type === 'textarea')
<div class="form-group">
<div class="input-field col s12">
<textarea id="textarea1" class="materialize-textarea" name="{{ $question->id }}[answer]"></textarea>
<label for="textarea1">Textarea</label>
</div>
</div>
#elseif($question->question_type === 'radio')
#foreach($question->option_name as $key=>$value)
<p style="margin:0px; padding:0px;">
#if($value === 'else')
<div class="form-group" style="margin-left: 20px;">
<input name="answer" class="custom-control-input" type="radio" id="{{ $value }}" value="{{$value}}"/>
<label class="custom-control-label" for="{{ $value }}">{{ $value }}</label>
<div id="textboxes" style="display: none">
<br>
<textarea class="form-control" name="commentaire" id="exampleFormControlTextarea1" rows="3" placeholder="Write a large text here ..."></textarea>
</div>
</div>
#else
<p style="margin:0px; padding:0px;">
<div class="form-group" style="margin-left: 20px;">
<input name="answer" class="custom-control-input" type="radio" id="{{ $value }}" value="{{ $value}}"/>
<label class="custom-control-label" for="{{ $value }}">{{ $value }}</label>
</div>
</p>
#endif
#endforeach
#elseif($question->question_type === 'checkbox')
#foreach($question->option_name as $key=>$value)
<p style="margin:0px; padding:0px;">
<div class="form-group">
<input type="checkbox" id="{{ $value }}" name="answer" value="{{$value}}"/>
<label for="{{$value}}">{{ $value }}</label>
</div>
</p>
#endforeach
#endif
<div class="divider" style="margin:10px 10px;"></div>
#empty
<span class='flow-text center-align'>Nothing to show</span>
#endempty
<div class="form-group">
{{ Form::submit('Submit Survey', array('class'=>'btn btn-success mt-4')) }}
</div>
{!! Form::close() !!}
model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Answer extends Model
{
protected $fillable = ['answer','commentaire','user_id','survey_id','last_ip'];
protected $table = 'Answer';
public function survey() {
return $this->belongsTo(\App\Survey::class);
}
public function question() {
return $this->belongsTo(\App\Question::class);
}
public function user() {
return $this->belongsTo('App\User');
}
}
Error:
ReflectionException (-1) Class App\Http\Controllers\AnswersController
does not exist
Please could you help me to fix that
ps: in the router, I put post method and controller
The problem is about naming. Your controller is Answerscontroller but the Laravel Looks fo AnswersController with capital C. So, check your controller name that should be AnswersController.php and the class name (inside the file AnswersController.php) that sould be AnswersController.

Laravel PHPUnit Test Undefined Errors Variable

I would like someone to explain to me why I'm getting undefined variable errors when I run my phpunit tests from my Laravel application. I have if statements set up so that it doesn't add them by default so not sure why.
<?php
Route::auth();
Route::group(['middleware' => 'web'], function () {
Route::get('dashboard', ['as' => 'dashboard', 'uses' => 'HomeController#dashboard']);
});
<form role="form" method="POST" action="{{ url('/login') }}">
{{ csrf_field() }}
<div class="form-group form-material floating {{ $errors->has('email') ? 'has-error' : '' }}">
<input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}"/>
<label for="email" class="floating-label">Email</label>
#if ($errors->has('email'))
<small class="help-block">{{ $errors->first('email') }}</small>
#endif
</div>
<div class="form-group form-material floating {{ $errors->has('password') ? 'has-error' : '' }}">
<input id="password" type="password" class="form-control" name="password" />
<label for="password" class="floating-label">Password</label>
#if ($errors->has('password'))
<small class="help-block pull-left">{{ $errors->first('password') }}</small>
#endif
</div>
<div class="form-group clearfix">
<div class="checkbox-custom checkbox-inline checkbox-primary checkbox-lg pull-left">
<input type="checkbox" id="inputCheckbox" name="remember">
<label for="inputCheckbox">Remember me</label>
</div>
<a class="pull-right" href="{{ url('/password/reset') }}">Forgot password?</a>
</div>
<button type="submit" class="btn btn-primary btn-block btn-lg margin-top-40">Log in</button>
</form>
<?php
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
class LoginTest extends TestCase
{
use WithoutMiddleware;
/** #test */
public function user_can_visit_login_page()
{
$this->visit('login');
}
/** #test */
public function user_submits_form_with_no_values_and_returns_errors()
{
$this->visit('login')
->press('Log in')
->seePageIs('login')
->see('The email field is required.')
->see('The password field is required.');
}
/** #test */
public function it_notifies_a_user_of_wrong_login_credentials()
{
$user = factory(App\User::class)->create([
'email' => 'john#example.com',
'password' => 'testpass123'
]);
$this->visit('login')
->type($user->email, 'email')
->type('notmypassword', 'password')
->press('Log in')
->seePageIs('login');
}
public function user_submits_login_form_unsuccesfully()
{
$user = factory(App\User::class)->create([
'email' => 'john#example.com',
'password' => 'testpass123'
]);
$this->visit('login')
->type($user->email, 'email')
->type($user->password, 'password')
->press('Log in')
->seePageIs('dashboard');
}
}
Errors Given
1) LoginTest::user_can_visit_login_page
A request to [http://myapp.app/login] failed. Received status code [500].
/Users/me/Projects/repositories/MyApp/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/InteractsWithPages.php:196
/Users/me/Projects/repositories/MyApp/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/InteractsWithPages.php:80
/Users/me/Projects/repositories/MyApp/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/InteractsWithPages.php:61
/Users/me/Projects/repositories/MyApp/tests/LoginTest.php:13
Caused by
exception 'ErrorException' with message 'Undefined variable: errors' in /Users/me/Projects/repositories/MyApp/storage/framework/views/cca75d7b87e55429621038e76ed68becbc19bc14.php:30
Stack trace:
Remove the WithoutMiddleware trait from your test.

Resources