Laravel 5 - MethodNotAllowedHttpException when validation is false - php

Always when the validation fails, I get a MethodNotAllowedHttpException
routes.php
Route::post('download', 'UrlController#download');
Route::post('search', 'UrlController#search');
UrlController.php
public function download(DownloadRequest $request)
{
dd($request->all());
}
DownloadRequest.php
public function authorize()
{
return true;
}
public function rules()
{
return [
'format' => 'required|between:1,13'
];
}
name.blade.php
{!! Form::open(['url' => 'download']) !!}
{!! Form::select('format', [
'Please select format',
'FormatGrp1' => [1 => 'best', 'p1','p2', 'p3', 'p4'],
'FormatGrp2' => [6 => 'p5', 'p6']
]) !!}
When "Please select format" is chosen and the form is submitted, I always get this error because "Please select format" has value 0 and i specified values must be between 1 and 13. (Look at DownloadRequest.php)
Thanks for help!

The error didn't come from the validation.
It was because it called the URL to go back and display the errors. And this is the search method.
So cause of the logic in search method the exception has been thrown.

When you have this error, in your if ($validator->fails()) { } consider that you are going to open the view you are working on for the first time, and add ->withErrors($validator)
For example:
public function edit($id)
{
$exams = Exam::all();
return view('exams.index', compact("exams"));
}
...
public function update(Request $request,$id)
{
$validator = Validator::make($request->all(),[
'start' => 'required',
'end' => 'required|after:start'
]);
if ($validator->fails())
{
$exams = Exam::all();
return view('exams.index', compact("exams"))->withErrors($validator);
}
//Your update code if validator not fails
}

I didn't exactly understand what this user was trying to explain as the actual problem or solution - I came across this question as I had the same issue and thought I would describe what I had done in error and how I solved it...
For me, I was building a site where users would submit photos. When the user clicked on the "add photo" it took them to a page where they had to check a box to accept a legal disclaimer. This form with the checkbox was a POST request. After they accepted it they would get re-directed to the photo submission page... WHICH WAS ALSO A FORM WITH A POST REQUEST. This was my issue: back to back POST request pages. If the user entered invalid data on the submission form, or didn't enter data in a field at all Laravel tries to essentially hit the "back button" in your browser and keep the form filled with the data the user did enter. The problem is that the "back" button (or the way the user came to this page) was from a POST request, so it couldn't do it. It gave me the error described above. Once I switched the legal acceptance page to a GET request form and updated the route to match everything started working fine. It was a foolish error on my part, I just hope to mitigate this frustration for others as they are learning to develop in Laravel. Have a great day!

Related

Laravel admin update users' info, duplicate email entry when updating his own admin account information

I am working on a laravel 8 application and using spatie/laravel-permission for roles and permissions. On the admin page, I'm displaying all users which the admin can do CRUD operations on. The users list also includes his own admin account.
The problem I'm having is when updating user details. The admin can successfully update user account information for other users with validation. However, if the admin tries to edit the information of his own admin account, the validation passes but I get an SQL error :
Integrity constraint violation: 1062 Duplicate entry 'admin#email.com'
for key 'users_email_unique'
See below my UserController update method for updating user information with validation:
public function update(Request $request, User $user)
{
$edit_user_rules = array(
// ... other validation rules ...
//'email' => "required|email|unique:users,email,{{$user->id}}", //. auth()->user()->id,
'email' => ['required', 'string', 'email', Rule::unique('users')->ignore($user->id)],
// ... other validation rules ...
);
$validator = Validator::make($request->all(), $edit_user_rules);
if ($validator->fails()) {
Session::flash('failed', 'Failed to save User details!');
return redirect(route('editUser', ['user' => $user->id]))->withErrors($validator)->withInput();
} else {
$validated = $validator->validated();
$updatedUser = User::find($user)->first();
// ... other user fields ...
$updatedUser->username = $validated['username'];
$updatedUser->email = $validated['email'];
// ... other user fields ...
if ($updatedUser->save()) {
return redirect(route('allUsers'));
} else {
return redirect(route('allUsers')); // with errors
}
}
}
I've tried to use different validation rules on the email field, for example,
"required|email|unique:users,email,{{$user->id}}"
"required|email|unique:users,email," . auth()->user()->id
but none worked. So I used a validation Rule to validate the unique email field. It works fine when I try to update other users' information but I get the SQL duplicate email error when updating the admin's own account.
Would appreciate any help I can get
The error is getting passed the validation rules, but it's failing when it saves the rule. This is because you're not getting the user properly. find() automatically gets the first record, so first() is unneeded, and is actually probably pulling the wrong account. When I try User::find(3)->first() locally, I'm getting user 1 instead of user 3. Remove first() from your call.
$updatedUser = User::find($user->id);
You didn't determined which column should be unique to ignore him self.
Change your email validation line to :
'email' => ['required', 'email', Rule::unique('users', 'email')->ignore($user->id)],
Don't forget to put this like to top of your code use Illuminate\Validation\Rule; .

