image does not want to be updated if the other values are not changed - laravel

I want to update the user image but the user image will only be updated if other values are also updated, such as name/username, I have tried various ways, even though in the edit post section there is no problem
so this is my form
<form action="/profile/{{ auth()->user()->id }}" method="post" enctype="multipart/form-data">
#method('put')
#csrf
<label for="">Name</label>
<input type="text" name="name" value="{{ auth()->user()->name }}">
<label for="">Username</label>
<input type="text" name="username" value="{{ auth()->user()->username }}">
<label for="">Profile Picture</label>
<input type="file" name="image">
<button type="submit">Update</button>
</form>
my web route
Route::get('/profile/{user}/edit', [ProfileController::class, 'edit'])->middleware('auth');
my ProfileController
$rules = [
'name' => ['required', 'max:15'],
'username' => ['required', 'min:5', 'max:12', 'unique:users'],
'image' => ['nullable','image','file','max:1024'],
];
$validatedData = $request->validate($rules);
if($request->file('image')) {
if($user->image){
Storage::delete($user->image);
}
$validatedData['image'] = $request->file('image')->store('profile-images');
}
$user->update($validatedData);
return back();
I have tried several ways and I have also created an edit post feature and it works well, I tried to copy and paste the code and change a little from the edit post feature but it doesn't work, the image is only updated if the other values are also edited / updated, what I want is that the image is updated even if the others are not updated, thank you

It seems to be due to the browser cache history.
Browsers usually store image data in cache. So if the image name is the same it won't be updated.
So I solved this problem like this.
All image names contain a unique random string with extension + ?
ex:Lynn.jpg?33f3r3

Related

Post form in a button

In the admin dashboard you can make a post inactive if its active and vice versa. When you click on the button: 'make inactive', you send this form
<form method="POST" action="/admin/posts/inactivate/{{$post->id}}" enctype="multipart/form-data">
#csrf
#method('PATCH')
<input type="number" id="active" name="active" value="1" hidden readonly>
<button type="submit">Make inactive</button>
</form>
I dd'd and made sure the correct 'active' value is given but when I click the button to update the value in the database it just does nothing(redirects back to the dashboard with no change). I have this in my controller
public function makeInactive(Post $post){
$attribute = request()->validate([
'active' => 'required',
]);
$post->update($attribute);
return redirect()->back();
}
I have the same sort code for updating user data and it works just fine. Am I missing something?
it works for me :) but I made the "active" column in the database as integer what about yours ?

Save array [ ] of form data in same columns individual row - Laravel

when the user click add more and submit their form data, I'm having a problem saving form array like this (service[], Amount[], Description[]) in database rows. I have two related tables of invoices and invoice_details, i want the form array to submit the list of form data into the invoice_details table. I have successfully created the models and relations between the invoice and invoice_details.
<!--Blade -->
<div class="service-box">
<div class="row">
<div class="col-md-12 service-group">
<div class="row">
<div class="form-group mb-3 col-md-6">
<label class="form-label">Service</label>
<div >
<select type="text" class="form-select" placeholder="Services" value="" name="service[]" id="service">
<option value="" disabled selected>Select your option</option>
#foreach ($services as $service)
<option value="{{$service->service_name}}" data-id="{{$service->amount}}">{{$service->service_name}}</option>
#endforeach
</select>
</div>
</div>
<div class="form-group mb-3 col-md-6">
<label class="form-label">Amount</label>
<div >
<input type="text" class="form-control" name="amount[]" id="amount" placeholder="Amount" readonly>
</div>
</div>
<div class="form-group mb-3 col-md-12">
<label class="form-label">Description</label>
<textarea class="form-control" id="description" name="description[]" rows="6" placeholder="Description.." ></textarea>
</div>
</div>
</div>
</div>
</div>
//Controller
$invoicedetailModel = new Invoice_detail;
//Here is where the problem lies, I have to save for arrays.
$invoicedetailModel->service = request('service');
$invoicedetailModel->amount = request('amount');
$invoicedetailModel->description = request('description');
$invoiceModel->Invoice_details()->save($invoicedetailModel);
It seems to me (correct me if I'm misinterpreting) that you're trying to save a batch of different InvoiceDetails and attach them to an original Invoice model.
The problem here is that you're trying to do so by passing arrays to a single invoiceDetails model so let's suppose you have the you have two detail instances passed by form you would have the request parameters structured like this:
$request->service: ['serviceX','serviceY']
$request->amount: [1,2]
$request->description: ['Lorem', 'Ipsum']
So if you tried to create the model you're trying to save in your code you would be doing something like this:
Invoice_Details::create([
'service' => ['serviceX', 'serviceY'],
'amount' => [1,2]
'description' => ['Lorem', 'Ipsum']
]);
Which can not work because those values are not set as Json to the database, and also explains why the createMany is not working, because there's a single object that uses an array of values for each value. What you might want is a situation like this:
Invoice_Details::createMany([
[
'service' => 'serviceX',
'amount' => 1
'description' => 'Lorem'
],
[
'service' => 'serviceY',
'amount' => 2
'description' => 'Ipsum'
]
]);
So you should iterate the request parameters and save a whole array of single models rather than try to stuff everything into a single one.
Also, it's pretty legitimate to ask yourself "Sure, but they all have two parameters, why doesn't it just split them when I use the createMany method?" Well, let's suppose the same situation with different parameters:
$request->service: ['serviceX','serviceY']
$request->amount: [1,2]
$request->description: ['Ipsum']
To which model does that description belong to? We could just go by appearence order, but this kind of assumption might lead to huge problems in case of bad implementations. This sadly means that everytime we need to create multiple models we need to define every single one, even though it means adding an iteration beforehand.
TL;DR: Instead of an array of parameters you need an array of models. Iterate through your parameters and build your models before saving them.
//Supposing you already fetched the arrays and they are all of the same length
$details = [];
foreach($services as $key => $service) {
$invoicedetailModel = new Invoice_detail();
$invoicedetailModel->service = $services[$key];
$invoicedetailModel->amount = $amounts[$key];
$invoicedetailModel->description = $descriptions[$key]);
$details[] = $invoicedetailModel;
}
// code to create and attach the many models

