Laravel 5.4 - Updating a File record - php

I'm pretty new to Laravel, thus I'm trying to learn some of the basics. I have managed to create a CRUD with file upload. What I did was I created a resource controller. My store method:
public function store(Request $request) {
$this->validate($request, [
'name' => 'required',
'avatar' => 'required|image|mimes:jpeg,png,jpg,gif,svg',
'boat_type' => 'required',
'rooms' => 'required',
'price_per_hour' => 'required',
'price' => 'required',
]);
$boat = new Boat($request->input()) ;
if($file = $request->hasFile('avatar')) {
$file = $request->file('avatar') ;
$fileName = $file->getClientOriginalName() ;
$destinationPath = public_path().'/img/boats/avatars/' ;
$file->move($destinationPath,$fileName);
$boat->avatar = $fileName ;
}
$boat->save() ;
return redirect()->route('management.index')
->with('success','New Boat Successfully Added!');
}
This method works perfectly fine, with this I am able to upload and store the details to my database and am able to manipulate it in my view.
But when I try to use the UPDATE method I have the exact code.. yet when I try to update my post everything can be updated except my avatar variable. it updates it but it stores it in a strange format. Here is my UPDATE method
public function update(Request $request, $id)
{
$this->validate($request, [
'name' => 'required',
'boat_type' => 'required',
'rooms' => 'required',
'price_per_hour' => 'required',
'price' => 'required',
]);
$boat = Boat::find($id);
if($file = $request->hasFile('avatar')) {
$file = $request->file('avatar') ;
$fileName = $file->getClientOriginalName() ;
$destinationPath = public_path().'/img/boats/avatars/' ;
$file->move($destinationPath,$fileName);
$boat->avatar = $fileName ;
}
$boat->save() ;
$boat_update = $request->all();
$boat->update($boat_update);
$request->session()->flash('alert-success', 'Boat Successfully Updated!');
return redirect('/management');
}
When I edit the avatar variable it stores it in /img/boats/avatars/C:\xampp\tmp\phpFA50.tmp
I'm not really sure what is wrong. Any help will be greatly appreciated.

$boat->save() ; you don't need to save before update -> remove it
$boat_update = $request->all(); -> Your filename is NOT in there
$boat->update($boat_update); Are all the fields $fillable? If yes you need to add the new filename to that array

