CakePhp 3.5 validation error mesages not showing on fields - php

so i started playing with a cakePhp app, trying to make it work, but i can't make the form helper output the validation error messages on the field with the error.I am using the FriendsOfCake/bootstrap-ui plugin to make the form helper output bootstrap forms.
Here is my model:
public function validationDefault(Validator $validator)
{
$validator
->integer('id')
->allowEmpty('id', 'create');
$validator
->notEmpty('name', 'Name should not be empty')
->scalar('name')
->requirePresence('name', 'create');
return $validator;
My controller method:
$user = $this->Users->newEntity();
if ($this->request->is('post')) {
$user = $this->Users->patchEntity($user, $this->request->getData());
if ($this->Users->save($user)) {
$this->Flash->success(__('V-ati inregistrat cu success'));
return $this->redirect($this->referer());
}
$this->Flash->error(__('The user could not be saved. Please, try again.'));
}
$this->viewBuilder()->setLayout('auth');
$this->viewBuilder()->setTemplate('register');
$this->set(compact('user'));
$this->set('_serialize', ['user']);
}
and my form:
<div class="container">
<div class="row">
<div class="col-md-4 col-md-offset-4">
<?=
$this->Form->create('users',['url'=>['controller'=>'Users','action'=>'store']]),
$this->Form->control('name'),
$this->Form->control('email'),
$this->Form->control('password'),
$this->Form->submit('Trimite'),
$this->Form->end()
?>
</div>
</div>

You are passing an invalid context to the form helper. The $context argument of FormHelper::create() by default only supports false/null, an array, a result set, or an entity, and you want to pass the latter, ie the $user variable, which holds the entity that contains the possible validation errors.
$this->Form->create($user, [/* ... */])
See also
Cookbook > Views > Helpers > Form > Starting A Form

Related

How to get validated data from Validator instance in Laravel?

