Laravel form data not posting to update controller - php

I am debugging a piece of code one of my team members has submitted, I am not too familiar with Laravel so bear with me if I've missed anything, but basically the form will submit and be redirected to the correct update controller, but when I try to get the result of one of the changed fields in the form, it is just blank.
Index Form Data
<form method="POST" action= "{{ route('apparatus_codes.update' , $apparatusCode->id )}}" class="is-readonly" >
#csrf
#method('PUT')
<tr id="table{{ $apparatusCode->id}}" data-target=".table{{ $apparatusCode->id}}">
<td class="main-bg"> {{ $apparatusCode->id}} </td>
<td class="data main-bg"><input name ="rent" id="rent" value = "{{ $apparatusCode->rent}}"/></td>
<input type="submit" id="save-button" class="save"><img class="mb-1 duration-300 ml-4 inset-0 h-6 w-6" src="/../../img/save-icon.svg" alt="save icon">
</form>
Controller
public function update(ApparatusCodesRequest $request, $id)
{
// find selected apparatus code details
$apparatusCodes = ApparatusCodes::find($id);
$test = $request->input('rent');
echo "TEST".$test;
}
If I echo the $apparatusCodes variable, this will display the correct data from the form on page load. However, I have an input field on the rent field, and the changed value for this field will not come through onto the controller. Also if I echo $request->all or dd($request->all()) there will be no data coming through. I can't tell why nothing is coming through when my form looks to be similar to others I have seen?
There are no errors appearing, it is reaching the intended controller ok it seems, but just not able to retrieve any of the inputted data. Any help would be great. Thanks.
Routes file
Route::post('/apparatus_codes/{id}', [App\Http\Controllers\ApparatusCodesController::class, 'update'] )->name('apparatus_codes.update');
ApparatusCodesRequest.php
<?php
namespace App\Http\Requests;
use Illuminate\Http\Request;
use Illuminate\Foundation\Http\FormRequest;
use App\Models\ApparatusCodes;
class ApparatusCodesRequest extends FormRequest
{
/**
* 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()
{
// initalising so that memo rule doesn't throw error when creating new apparatus code
$stored_memo = '';
// this is returning id of current apparatusCode
$apparatusCodes_id = $this->route('apparatusCodes');
// this request is used for both create, and update
// we don't want to check for a stored memo when validating a create request
if(!$apparatusCodes_id == null){
// getting the current memo for grantor
// used to check that memo has been updated
$stored_memo = ApparatusCodes::where('id', $apparatusCodes_id)->pluck('memo')->firstOrFail();
}
return [
];
}
public function messages()
{
return [
'memo.not_in' => 'An update to the memo field is required'
];
}
}

Related

How do delete single row in pivot table with laravel

I want to delete a single row of data in my pivot table. I don't get any error but when try to click on the button. It did not redirect me to anywhere so the delete function is not performed.
In the picture above I want to delete the highlighted id for user_id = 3
My scenario is that the user suddenly can't make it to even_id = 6 so the user wants to delete/unjoined the event.
route
Route::get('/user/event/{event}', 'HomeController#destroy')->name('user.event.destroy');
blade
#foreach ($events as $event)
<tr>
<td>{{$loop->index +1 }}</td>
<td>{{$event->event_name}}</td>
<td>{{$event->event_date}}</td>
<td>
<form method="POST" action="{{ route('user.event.destroy',$event)}}">
#csrf
#method('DELETE')
<a class="btn btn-danger">Unjoined!</a>
</form>
</td>
</tr>
#endforeach
controller
public function storeEventUser(Request $request)
{
$user = User::find(Auth::user()->id);
//how I storing my pivot data (just to show if anyone asking)
$user->events()->syncWithoutDetaching([$request->event_id]);
}
public function destroy($event)
{
$event= Event::findOrFail($event_id);
$user->events()->detach($event);
return redirect()->back()->with('success','Deleted.');
}
Event model
public function users()
{
return $this->belongsToMany(User::class,'event_user','event_id','user_id');
}
user model
public function events()
{
return $this->belongsToMany(Event::class,'event_user','user_id','event_id');
}
I am adjusting your controller method to use Route Model Binding for simplicity:
public function destroy(Event $event)
{
Auth::user()->events()->detach($event);
// or from the other side of the relationship
// $event->users()->detach(Auth::user());
return redirect()->back()->with('success', 'Deleted.');
}
As stated in the comments you need to adjust your route to Route::delete if you want to use the DELETE HTTP method that your form is spoofing via the #method('DELETE') blade directive.
Side note:
Auth::user() returns a User instance so you don't need to query for it again, in your storeEventUser method:
$user = Auth::user();

Laravel 5.0 - Using Request in function

I am building an application that uses the repository pattern. Now what I have done is reuse functionality but I have hit a bit of a hiccup. I have one view that shows several different models on it. These models are related through a one-to-one relationship (MovieBasic to MovieDetail) and one-to-many relationship (MovieBasic to MoviePersonnel). The issue I am having is that I have two different request to validate my forms. They are MovieBasicRequest, which validates my movie's basic information (Title, synopsis) and MovieDetailRequest, which validates my movie's detail information (price, screen type, runtime, etc). So to distinguish between which request to use I have added a parameter to my url as follows:
movie_basic.blade.php
<?php $params = ['id' => $movie->id, 'type' => 'movie_basic']; ?>
<h4>Movie Baiscs <span class="pull-right">Edit</span></h4>
<hr>
<table class="table table-bordered">
<tbody>
<tr>
<td>{{ $movie->movie_title}}</td>
</tr>
<tr>
<td>{{ $movie->movie_synopsis }}</td>
</tr>
</tbody>
</table>
I know that using the <?php ?> tags is not best practice but I will clean that up later. So because of my $params the URL will look like so
www.moviesite.dev/1/edit?movie_basic
Which will call the edit function in the controller like so
MovieController.php
/**
* Show the form for editing the specified resource.
*
* #param int $id
* #return Response
*/
public function edit($id)
{
$movie = $this->movieBasic->find($id);
return view('cms.edit', compact('movie', 'type'));
}
In this case the type does not really play a role because of the relationship between MovieBasic and MovieDetail models. However it does play a role in my update function below:
MovieController.php
/**
* Update the specified resource in storage.
*
* #param int $id, MovieBasicRequest $request
* #return Response
*/
public function update($id)
{
if(strcmp($_GET['type'], 'movie_basic') == 0)
{
$movie = $this->movieBasic->find($id);
$this->request = new MovieBasicRequest;
$this->movieBasic->update($id, $this->request);
}
elseif(strcmp($_GET['type'], 'movie_detail') == 0)
{
$movie = $this->movieBasic->find($id);
$this->request = new MovieDetailRequest;
$this->movieDetail->update($id, $this->request);
}
return redirect()->action('MovieController#show', compact('movie'));
}
Essentially what this function does is determine what is being passed in and from there call the correct request. However the way I have it now it just creates an empty array and thus validates nothing. Is there any way to uses these requests to validate information passed in? Or to validate input before I pass it to the update function of the repository?
PS. I have also tried this:
$this->movieBasic->update($id, MovieBasicRequest $request);
but I get an "Undefined variable $request" error.
You should better combine them. And you can use sometimes on your form validation for handling both where you will only validate present fields. So that your MovieRequest can be like below
class MovieRequest extends Request
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'movie_title' => 'sometimes|required|min:3',
'price' => 'sometimes|required|integer'
// and so on
];
}
}
So you can update your controller as below and use for the both pages. For instance, if the price is not set within the request, then it will skip validating it, but if it's present and empty, then it will throw an error message as it's required.
public function update($id, MovieRequest $request)
{
$movie = $this->Movie->find($id);
$movie->fill($request->all());
$movie->save();
return redirect()->action('MovieController#show', compact('movie'));
}