Table column filled later on

I'm new on Laravel and as I'm playing around with it I encounter this issue.
I have a registration system which worked fine but now I wanted to add a new field in my table (description field for users).
However, this description field, I don't want to be filled when the user signs up, I want the user to fill this when he gets on his profile and updates a modal window.
The problem is, if I let that filed empty, I get an error when I sign up saying that the description filed can't be empty.
This is what I use in my UserController in order to update the description field but I'm not sure if is correct.
public function postDesc(Request $request){
$this->validate($request, [
'description' => 'required|min:20'
]);
$user = User::all();
$user->description = $request->input('description');
$user->save();
return redirect()->route('user.profile.edit');
}
This is how I opened the form:
{!! Form::open(['method' => 'PUT', 'action' => 'UserController#postDesc', 'class' => 'profile-form']) !!}
You use required validation rule, that's why you get the message. You should use different validation rules for register page and profile update form.
Good practice is to create two Request classes and use them for validation of two forms.
In this scenario, I will prefer to keep your description column nullalbe(). So it won't throw an error that description field is empty at the time of sign up.
And later you can update the description field.
public function postDesc(Request $request)
{
$this->validate($request, [
'description' => 'required|min:20'
]);
// Get the logged in user id using auth and then updating description filed
$user = User::where('user_id', Auth::id())
->update([
'description' => $request->description
]);
return redirect()->route('user.profile.edit');
}

Laravel 4: Multi-Page Form on the same route?

Hello folks I am stuck.
I want to register a User in Laravel 4. Now the thing is, that I want to first grab the email and password and save them in the database. And in step 2 of the registration process, I want to grab all the other details like first and last name and so on.
The difficulty is, that everything should be under one route called signup, for example everything under http://example.org/signup
Another difficulty is, that I have to access the same route with the same methods (GET & POST) twice, because I once get and post the form for Email and Password, and then I get and post the First, Last and Company Name into the Database.
I came up with the following solution, to store everything into the session, because through the session I can access the variables. So whenever I access my UserController I check, if there is data in the session and if yes, redirect to form 2.
Here are all my files:
http://help.laravel.io/d4104cae42f9a2efe1466ce53d086826bc9f6d7f
My Get-Method from the UserController:
public function create()
{
if(Session::has('email')) {
return View::make('frontend.signup.step2');
}
else {
return View::make('frontend.signup.step1');
}
}
My Post-Method from the UserController:
public function store()
{
// If User has a email and password in the session from the first create-View
// his data should be stored and then he gets redirected to a new create-View
Session::flush();
Session::put('email', Input::get('email'));
Session::put('password', Input::get('password'));
if (Session::has('email')) {
try
{
// Let's register a user.
$user = Sentry::register(array(
'email' => Input::get('email'),
'password' => Input::get('password'),
));
// Let's get the activation code
$activationCode = $user->getActivationCode();
// Send activation code to the user so he can activate the account
// Save Email in Emaillist
Email::create(array(
'email' => Session::get('email')
));
// Redirect
return Redirect::action('UserController#create');
}
return Redirect::route('signup');
}
else {
return 'No Session here';
}
}
Here are my routes:
Route::get('signup', array('as' => 'signup', 'uses' => 'UserController#create'));
Route::post('signup', array('as' => 'signup', 'uses' => 'UserController#store'));
For some reason I believe that it gets unneccessary complicated and I believe that there must be another more simple and intuitiv way to solve this, instead with if statements and redirects to the same controller-method.
Nonetheless I came up with some other solutions, for example just using the "signup" as prefix, but I don't like it that way.
Route::group(array('prefix' => 'signup'), function()
{
Route::get('/', function(){
return 'Yeab bababy yea';
});
Route::get('step1', array('as' => 'signup.step1', 'uses' => 'UserController#getStep1'));
Route::post('step1', array('as' => 'signup.step1', 'uses' => 'UserController#postStep1'));
Route::get('step2', array('as' => 'signup.step2', 'uses' => 'UserController#postStep2'));
Route::post('step2', array('as' => 'signup.step2', 'uses' => 'UserController#postStep2'));
});
Is there any way of accomplishing the task while only using one route and without using clientside Javascript to store the variables in the database? (I am a unexperienced with ajax)
The Goal should be to catch the email and still stay on the same route, like those smart guys here for example:
https://www.crazyegg.com/signup
I hope there is a way. Thank you for your help Internet.
Kind regards,
George
P.S.
It's 1 am here in Germany, so don't be mad if I don't respond the next couple of hours to comments, because I am going to sleep now. Thank you very much.