Submit POST data from controller

I am trying to implement Payhere payment gateway (Local gateway based in Sri Lanka). As per their documentation we could submit data as below.
<html>
<body>
<form method="post" action="https://sandbox.payhere.lk/pay/checkout">
<input type="hidden" name="merchant_id" value="121XXXX"> <!-- Replace your Merchant ID -->
<input type="hidden" name="return_url" value="http://sample.com/return">
<input type="hidden" name="cancel_url" value="http://sample.com/cancel">
<input type="hidden" name="notify_url" value="http://sample.com/notify">
<br><br>Item Details<br>
<input type="text" name="order_id" value="ItemNo12345">
<input type="text" name="items" value="Door bell wireless"><br>
<input type="text" name="currency" value="LKR">
<input type="text" name="amount" value="1000">
<br><br>Customer Details<br>
<input type="text" name="first_name" value="Saman">
<input type="text" name="last_name" value="Perera"><br>
<input type="text" name="email" value="samanp#gmail.com">
<input type="text" name="phone" value="0771234567"><br>
<input type="text" name="address" value="No.1, Galle Road">
<input type="text" name="city" value="Colombo">
<input type="hidden" name="country" value="Sri Lanka"><br><br>
<input type="submit" value="Buy Now">
</form>
</body>
</html>
This will redirect to url "https://sandbox.payhere.lk/pay/checkout" and opens a widow to submit card details.
But what I want to do is, send related POST data from a controller without a view (Same function as above, but through controller when after an database insertion done)
Any suggestion how to do this. I have tried using HTTP client, but since above gateway redirect to external url and popsup a window that's collect data.
$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://sandbox.payhere.lk/pay/checkout', [
'form_params' => [
"merchant_id" => '1218XXX',
"return_url" => route('admin.dashboard'),
"cancel_url" => 'key-app.test',
"notify_url" => route('notify'),
"order_id" => '1',
"items" => 'Test',
"currency" => 'LKR',
"amount" => '50.00',
"first_name" => 'Arafath',
"last_name" => 'a',
"email" => 'mhmaarafath#gmail.com',
"phone" => '0765245237',
"address" => 'Mount Lavinia',
"city" => 'Colombo',
"country" => 'Sri Lanka',
]
]);
return redirect('https://sandbox.payhere.lk/pay/checkout');
First point you can't make a Guzzle request here since you need to open a new window here. (instead of Guzzle you can use HTTP client )
Yo can do something like below to accomplish your requirement
Get all related data from db inside controller and then return a view with that data where that view has the payhere form and you can hide the form with css. payhereCheckout ()
Now submit the form via JQuery or JS . What you have to do is just click form submit button via JS or JQuery. Just put a small loader or something which may show the user to that the server is processing the request.
I'll provide some codes how you need to achieve this. I have not used this process to PayHere but all the payment gateways in SL use a form submission .So that process should same.Here is the example code.
Controller
class PayHereChekoutControler extends Controller
{
public function payhereCheckout () {
$userData = UserDataModel::find(Auth::id());
$email = $userData->email;
$firstName = $userData->first_name;
//Other required paramas here or just pass the collection to view and get the required feilds there.
return view('payhere_hidden_checkout', compact(
'first_name',
'email',
));
}
}
web.php
Route::get('payhere-payment,'[PayHereChekoutControler::class, 'payhereCheckout']);
payhere_hidden_checkout.blade.php
<form id="payhere" style="display:none" method="post" action="https://sandbox.payhere.lk/pay/checkout">
<input type="text" name="first_name" value="{{$first_name}}">
<input type="text" name="email" value="{{$email}}">
<input type="submit" value="Buy Now">
</form>
<script>
$(document).ready(function () { // Now the DOM is ready
//Start loader or something here. You don't need to hide the loader because once form submitted it will redirect to payhere
setTimeout(() => {
$('form#payhere').submit();
}, 500)
});
</script>
I have not used this for Payhere but I have implemented this to WEBXPAY. Both the gateways use same process.
Hope this will make a scene to your requirement.