How to validate radio button/checkbox and must to select one in laravel

I'm trying to validate a radio button in Laravel. This is my code, but it doesn't work.
In my case, i have a dynamic form with many questions with different of type such as : radio, checkbook, single input, number input,... So I have to use array name for each type of question. For example : name="radio['.$k.']".
In my controller i make validation and $key is the $k value in initial form.
public function rules()
{
$rules = [];
if (Input::has('radio')) {
foreach (Input::get('radio') as $key => $val) {
$rules['radio.' . $key] = 'required';
}
}
if (Input::has('singleinput')) {
foreach (Input::get('singleinput') as $key => $val) {
$rules['singleinput.'.$key] = 'required|max:10';
}
}
}
public function messages()
{
$messages = [];
if (Input::has('radio')) {
// some code here;
}
}
public function answer_store($survey_id, $patient_id)
{
$rule = $this->rules();
$message = $this->messages();
$validator = Validator::make(Input::all(), $rule, $message);
}
In the view:
<input type="radio" name="radio['.$k.']" value="'.$str1.'">'.$answer->answer_body
My code works with text input type but not with radio & checkbox.
Anyone can help me?
Okay with no reply, this is my answer if you are using Laravel 5.
Laravel 5 uses requests when you submit a form. You can perform validation on that data before it executes your controller.
Firstly use your terminal to run a artisan command
php artisan make:request MyRequest
This will create a file in App\Http\Requests.
Put this in the new request file
<?php namespace App\Http\Requests;
use App\Http\Requests\Request;
class MyRequest 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 [
'myRadios' => 'required'
];
}
}
In your view, have radios like the following, ensuring the group of radios you want all have the same name.
<input type="radio" name="myRadios" value="1"> Number 1
<input type="radio" name="myRadios" value="2"> Number 2
<input type="radio" name="myRadios" value="3"> Number 3
In your Controller you will need to reference the request file and put it into your function using dependency injection.
When you want to use the value of the radio that was selected, you use the $request array
<?php namespace App\Http\Controllers;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests\MyRequest;
class MyController extends Controller {
/**
* Display a listing of the resource.
*
* #return Response
*/
public function myFormFunction(MyRequest $request)
{
//Get the value of the radio selected
$myVariable = $request['myRadios'];
}
}
?>
After one day, I found the solution for my problem.
Using if (Input::has('radio')) { } in the rule code. Because if i
don't select anything, don't have any information related radio to
validate.
For array of radio questions I use:
<input type="radio" name="radio['.$count_radio.']" value="'.$str1.'">
My problem is i don't know how many radio question each form. I have many different form. I will count number of radio form in View file and pass to Controll ($count_radio).
In controller, i make rule like this:
for ($key = 1; $key <= $count_radio; $key++) {
$rules['radio.' . $key] = 'required';
}
I also add error with this code in View:
if($errors->has('radio.'.$count_radio.'')) {
echo $errors->first('radio.'.$count_radio.'');
}
That's all.
You have the input tag ending in </label>.
Not sure if that will help.