Found the solution, it was pretty much a logic error as I was simply saving the file name then overwriting it with the $request->all()
The correct solution would be this:
$boat = Boat::find($id);
$boat->fill($request->except('avatar'));
if($file = $request->hasFile('avatar')) {
$file = $request->file('avatar') ;
$fileName = $file->getClientOriginalName() ;
$destinationPath = public_path().'/img/boats/avatars/' ;
$file->move($destinationPath,$fileName);
$boat->avatar = $fileName ;
}
$boat->save();
$request->session()->flash('alert-success', 'Boat Successfully Updated!');
return redirect('/management');`

Related

Laravel, update method not working properly when i want to update image file, img become null

i want to update forums table that contains
fr_user_id
fr_author
fr_title
fr_body
fr_filename
code in my controller :
$request->validate([
'fr_user_id' => 'required',
'fr_author' => 'required',
'fr_title' => 'required',
'fr_body' => 'required'
]);
$input = $request->all();
if ($image = $request->file('fr_filename')){
$destinationPath = public_path('/images');
$imgName = time() . '.' . $image->getClientOriginalExtension();
$image->move($destinationPath, $imgName);
$input['fr_filename'] = "$imgName";
} else {
unset($input['fr_filename']);
}
$forum = Forum::find($id);
$forum->update($input);
return redirect('/user/myforum')->with('success','Update Successfull');
my Routes
Route::match(['put','patch'],'/forum/update/{id}',[ForumController::class,'update'])->name('forum/update');
this code is working but the 'fr_filename' data is become null in my db, what should i do?
Had you checked, file is coming in request?

Upload file to API endpoint Laravel

I'm trying to upload files via API, in POSTMAN I can do it perfectly. However when doing in my application is not accepted.
Store in Controller:
public function store(Request $request)
{
$data = $request->validate([
'projeto_id' => 'required|integer',
'name' => 'required|string|max:255',
'logo' => 'nullable|image|mimes:jpeg,png,jpg|max:2000',
'telephone' => 'required|string|max:255',
'desc' => 'required|string',
'quantity' => 'required|integer|gt:0|lt:51',
'sequential' => 'required|integer|gt:0',
]);
$user = Auth::user()->id;
if($user != Auth::id()){
abort(403);
}
//UPLOAD IMAGEM DO GRUPO
$logo = $request['logo'];
// Check if a profile image has been uploaded
if ($request->has('logo')) {
// Get image file
$image = $request->file('logo');
// Make a image name based on user name and current timestamp
$name = Str::slug($user.'_'.time());
// Define folder path
$folder = '/uploads/images/'.$user.'/groupimg/logo/';
// Make a file path where image will be stored [ folder path + file name + file extension]
$filePath = $folder . $name. '.' . $image->getClientOriginalExtension();
// Upload image
$this->uploadOne($image, $folder, 'public', $name);
// Set user profile image path in database to filePath
$logo = $filePath;
}
$gPrivado = '0';
if($request->has('private')){
$gPrivado = '1';
}
$i = 0;
$delayCounter = 0;
$sequential = $data['sequential'];
while ($i < (int)$data['quantity']) {
$delay = $delayCounter + rand(10, 15);
CreateGroups::dispatch($data['name'] . " {$sequential}", $logo , $data['desc'], $gPrivado, [$data['telephone']], $data['projeto_id'], auth()->user())
->delay(Carbon::now()
->addSeconds($delay));
$delayCounter = $delay;
$i++;
$sequential++;
}
return redirect()->back()->with('success', 'Grupos adicionados em fila de criação, aguarde alguns minutos .');
}
Use Job to proccess:
public function handle()
{
$user = $this->user;
if ($user->instance_connected) {
$ZApi = new ZApi($user->zapi_instance_id, $user->zapi_token);
$createdGroup = $ZApi
->createGroup($this->name, $this->phones);
sleep(3);
foreach($createdGroup->groupInfo as $informacoes){
$linkInvite = $ZApi->getGroupInvite($informacoes->id);
$idGroup = $informacoes->id;
}
//DESCRICAO DO GRUPO
$descricao = $this->desc;
$setDescricao = $ZApi->setGroupDescription($idGroup, $descricao);
//GRUPO PRIVADO
if ($this->private == '1'){
$grupoPrivado = $ZApi->setGroupMessages($idGroup, 'true');
$adminOnly = $ZApi->setGroupEdit($idGroup, 'true');
}
$setImg = $ZApi->groupImage($idGroup, $this->logo);
The last line send to API, I'm using Guzzle
And this is my API function
public function groupImage(string $groupId, string $value)
{
return $this->doRequest2('POST', "group-pic", [
'multipart' => [
[
'name' => 'phone',
'contents' => $groupId,
],
[
'Content-type' => 'multipart/form-data',
'name' => 'file',
'contents' => fopen('storage'.$value, 'r'),
]
]
]);
}
But get this error response
GuzzleHttp\Exception\ClientException Client error: POST http://localhost:8081/api/danilo/group-pic resulted in a 400 Bad Request response: {"status":"Error","message":"File parameter is
required!"}
Can someone help me?

How to delete the image from the storage in laravel?

I am currently trying to delete an image when a user updates his/her post before publishing.
Everything works fine, the image is changed in the database and post page, but I want to delete the previous image.
Here is my controller
public function updatePost(Request $request){
$data = $request->all();
$postid = $request['id'];
$isExist = Post::where('id', $postid)->first();
if($isExist){
if ($request->hasFile('image')) {
$file = $request->File('image');
//Get filename with extension
$fileNameToStoreWithExt = $file[0]->getClientOriginalName();
//Get just filename
$filename = pathinfo($fileNameToStoreWithExt, PATHINFO_FILENAME);
//Get just ext
$extension = $file[0]->getClientOriginalExtension();
//File to store
$fileNameToStore = $filename . '_' . time() . '.' . $extension;
//Upload Image
$path = $file[0]->storeAs('image', $fileNameToStore);
$file[0]->move('storage/image', $fileNameToStore);
File::delete(public_path('storage/image'.$isExist['image']));
Post::where('id', $postid)->update([
'title' => $data['title'],
'category' => $data['category'],
'content' => $data['content'],
'image' => $path
]);
return response()->json([
'status'=>'200',
'response'=> 'successfully updated'
]);
}else{
Post::where('id', $postid)->update([
'title' => $data['title'],
'category' => $data['category'],
'content' => $data['content']
]);
return response()->json([
'status'=>'200',
'response'=> 'successfully updated'
]);
}
}else{
return response()->json([
'error'=> 'post does not exist'
]);
}
}
I used:
File::delete(public_path('storage/image'.$isExist['image']));
but it didn't do the job
my delete function
public function deletePost($id){
$post = Post::where('id',$id)->first();
// dd($post);
if(!$post){
return response()->json([
'status' => '500',
'error' => 'post not found'
]);
}
Storage::disk('public')->delete('/storage/image'. $post['image']);
Post::where('id', $id)->delete();
return response()->json([
'status'=> '200',
'response'=> 'Post successfully deleted'
]);
}
my storage path snapshot
use Illuminate\Support\Facades\Storage;
Storage::delete('file.jpg'); // delete file from default disk
Storage::delete(['file.jpg', 'file2.jpg']); // delete multiple files
Storage::disk('your_disk')->delete('file.jpg'); // delete file from specific disk e.g; s3, local etc
Please refer link https://laravel.com/docs/6.x/filesystem
If you look at laravel file-system documentation you will see there are multiple Disk laravel support. you can used Storage Facades to delete a file from Storage like this
use Illuminate\Support\Facades\Storage;
Storage::disk('local')->delete('folder_path/file_name.jpg');
path should be like this for public directory.
Storage::disk('local')->delete('public/image/'.$filename);
its easy to do an if statement and delete old image on updating! this code is an example edit it to your requirements.
if ($request->hasFile('file')) {
Storage::delete($myImage->file); // If $file is path to old image
$myImage->file= $request->file('file')->store('name-of-folder');
}
Another :
File::delete(public_path('images/'. $oldFilename));
see here : https://laracasts.com/discuss/channels/laravel/delete-old-image-from-public-folder-after-updating
You can use normal PHP delete file keyword #unlink
if (file_exists($image)) {
#unlink($image);
}
You can use File to delete file from specific path
$file= "image path here";
\File::delete($file);
Delete uploaded file from public dir
OR
You can use unlink for the same
$image_path = "image path here";
if (file_exists($image_path)) {
#unlink($image_path);
}
PHP -> unlink

How to store data without multiple uploads "if i don't have a file want to upload"?

I have a problem when I want to save a new data I don't want to upload file too but I have to code multiple uploads in my public function store. I want to add file when I open edit form and uploaded. what should I do?
I have tried to set validation to set but when I submit error Undefined variable: data.
public function store(Request $request)
{
$request->validate([
'employee_sid' => 'required',
'employee_npk' => 'required',
'employee_name' => 'required',
'file_uploads' => 'nullable',
'file_uploads.*' => 'file|image|mimes:pdf,jpg,jpeg,png',
]);
if($request->file('file_uploads'))
{
foreach($request->file('file_uploads') as $file)
{
$name = $file->getClientOriginalName();
$path = 'public/file/'.$request->employee_name;
$file->move($path, $name);
$data[] = $name;
}
}
$sid = new Sid;
$sid->employee_sid = $request->employee_sid;
$sid->employee_npk = $request->employee_npk;
$sid->employee_name = $request->employee_name;
$sid->file_uploads = json_encode($data);
$sid->save();
I expect when I submit that data without the file_uploads it will. but error
Undefined variable: data.
You are defining the $data variable inside an if, so if the condition is false, the $data variable will be not defined. One possible fix could be:
$sid = new Sid;
$sid->employee_sid = $request->employee_sid;
$sid->employee_npk = $request->employee_npk;
$sid->employee_name = $request->employee_name;
$sid->file_uploads = isset($data)? json_encode($data): null;
$sid->save();

My update function doesn't set values to null after saving

I received help to solve how to delete files uploaded by using the Cakephp Upload package. However, there seems to be a problem with how I update the values of the photo and dir fields. By using unlink I was able to delete the files perfectly, but there seems to be a problem when I try to set the values to null. I made a function to test it out:
public function deletePhoto2($id)
{
// $this->request->allowMethod(['post']);
if ($this->request->is(['patch', 'post', 'put'])) {
$brigada = $this->Brigadas
->findById($id)
->firstOrFail();
$brigada->dir = null;
$brigada->photo = null;
if ($this->Brigadas->save($brigada)) {
$this->Flash->success(__('Your team data has been saved.'));
return $this->redirect(['action' => 'edit', $brigada->id]);
}
$this->set('brigada', $brigada);
}
}
Before saving I find that the value of $brigada->photo and $brigada->dir are null, but values don't save. I have several possibilities that want to explore but my knowledge of PHP is a hindrance:
I may be doing updates wrong. Link
I may need to use the deleteCallback which is documented here, but I don't know how to do it. I figured that it would be with $this->Brigadas->deleteCallback() or something similar, but I'd like to understand an example first, which is why I'm asking. I found no use of these callbacks in any example on the web, and the documentation on events is still a bit esoteric for me.
Here is how BrigadasTable.php is setup to upload files:
// http://josediazgonzalez.com/2015/12/05/uploading-files-and-images/
$this->addBehavior('Josegonzalez/Upload.Upload', [
'photo' => [
'fields' => [
'dir' => 'dir',
'size' => 'photo_size', // defaults to `size`
'type' => 'photo_type', // defaults to `type`
],
'nameCallback' => function ($table, $entity, $data, $field, $settings) {
if ($entity->gvCode){
$array = explode(".", $data['name']);
return strtolower($entity->gvCode) . '_' . date("Ymd-hisa") . '.jpg';
} else{
$array = explode(".", $data['name']);
$newArray = array_pop($array);
return strtolower(join('_', $array)) . '_' . date("Ymd-hisa") . '.jpg';
}
},
'transformer' => function ($table, $entity, $data, $field, $settings) {
$extension = pathinfo($data['name'], PATHINFO_EXTENSION);
// Store the thumbnail in a temporary file
$tmp = tempnam(sys_get_temp_dir(), 'upload') . '.' . $extension;
// Use the Imagine library to DO THE THING
$size = new \Imagine\Image\Box(640, 640);
$mode = \Imagine\Image\ImageInterface::THUMBNAIL_INSET;
$imagine = new \Imagine\Gd\Imagine();
// Save that modified file to our temp file
$imagine->open($data['tmp_name'])
->thumbnail($size, $mode)
->save($tmp);
$filenameTmp = explode('.', $data['name']);
array_pop($filenameTmp);
$filenameTmp = join('_', $filenameTmp) . '.jpg';
// return debug($filenameTmp);
// Now return the original *and* the thumbnail
return [
$data['tmp_name'] => $filenameTmp,
$tmp => 'thumbnail-' . $filenameTmp,
];
},
'deleteCallback' => function ($path, $entity, $field, $settings) {
// When deleting the entity, both the original and the thumbnail will be removed
// when keepFilesOnDelete is set to false
$entity->{$field} = null;
return [
$path . $entity->{$field},
$path . 'thumbnail-' . $entity->{$field}
];
},
'keepFilesOnDelete' => false
]
]);
Thank you!
You can run an update query straight, instead of fetching the record, setting values and saving it.
$query = $this->Brigadas->query();
$query->update()
->set([
'dir' => null,
'photo' => null,
])
->where(<condition>)
->execute();
Incase any of your columns are json,
$query = $this->Brigadas->query();
$query->update()
->set([
'dir = null',
'photo' => null,
])
->where(<condition>)
->execute();

Categories