Validation on checkbox where one one checkbox must be checked in laravel

I have the following Checkboxes now a want put validation in checkbox that one checkbox must be checked . But i dont't know how to do that.
CheckBox
<div class="form-group clearfix">
<label for="" class="col-sm-2 col-form-label">Arch (es) </label>
<div class="col-sm-10">
<label class="control-label" for="inputError" style="color: red"><i
id="arch_upper_error"></i></label>
<div class="demo-checkbox">
<input id="md_checkbox_1" name="arch_upper" value="41" class="chk-col-black"
type="checkbox">
<label for="md_checkbox_1">Upper</label>
<input id="md_checkbox_2" name="arch_lower" value="41" class="chk-col-black"
type="checkbox">
<label for="md_checkbox_2">Lower</label>
</div>
</div>
</div>
I tried this in laravel validation but i know its wrong because it required for both but i want at least one checkbox is checked.
public function rules()
{
return [
'arch_lower' => 'required',
'agarch_upper' => 'required',
,
];
}
I think you could use Laravel's required-without method:
The field under validation must be present and not empty only when any
of the other specified fields are not present.
Implementation would look something like this:
'arch_upper' => 'required_without: arch_lower',
If, by any chance, you have more checkboxes, you could use required-without-all:
The field under validation must be present and not empty only when all
of the other specified fields are not present.
Implementation:
'arch_upper' => 'required_without_all: arch_lower,another_checkbox',
Note: Code is not tested, if you encounter any errors, let me know.
You can read more on Laravel's official documentantion.

Single Checkbox Form Laravel 5.5

I'm working on a webpage where users can click a checkbox; any user can click the checkbox, and the result will be the same when viewed by all users. So, if User A checks the box, User B will see it as checked. If User B then unchecks it, User A will see it as unchecked.
I can get the checkbox to display the value from the database, but I can't seem to get the value to change and update in the database when a user clicks on the checkbox.
My blade layout looks like this:
<form method="POST" action="{{ action('QuestionController#answered', $question->id) }}" role="form">
{{ csrf_field() }}
<input type="checkbox" id="answered" name="answered" value="0" #if($question->answered == 1) checked #endif> Answered
</form>
The function in my controller looks like this:
public function answered(Request $request, $id)
{
$request->request->add(['answered_userid' => $this->userId]);
$this->validate($request, [
'answered' => 'required',
'answered_userid' => 'required'
]);
Question::find($id)->update($request->all());
}
}
And, in my routes file, I have this:
Route::post('questions/answered', ['as' => 'questions.answered', 'uses' => 'QuestionController#answered']);
EDIT: I've updated it to include the name, but I'm still running into the same problem.
You have to set a name in the input. The request will use the name of the input as the parameter:
<input type="checkbox" name="answered" id="answered" value="0" #if($question->answered == 1) checked #endif>
Set the name and its value
<input type="checkbox" name='answered' {{$question->answred ==1 ? Value="1" checked : value="0"}}>

Resources