ZF2 - Separating one form in many tabs

I need a help..
I have a unique form with multiples fieldsets, and i need separate some fieldsets in tabs..
So, i tried in the view (form is my variable with the whole form):
$form = $this->form;
$customFieldset = $form->get('customFieldset');
$form->remove('customFieldset');
It works, my fieldset form is in $customFieldset.. but, i can't render this!
When a try:
echo $this->form($customFieldset);
//OR
echo $this->formInput($customFieldset);
//OR
$this->formCollection($customFieldset);
None of that works..
I'm doing right? How i can do it?
Thank very much.
To achieve the result you want (using the form across several tabs, it is better to construct the form differently, based on the tab's number. For example, your form constructor method would look like below:
<?php
namespace Application\Form;
use Zend\Form\Form;
// A form model
class YourForm extends Form
{
// Constructor.
public function __construct($tabNum)
{
// Define form name
parent::__construct('contact-form');
// Set POST method for this form
$this->setAttribute('method', 'post');
// Create the form fields here ...
if($tabNum==1) {
// Add fields for the first tab
} else if($tabNum==2) {
// Add fields for the second tab
}
}
}
In the example above, you pass the $tabNum parameter to form model's constructor, and the constructor method creates a different set of fields based on its value.
In your controller's action, you use the form model as below:
<?php
namespace Application\Controller;
use Application\Form\ContactForm;
// ...
class IndexController extends AbstractActionController {
// This action displays the form
public function someAction() {
// Get tab number from POST
$tabNum = $this->params()->fromPost('tab_num', 1);
// Create the form
$form = new YourForm($tabNum);
// Check if user has submitted the form
if($this->getRequest()->isPost()) {
// Fill in the form with POST data
$data = $this->params()->fromPost();
$form->setData($data);
// Validate form
if($form->isValid()) {
// Get filtered and validated data
$data = $form->getData();
// ... Do something with the validated data ...
// If all tabs were shown, redirect the user to Thank You page
if($tabNum==2) {
// Redirect to "Thank You" page
return $this->redirect()->toRoute('application/default',
array('controller'=>'index', 'action'=>'thankYou'));
}
}
}
// Pass form variable to view
return new ViewModel(array(
'form' => $form,
'tabNum' => $tabNum
));
}
}
In your view template, you use the following code:
<form action="">
<hidden name="tab_num" value="<?php echo $this->tabNum++; ?>" />
<!-- add other form fields here -->
</form>

Yii, best way to implement "user change of password"

I'm using Yii for an application, I'm writing a very simple user management, like registering, deleting and updating users... For updating the existing user I need to check the old password first before change it to the new inserted password. So here is the fields I have in the form:
username:----
old_password:---
new_password:---
and my user table looks like this:
id, username, password
How can I validate the old_password before updating it with the new_password? I know the usual php coding, but I want to know if there are any Yii tricks that does this automatically...
Thanks in advance
You should not pollute your model with rubbish. Please, always have in mind these basic MVC principles:
Your controller must not be aware of your model's implementation.
Don't pollute your model with stuff not connected with your application's business model.
Always create reusable code, make your code "DRY" (Don't repeat yourself)
By the way, what is the purpose of the username field? Since the form would be available to the logged user only, the username can be accessed already with Yii::app()->user.
<?php
// models/ChangePasswordForm.php
class ChangePasswordForm extends CFormModel
{
/**
* #var string
*/
public $currentPassword;
/**
* #var string
*/
public $newPassword;
/**
* #var string
*/
public $newPasswordRepeat;
/**
* Validation rules for this form.
*
* #return array
*/
public function rules()
{
return array(
array('currentPassword, newPassword, newPasswordRepeat', 'required'),
array('currentPassword', 'validateCurrentPassword', 'message'=>'This is not your password.'),
array('newPassword', 'compare', 'compareAttribute'=>'validateNewPassword'),
array('newPassword', 'match', 'pattern'=>'/^[a-z0-9_\-]{5,}/i', 'message'=>'Your password does not meet our password complexity policy.'),
);
}
/**
* I don't know your hashing policy, so I assume it's simple MD5 hashing method.
*
* #return string Hashed password
*/
protected function createPasswordHash($password)
{
return md5($password);
}
/**
* I don't know how you access user's password as well.
*
* #return string
*/
protected function getUserPassword()
{
return Yii::app()->user->password;
}
/**
* Saves the new password.
*/
public function saveNewPassword()
{
$user = UserModel::findByPk(Yii::app()->user->username);
$user->password = $this->createPasswordHash($this->newPassword);
$user->update();
}
/**
* Validates current password.
*
* #return bool Is password valid
*/
public function validateCurrentPassword()
{
return $this->createPasswordHash($this->currentPassword) == $this->getUserPassword();
}
}
example controller action:
public function actionChangePassword()
{
$model=new ChangePasswordForm();
if (isset($_POST['ChangePasswordForm'])) {
$model->setAttributes($_POST['ChangePasswordForm']);
if ($model->validate()) {
$model->save();
// you can redirect here
}
}
$this->render('changePasswordTemplate', array('model'=>$model));
}
example template code:
<?php echo CHtml::errorSummary($model); ?>
<div class="row">
<?php echo CHtml::activeLabel($model,'currentPassword'); ?>
<?php echo CHtml::activePasswordField($model,'currentPassword') ?>
</div>
<div class="row">
<?php echo CHtml::activeLabel($model,'newPassword'); ?>
<?php echo CHtml::activePasswordField($model,'newPassword') ?>
</div>
<div class="row">
<?php echo CHtml::activeLabel($model,'newPasswordRepeat'); ?>
<?php echo CHtml::activePasswordField($model,'newPasswordRepeat') ?>
</div>
<div class="row submit">
<?php echo CHtml::submitButton('Change password'); ?>
</div>
<?php echo CHtml::endForm(); ?>
</div><!-- form -->
The template should be easy enough to create. This code, with some minor tweaks, is ready to be copied & pasted to another Yii project.
Its simple create a action that has logic for update pass.
Make target for form to new action in this case actionChangePass and validate there the way you want .
A rough example can be put like this
public function actionChangePass($id)
{
$user = loadModel($id)
if(md5($_POST['User']['old_password']) === $user->password)
{
$user->setScenario('changePassword');
$user->attributes = $_POST['User'];
$user->password = md5($_POST['User']['new_password']);
if($user->save())
Yii::app()->user->setFlash('passChanged', 'Your password has been changed <strong>successfully</strong>.');
}
else
{
Yii::app()->user->setFlash('passChangeError', 'Your password was not changed because it did not matched the <strong>old password</strong>.');
}
}
Also make sure you have $old_password in your user User Model. Also you can do some validations in rules of model to make new password required
there can be some different ways too but i do it like this
Also create your custom validation scenario changePassword
Here is what I personally like to do. It is a complicated version of this.
Add to model two fields that will help you process the password. Note these two fields do not exists in database and are not present in Gii generated code. Something like
class UserModel extends CActiveRecord
{
/*Password attributes*/
public $initial_password;
public $repeat_password;
//..................
}
In the form, do not associate the actual password field in the database with any input. The two field in database should be associated with these two fields. The short version of the form becomes:
<?php echo $form->errorSummary($model); ?>
<?php echo $form->passwordFieldRow($model,'initial_password',array('class'=>'span5','maxlength'=>128)); ?>
<?php echo $form->passwordFieldRow($model,'repeat_password',array('class'=>'span5','maxlength'=>128)); ?>
Now how do I know that user changed password? I simply check in beforeSave() if the two fields are empty and compare them and then change the password. If they are empty then I just skip the whole thing altogether. So simple version of beforeSave is:
/**
* Called before saving the model
*/
protected function beforeSave()
{
if(parent::beforeSave())
{
if($this->isNewRecord)
{
$this->password = HashYourPass($this->initial_password);
}
else
{
//should we update password?
if($this->initial_password !== '')
{
//encrypt password and assign to password field
$this->password = HashYourPass($this->initial_password);
//Check old password match here
}
}
return true;
}
else
return false;
}
Now according to your question, one thing is missing. Checking old password! You can add new Model fields called aold password and its form input control. Then in beforesave method (as indicated by comment) you can compare the input with actual password field from the database and if they match then do change password.
You can add them as validation rules with scenarios but I found it complicated somehow and with little time at hand I went with this method.

Categories