Symfony 1.4 forms using Propel Object '<class here>' not Found

From this page:
main_dev.php/player/new
to (when I click submit):
main_dev.php/player/edit/player_id/(no id)
if I put an id here it displays fine.
When I click the submit button (somehow it saves) but displays this:
404 | Not Found | sfError404Exception
Object Player does not exist().
this is my baseform:
$this->setWidgets(array(
'player_id' => new sfWidgetFormInputHidden(), //primary key auto increment()
'player_name' => new sfWidgetFormInputText(),
'player_gold' => new sfWidgetFormInputText(),
'chara_id' => new sfWidgetFormInputText(),
'open_social_id' => new sfWidgetFormInputText(),
));
im suspecting that the issue here is that player_id is not displayed and is auto increment. that means that when i submit the form player_id is left blank and since symfony cannot find where to get the id for the reference to display a record it goes 404, is there any workaround in this?
and my action.class is left from the default(instance when i generated it) so i think is not an issue
heres what the code for saving the form:
protected function processForm(sfWebRequest $request, sfForm $form)
{
$form->bind($request->getParameter($form->getName()), $request->getFiles($form->getName()));
if ($form->isValid())
{
$Player = $form->save();
$this->redirect('player/edit?player_id='.$Player->getPlayerId());
}
}
and ofcourse for the new page controller:
public function executeNew(sfWebRequest $request)
{
$this->form = new PlayerForm();
}
If the POST request saves a new Player object (in the database), it is not your BasePlayerForm.class, nor the submit url.
If your routing works when manually entered, and not when called within the action class, then your routing.yml is probably not the problem.
If you have not over-written the configure() of the BasePlayerForm.class.php (in PlayerForm.class.php, or anywhere else), then it is not in your lib/form/ classes.
Either this answer is useless (sorry) or you do not actually mean that the action "saves" the object to the database - in which case, check the submit url/request from the newSuccess template; also verify your routing:
Your newSuccess.php form tag action should POST to main_dev.php/player:
<form method="post" action="/main_dev.php/player">
[And pass the id rendered in html as <input type="hidden" name="player[player_id]" id="player_id" />.]
Lastly, the edit routing in the url will normally match player/:player_id/edit - check if you actually have an auto-created "id" column in your schema/database in addition to the "player_id" which might really be what is causing this.

CodeIgniter - form_checkbox and a required check

I have a little checkbox on a signup form im creating which 'must' be checked before the user is allowed to continue ... Im finding it difficult to figure out how to do this with the form_validation functions as well, basically the 'agree to terms and conditions' checkbox MUST be checked in order for the user to continue, if not, an error message displayed, the code i have at the moment is below, if someone could give me a bit of a helping hand that would be great.
Ok, in my view i have the following
$agreeCheck = array( 'name' => 'agreeCheck', 'id' => 'agreeCheck', 'value' => 'agree', 'checked' => set_checkbox('agreeCheck', 'agree', FALSE));
<?php echo form_checkbox($agreeCheck); ?>
and then in my controller i have the following
$this->form_validation->set_rules('agreeCheck', 'Agree to the Terms and Conditions', 'required');
At the moment, it only remembers the value that was clicked if there is a submission, except if its not checked, it doesnt return anything.
Try this out:
$this->form_validation->set_rules('agreeCheck', 'Agree to the Terms and Conditions', 'required|isset');
Try this out:
$this->form_validation->set_rules('agreeCheck', '...', 'callback_terms_check');
And then set up this method in the controller:
function terms_check() {
if (isset($_POST['agreeCheck'])) return true;
$this->form_validation->set_message('terms_check', 'THIS IS SOOOOO REQUIRED, DUDE!');
return false;
}

Categories