I have a basic form to send an email :
<form action="{{ path('user_send_mail') }}" method="post" enctype="multipart/form-data">
<input name="email_to" type="email" class="form-control" placeholder="To" required>
<input name="email_cc" type="email" class="form-control" placeholder="Cc">
<textarea name="message" id="email_message" class="form-control" placeholder="message" style="height: 120px;" required></textarea>
<input type="file" name="attachment"/>
<p class="help-block">Max. 2MB</p>
<button type="submit" class="btn btn-primary pull-left"><i class="fa fa-envelope"></i> Send the email</button>
</form>
And an action in my controller to validate the data and send the mail but validation doesn't work..
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\File;
use Symfony\Component\Validator\Constraints\NotBlank;
public function sendMailToUserAction(Request $request)
{
$form = $this->createFormBuilder(null)
->add('email_to', 'email', array(
'required' => true,
'constraints' => new Email()
))
->add('email_cc', 'email', array(
'required' => false,
'constraints' => new Email()
))
->add('message', 'textarea', array(
'required' => true,
'constraints' => new NotBlank()
))
->add('attachment', 'file', array(
'required' => false,
'constraints' => new File()
))
->getForm();
$form->handleRequest($request);
if ($form->isValid()) {
$data = $form->getData();
var_dump($data);exit;
} else {
var_dump("error");exit;
}
}
When I submit the form, I got always "error", so validation doesn't work but I don't know why... I have read a lot of topics about this but I get stuck..
EDIT : If I print form error using $form->getErrorsAsString() instead of var_dump("error");exit;, I got this :
string(97) "email_to: No errors email_cc: No errors message: No errors attachment: No errors "
please reffer to this: http://symfony.com/doc/current/book/forms.html#using-a-form-without-a-class it think you have to pass array with fields name that you want to validate (its like a default values)
p. s. why not using Simple PHP Object for that? Symfony2 forms fields name should contain brakets like (for example): data[email_to] instead of email_to
Related
I have a webpage with 4 different urls
www.sample.com\home
www.sample.com\about
www.sample.com\products
www.sample.com\contact
I have a contact form in all the pages of my webpage.
I need to know the Page, from where the contact form is submitted from either(home, about, products or services).
I use laravel mailer to send mail, once the contact form is submitted.
Contact form:
<input type="hidden" name="url" value="{{substr(strrchr(url()->current(),'/'),1)}}">
<form method="POST" action="sendEmail">
<label for="name">Name</label>
<input type="text" name="name" id="name" value="{{ old('name') }}" />
<label for="email">Email</label>
<input type="email" name="email" id="email" value ="{{ old('email') }}"/>
<label for="message">Message</label>
<textarea name="body" id="message" rows="5"> {{ old('message') }}</textarea>
<button class ="primary"> Submit </button>
</form>
Controller:
use Illuminate\Support\Facades\Request as PostRequest;
public function store()
{
$data = request()->validate([
'name' => 'required',
'email' => 'required|email',
'body' => 'required'
]);
// To get the current URL
$currentPage = PostRequest::input('url');
\Mail::send('E-mail view', $data, $currentPage, function($message) use ($data, $currentPage){
$message->to('abc#xyz.com')
->from($data['email'], $data['name'])
->replyTo($data['email'], $data['name'])
->returnPath($currentPage)
->subject('Notification');
});
return back();
}
I need the URL as home, about, products, contact, from where the Contact form is submitted from not the form action sendEmail inside the E-mail View blade file
Email View Blade:
<p> $name </p>
<p> $email</p>
<p> $currentPage </p>
It throws an Error
Function name must be a string
How to pass the current URL from Where the Form is submiited from (home, about,..) to Mail?
Could anyone please help?
Many thanks.
Try like this
use Illuminate\Support\Facades\Request as PostRequest;
public function store()
{
$data = request()->validate([
'name' => 'required',
'email' => 'required|email',
'body' => 'required'
]);
// To get the current URL
$currentPage = request()->url();
$data['currentPage'] = $currentPage;
\Mail::send('E-mail view', $data, function($message) use ($data, $currentPage){
$message->to('abc#xyz.com')
->from($data['email'], $data['name'])
->replyTo($data['email'], $data['name'])
->returnPath($currentPage)
->subject('Notification');
});
return back();
}
I have a Controller method like this:
use Validator;
public function insert(Request $request)
{
$data = Validator::make(request()->all(),[
'title' => 'required',
'name' => 'required|alpha_num',
'activation' => 'nullable',
'cachable' => 'nullable'
])->validated();
$wallet = new Wallet();
$wallet->title = $data['title'];
$wallet->name = $data['name'];
if (!empty($data['activation'])) {
$wallet->is_active = 1;
} else {
$wallet->is_active = 0;
}
if (!empty($data['cachable'])) {
$wallet->is_cachable = 1;
} else {
$wallet->is_cachable = 0;
}
$wallet->save();
return redirect(url('admin/wallets/index'));
}
And then I tried showing errors like this:
#error("name")
<div class="alert alert-danger">{{$message}}</div>
#enderror
But the problem is, it does not print any error when I fill the form incorrectly.
So how to fix this and show errors properly?
Here is the form itself, however it submits data to the DB correctly:
<form action="{{ route('insertWallet') }}" method="POST" enctype="multipart/form-data">
#csrf
<label for="title" class="control-label">Title</label>
<br>
<input type="text" id="title-shop" name="title" class="form-control" value="" autofocus>
#error("title")
<div class="alert alert-danger">{{$message}}</div>
#enderror
<label for="title" class="control-label">Name</label>
<br>
<input type="text" id="title-shop" name="name" class="form-control" value="" autofocus>
#error("name")
<div class="alert alert-danger">{{$message}}</div>
#enderror
<input class="form-check-input" type="checkbox" name="cachable" value="cashable" id="cacheStatus">
<label class="form-check-label" for="cacheStatus">
With Cash
</label>
<input class="form-check-input" type="checkbox" name="activaton" value="active" id="activationStatus">
<label class="form-check-label" for="activationStatus">
Be Active
</label>
<button class="btn btn-success">Submit</button>
</form>
check the official documentation here
add the following code
if($data->fails()){
return redirect(url('admin/wallets/index'))->withErrors($data)->withInput();
}
And after that save your data in your database
You are not returning any errors, you are just redirecting back to the view without any data.
Your fix would be to have your validator as this:
$data = Validator::validate(request()->all(),[
'title' => 'required',
'name' => 'required|alpha_num',
'activation' => 'nullable',
'cachable' => 'nullable'
]);
See that I have changed Validator::make to Validator::validate. As the documentation states:
If the validation rules pass, your code will keep executing normally; however, if validation fails, an exception will be thrown and the proper error response will automatically be sent back to the user.
If validation fails during a traditional HTTP request, a redirect response to the previous URL will be generated. If the incoming request is an XHR request, a JSON response containing the validation error messages will be returned.
So, if your validation passes, it will save all the validated data into $data, as you did with ->validated() (but you don't have to write it here), and if it fails, it will automatically throw an Exception, in this case ValidationException, so Laravel will automatically handle it and redirect back with to the same URL and with the errors. So it now should work...
This is the Validator::validate source code and this is the validate source code for the validator validate method.
I am having trouble running the following code to update my database with the form input the user has filled in. The ideal output would be to be redirected to my pageManagement.blade after updating the record in the database. The current output is an error message: Call to a member function update() on string.
The code I have used is shown below.
PageController#update function.
public function update($URI)
{
$data = request()->validate([
'title' => 'required',
'URI' => 'required|min:5|max:10',
'pageContent' => 'required'
]);
$URI->update($data);
return redirect('/p');
}
editPage.blade.php
<h1>Fill in the form to edit a page below.</h1>
<form action="/page/{{ $pageContent->URI }}" method="post">
#csrf
#method('PATCH')
<label for="title">Title:</label><br>
<input type="text" id="title" name="title" autocomplete="off" value="{{ $pageContent -> title
}}"><br>
#error('title') <p style="color: red">{{ $message }}</p> #enderror
<label for="URI">URI:</label><br>
<input type="text" id="URI" name="URI" autocomplete="off" value="{{ $pageContent -> URI }}">
<br>
#error('URI') <p style="color: red">{{ $message }}</p> #enderror
<label for="pageContent">Page Content:</label><br>
<textarea id="pageContent" name="pageContent" value="{{ $pageContent -> pageContent }}">
</textarea>
#error('pageContent') <p style="color: red">{{ $message }}</p> #enderror
<input type="submit" value="Submit">
</form>
THE SCRIPT SRC SHOULD BE HERE BUT HAS NOT BEEN INCLUDED DUE TO THE INDENTATION ISSUE WITH
STACKOVERFLOW.
<script>
tinymce.init({
selector:'#pageContent'
})
</script>
Web.php file where I store my routes.
Route::patch('/page/{URI}','PageController#update');
My GitHub repository link is attached below if you want a better view of the code.
https://github.com/xiaoheixi/wfams
Thanks for the help everyone!
The error is coming from a non-instantiated object URI. You are passing a string from your form - whatever $pageContent->URI is. Without loading the object you wish to update, it is just a string, thus the error message.
$URI->update($data);
at the end of your method is basically saying something like 'call update on the number 32' (32->update($data)).
To fix the error in your question, you can instantiate the object at the beginning of your method:
public function update($URI)
{
$data = request()->validate([
'title' => 'required',
'URI' => 'required|min:5|max:10',
'pageContent' => 'required'
]);
$obj = \App\URIModel::find($URI); // Whatever the model is
$obj->update(request()->all());
return redirect('/p');
}
Alternate Fix: Since you have the named variable inside the route file, you can also take advantage of route-model binding by injecting the model directly in the method() to save a line of code:
public function update(\App\URIModel $URI)
{
$data = request()->validate([
'title' => 'required',
'URI' => 'required|min:5|max:10',
'pageContent' => 'required'
]);
$URI->update(request()->all);
return redirect('/p');
}
Here is my content.blade.php
<form action="{{ route('home') }}" method="post">
<input class="input-text" type="text" name="name" value="Your Name *" onFocus="if(this.value==this.defaultValue)this.value='';" onBlur="if(this.value=='')this.value=this.defaultValue;">
<input class="input-text" type="text" name="email" value="Your E-mail *" onFocus="if(this.value==this.defaultValue)this.value='';" onBlur="if(this.value=='')this.value=this.defaultValue;">
<textarea name="text" class="input-text text-area" cols="0" rows="0" onFocus="if(this.value==this.defaultValue)this.value='';" onBlur="if(this.value=='')this.value=this.defaultValue;">Your Message *</textarea>
<input class="input-btn" type="submit" value="send message">
{{ csrf_field() }}
</form>
That's my routes(web.php)
Route::group(['middleware'=>'web'], function(){
Route::match(['get', 'post'], '/', ['uses'=>'IndexController#execute', 'as'=>'home']);
Route::get('/page/{alias}', ['uses'=>'PageController#execute', 'as'=>'page']);
Route::auth();
});
And Finally here is my IndexController.php, method execute():
if($request->isMethod('post')){
$messages = [
'required' => "Поле :attribute обязательно к заполнению",
'email' => "Поле :attribute должно соответствовать email адресу"
];
$this->validate($request, [
'name' => 'required|max:255',
'email' => 'required|email',
'text' => 'required'
], $messages);
dump($request);
}
So, the problem is that dump($request) does not work, and I also tried to comment everything except dump($request), and the result is the same. I think it just skips if($request->isMethod('post')) so that it returns that the method is not true, may be there is something wrong with token, I am not sure.
How to resolve this issue?
edit:
That's the code above if statement
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Page;
use App\Service;
use App\Portfolio;
use App\People;
use DB;
class IndexController extends Controller
{
//
public function execute(Request $request){
You should assign $request to somewhere first.
For example, if i have a store method and i have to use Request $request for grabbing the information, i should establish it first, so by establishing it my application will recognize what does the variable is retrieving, let me show you an example code:
public function store(Request $request)
{
$data = $request->all();
$data['a'] = Input::get('a');
$data['b'] = Input::get('b');
$data['c'] = Input::get('c');
$data['d'] = Input::get('d');
$data['e'] = Input::get('e');
Letters::create($data);
return redirect::to('/');
}
Did you get it?
If not, here is an example with isMethod:
$method = $request->method();
if ($request->isMethod('post')) {
//
}
In your code i did not see the $var = $request->method(); (or what you want it to be).
I'm trying to check if the email is already exist my database on my subscribes table.
Form
{!! Form::open(array('url' => '/subscribe', 'class' => 'subscribe-form', 'role' =>'form')) !!}
<div class="form-group col-lg-7 col-md-8 col-sm-8 col-lg-offset-1">
<label class="sr-only" for="mce-EMAIL">Email address</label>
<input type="email" name="subscribe_email" class="form-control" id="mce-EMAIL" placeholder="Enter email" required>
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;"><input type="text" name="b_168a366a98d3248fbc35c0b67_73d49e0d23" value=""></div>
</div>
<div class="form-group col-lg-3 col-md-4 col-sm-4"><input type="submit" value="Subscribe" name="subscribe" id="mc-embedded-subscribe" class="btn btn-primary btn-block"></div>
{!! Form::close() !!}
Controller
public function postSubscribe() {
// Validation
$validator = Validator::make( Input::only('subscribe_email'),
array(
'email' =>'unique:subscribes',
)
);
if ($validator->fails()) {
return Redirect::to('/#footer')
->with('subscribe_error','This email is already subscribed to us.')
->withErrors($validator)->withInput();
}else{
dd("HERE");
$subscribe = new Subscribe;
$subscribe->email = Input::get('subscribe_email');
$subscribe->save();
return Redirect::to('/thank-you');
}
}
Debuging Steps
I tried inputting email that I know already exist in my db.
I want to my validation to fail, and redirect me back to my /#footer (homepage).
I try printing dd("HERE"); if my vaildation not fail.
BUT I keep getting HERE to print which mean my validation is not failing.
Why is that happening ? I'm completely blank out now.
Can someone please point out what I missed ?
I know I am very close.
Thanks.
Your db field name is email not subscribe_email, your input param name however is. Laravel defaults to the fieldname given with the input, so in your case subscribe_email
Try this:
array(
'subscribe_email' => 'required|email|unique:subscribes,email',
)
This uses the db fieldname email, like you have, but the validation is on the field subscribe_email.
try specifying the column name of email in subscribes table
$rules = array(
'email' => 'email|unique:subscribes,email'
);
It looks like the reason this is not working is because you are trying to match the subscribe_email field against validation for a email field, no match is being made. To fix you need to do this:
$validator = Validator::make( Input::only('subscribe_email'),
array(
'subscribe_email' =>'email|unique:subscribes,email',
)
);
//put this in your controller
if (User::where('email', '=', Input::get('email'))->exists()) {
return back()->withErrors([
'message' => 'Email is already taken'
]);
//then go up and include
use Illuminate\Support\Facades\Input;