I manually created a Validator, but i can't find a method to get the validated data.
For Request, validated data return from $request->validate([...])
For FormRequest, it's return from $formRequest->validated()
But with Validator, i don't see a method like those 2 above.
Assuming that you're using Validator facade:
use Illuminate\Support\Facades\Validator;
$validator = Validator::make($request->all(), $rules, $messages, $attributes);
if ($validator->fails()) {
return $validator->errors();
}
//If validation passes, return valid fields
return $validator->valid();
https://laravel.com/api/5.5/Illuminate/Validation/Validator.html#method_valid
If you use the Validator facade with make it will return a validator instance. This validator instance has methods like validate(), fails() and so on. You can look those methods up in the validator class or in the laravel api-documentation.
Writing The Validation Logic
public function store(Request $request)
{
$validatedData = $request->validate([
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
// The blog post is valid...
}
Displaying The Validation Errors
<!-- /resources/views/post/create.blade.php -->
<h1>Create Post</h1>
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
<!-- Create Post Form -->

Laravel 5.1 passing data to mail view doesn't work

So, I'm trying to make an e-mail view, using data the user posted. The problem is, that specific data is unreachable. I don't know how I'm supposed to get that data.
Here is my controller:
public function PostSignupForm(Request $request)
{
// Make's messages of faults
$messages = [
//removed them to save space
];
//Validation rules
$rules = [
//removed them to save space
];
$validator = Validator::make($request->all(), $rules, $messages);
if ($validator->fails()) {
return Redirect::back()->withInput()->withErrors($validator);
}
DB::table('rittensport')->insert([
'note' => $request->get('note'),
//standard instert
]);
/**
* Sending the e-mails to the pilot and co-pilot
*
* #return none
*/
Mail::send('emails.rittensport_signup', $request->all(), function ($message) {
$message->from(env('APP_MAIL'), 'RallyPodium & Reporting');
$message->sender(env('APP_MAIL'), 'RallyPodium & Reporting');
$message->to($request->get('piloot_email'), strtoupper($request->get('piloot_lastname')).' '.$request->get('piloot_firstname'));
$message->to($request->get('navigator_email'), strtoupper($request->get('navigator_lastname')).' '.$request->get('navigator_firstname'));
$message->subject('Uw inschrijving voor de RPR Gapersrit '. date('Y'));
$message->priority(1);//Highest priority (5 is lowest).
});
return Redirect::back();
Well, the view exists and the error I'm facing to is:
Undefined variable: request.
This is how I try to get the data in the e-mail view: {{ $request->get('note') }} I already tried things like {{ $message->note }}, $message['note'] And so on.
Try this:
Mail::send('emails.rittensport_signup', array("request" => $request), function (...

Laravel 5.2 Displaying Validation Error

I am trying to validate a simple form by using Laravel's validator. Looks like validation works fine but i am unable to display errors. Form and controller looks like this.
Form
<h3>Add a New Team</h3>
<form method="POST" action="/teams">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<div class="form-group">
<input class="form-control" name="team_name" value="{{ old('team_name') }}" />
</div>
<div class="form-group">
<button type="submit" class="btn bg-primary">Add Team</button>
</div>
</form>
#if(count($errors))
<div class="alert alert-danger">
<ul>
#foreach($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
Controller Method
public function store(Request $request) {
$this->validate($request, [
'team_name' => 'required|min:10'
]);
$team = new Team;
$team->team_name = $request->team_name;
$team->save();
return back();
}
If i remove web middleware group from my routes, errors displays fine.
Currently my routes.php file looks like this
Route::group(['middleware' => ['web']], function () {
Route::get('/teams', 'TeamsController#create');
Route::post('/teams', 'TeamsController#store');
});
How do i fix this problem ? Any help would be appreciated.
why do use the validation looks like laravel 4 while you are using laravel 5!!
in laravel 5 you need first to make Request class that handle your validation
php artisan make:request RequestName
you will find the request class that you make in
'app/http/Requests/RequestName.php'
and in the rules function you can handle your validation
public function rules()
{
return [
// put your validation rules here
'team_name' => 'required|min:10'
];
}
finally in your controller
use App\Http\Requests\RequestName;
public function store(RequestName $request) {
Team::create($request->all());
return Redirect::back();
}
for more illustration here
I recommend you to use Laravel Form Request
run
artisan make:request TeamRequest
add some logic and rules
class TeamRequest extends Request {
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true; //you can put here any other variable or condition
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
// put your validation rules here
];
}
}
then your contorller code will be like so:
public function store(TeamRequest $request)
{
$team = Team::create($request->all());
return back();
}
you no longer need to validate request and redirect back with errors and other stuff, laravel will do it for you
And you code looks more clean and neat, isn't it?
Write below code in your controller :
// define rules
$rules = array(
'team_name' => 'required|min:10'
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails())
{
// something
return Redirect::back()
->withErrors($validator) // send back all errors to the login form
->withInput();
}
else
{
// something
// save your data
$team = new Team;
$team->team_name = $request->team_name;
$team->save();
}
change in View File :
#if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
After a little bit research, i have found that Laravel 5.2 has a RouteServiceProvider and it includes web middleware group for all routes. So i do not have to add the web middleware group to my routes manually. I just removed it from routes.php and problem solved.
If i remove web middleware group from my routes, errors displays fine.
In Laravel 5.2 the web midddleware is automatically applied to your routes in routes.php so no need to apply web middleware again. It is defined in mapWebRoutes() method of RouteServiceProvider.

Laravel -5: How do I get my form inputs to validate (among other things..)?

I have a few problems.
I can't seem to display the saved data inside my form inputs.
I can't get my urls to validate unique.
My controller code looks very redundant.
Getting the urls to validate unique takes priority though.
Also I created the table for sharing social links with a user one to many relationship. I think thats correct. If not, please correct me.
update Just a thought...I think I'm probably complicating things by only have a single 'type' column. It would be easier if I had a column for each type of link i.e facebook col, twitter col etc. I just didn't want empty columns if user didn't provide info for some services
Heres my code:
UPDATE I gave up and just added individual columns for the different types of urls and changed to a one-to-one relationship.
form
{!! Form::model($user_links,['method' => 'PATCH', 'action'=> ['UserController#update_social']]) !!}
<div class='row form-group'>
<div class='col-md-2'>
{!! Form::label('facebook', 'Facebook Username') !!}
</div>
<div class='col-md-7'>
{!! Form::text('facebook', '',['class'=>'form-control']) !!}
</div>
</div>
<div class='row form-group'>
<div class='col-md-2'>
{!! Form::label('twitter', 'Twitter Username') !!}
</div>
<div class='col-md-7'>
{!! Form::text('twitter', null,['class'=>'form-control']) !!}
</div>
</div>
<div class='row form-group'>
<div class='col-md-2'>
{!! Form::label('reddit', 'Reddit Username') !!}
</div>
<div class='col-md-7'>
{!! Form::text('reddit', null,['class'=>'form-control']) !!}
</div>
</div>
<div class='row form-group'>
<div class='col-md-3'>
{!! Form::submit('Save Changes',['class'=>'btn btn-md btn-success']) !!}
</div>
</div>
{!! Form::close() !!}
controllers
public function show_social(Request $request){
$user_links= $request->user()->links;
return view('user.edit.social_connect',compact('user_links'));
}
public function update_social(SocialRequest $request){
$facebook= Input::get('facebook');
$twitter= Input::get('twitter');
$reddit= Input::get('reddit');
$user = $request->user();
$this->validate($request,['url'=>'unique']);
if(Input::has('facebook')||Input::has('google')||Input::has('reddit')||Input::has('twitter'))
{
if($facebook != ""){
$link = new SocialLinks();
$link->type = 'facebook';
$link->url='https//www.facebook.com/'.$facebook;
$link->user_id=$user->id;
$link->save();
}
if($twitter != ""){
$link = new SocialLinks();
$link->type = 'twitter';
$link->url='https//www.twitter.com/'.$twitter;
$link->user_id=$user->id;
$link->save();
}
if($reddit != ""){
$link = new SocialLinks();
$link->type = 'reddit';
$link->url='https//www.reddit.com/user'.$reddit;
$link->user_id=$user->id;
$link->save();
}
return Redirect::back()->with('message','Your profile has been updated');
}
return Redirect::back();
}
my model file
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Eloquent;
class SocialLinks extends Eloquent{
protected $table= 'social_links';
protected $fillable=[
'type',
'url'
];
public function user()
{
return $this->belongsTo('App\User');
}
}
?>
my request
<?php
namespace App\Http\Requests;
use App\Http\Requests\Request;
class SocialRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'url'=>'unique|user_id'
];
}
}
Okay, there are a few things wrong here. Your request file is being used incorrectly. You need a model for that, unless ofcourse you're just getting "request file" and "model" mixed up. For the purpose of this comment, I'm going to use Laravel's validation method from within the controller.
Something worth noting, your "url" is not present within the form. The validation looks for a "url" parameter inside of the request, but as you do not appear to be sending that within the form, it is quite redundant. Also, when you use the "unique" validator, you need to supply a database table for it to search and check against the supplied value, in this case; url.
I've added that in, but, really it's not doing anything because the url will always be empty until you supply it in your form, so the request will always pass.
public function show_social(Request $request)
{
$user_links = $request->user()->links;
return view('user.edit.social_connect', compact('user_links'));
}
public function update_social(Request $request)
{
$facebook = $request->facebook;
$twitter = $request->twitter;
$reddit = $request->reddit;
$user = $request->user();
$this->validate($request, [
'url' => 'unique:social_links,column',
]);
if($request->has('facebook') || $request->has('google') || $request->has('reddit') || $request->has('twitter'))
{
if($facebook != ""){
$link = new SocialLinks();
$link->type = 'facebook';
$link->url = 'https//www.facebook.com/'.$facebook;
$link->user_id = $user->id;
$link->save();
}
if($twitter != ""){
$link = new SocialLinks();
$link->type = 'twitter';
$link->url = 'https//www.twitter.com/'.$twitter;
$link->user_id = $user->id;
$link->save();
}
if($reddit != ""){
$link = new SocialLinks();
$link->type = 'reddit';
$link->url = 'https//www.reddit.com/user'.$reddit;
$link->user_id = $user->id;
$link->save();
}
return Redirect::back()->with('message','Your profile has been updated');
}
return Redirect::back();
}
As you can see, I removed the type hinting for your request because what you were actually doing (from what I can tell), was type hinting the model. Your "request file" which you supplied is a model and should be in the App/ directory, and referenced using a namespace.
If you are indeed using that file as a model, then your relationship looks okay, assuming of course you've got the right foreign column setup in your database, referencing the user table.
As for your model binding not working, have you tried dumping the $user_links variable, like so: dd($user_links); - to see if it actually contains anything? As you're using a request there, I cannot tell where you're getting the information.
Hopefully this helps, if you have any more questions, feel free to ask.

Laravel Message Bag Error

Am working on form validations for newsletter for a project am on, the news letter form appears on every page so it will also appear on the longin and registration page so i decided to make use of Laravel Message Bags to store the news letter errors but it keeps giving me an undefined property error on the actual page i check and output echo the errors, i don't know if am doing something wrong here are the details though!
The Error:
Undefined property: Illuminate\Support\MessageBag::$newsletter
My code In the Controller:
return Redirect::back()->withInput()->withErrors($inputs, "newsletter");
My code in the View:
#if($errors->newsletter->any())
<p>
{{$errors->newsletter->any()}}
</p>
Code in controller:
$post_data = Input::all();
$validator = Validator::make(Input::all(),
array(
'email' => 'required',
'password' => 'required'
));
if ($validator->fails()) {
return Redirect::back()
->withInput()
->withErrors(['auth-validation' => 'ERROR: in validation!']);
}
Code in vew:
#if($errors->any())
#foreach($errors->getMessages() as $this_error)
<p style="color: red;">{{$this_error[0]}}</p>
#endforeach
#endif
The RedirectResponse class function withErrors() doesn't have a second parameter..
The function vendor\laravel\framework\src\Illuminate\Http\RedirectResponse.php -> withErrors():
/**
* Flash a container of errors to the session.
*
* #param \Illuminate\Support\Contracts\MessageProviderInterface|array $provider
* #return \Illuminate\Http\RedirectResponse
*/
public function withErrors($provider)
{
if ($provider instanceof MessageProviderInterface)
{
$this->with('errors', $provider->getMessageBag());
}
else
{
$this->with('errors', new MessageBag((array) $provider));
}
return $this;
}
So, if you really want to use the MessageBag then this should work (didn't test it):
$your_message_bag = new Illuminate\Support\MessageBag;
$your_message_bag->add('foo', 'bar');
return Redirect::back()->withInput()->withErrors($your_message_bag->all());
withErrors should receive the messages from validator object. After your validation process something like:
$validation = Validator::make(Input::all(), $validation_rules);
if (!$validation->passes()){
return Redirect::back()->withInput()->withErrors($validation->messages());
}
I hope it works fine for you.
You can write a function like this
if(!function_exists('errors_for')) {
function errors_for($attribute = null, $errors = null) {
if($errors && $errors->any()) {
return '<p class="text-danger">'.$errors->first($attribute).'</p>';
}
}
}
then in your View
<div class="form-group">
<label for="bio">Bio</label>
<textarea class="form-control" name="bio"></textarea>
</div>
{!! errors_for('bio',$errors) !!}
learnt from Jeffrey Way on Laracasts

Categories