File exist but laravel can't find it (FileNotFoundException) - php

I'm trying to check if the file exists to delete it when the post is deleted but it's never finding it.
If I change the Storage::exists() for Storage::get() just to check, I get the File Not Found Exception with the path C:/xampp/htdocs/cms/blog/public/images/apple.jpg which I can see the picture if I put in the browser.
Store function on PostController
public function store(CreatePostRequest $request)
{
$input = $request->all();
if ($file = $request->file('file')) {
//
$name = $file->getClientOriginalName();
$file->move(public_path('images/'), $name);
$input['path'] = $name;
}
$new_post = Post::create($input);
return redirect(route('post.show', $new_post->id));
}
Destroy function on PostController
public function destroy($id)
{
$post = Post::findOrFail($id);
if (Storage::exists(public_path('images/') . $post->path))
Storage::delete(public_path('images/') . $post->path);
$post->delete();
return redirect(route('posts.index'));
}
I also have this on my filesystems.php
'links' => [
public_path('storage') => storage_path('app/public'),
public_path('images') => storage_path('app/images'),
],
I can easily show the image in blade with just src="{{'/images/' . $post->path}}"

You could try using unlink.
$image_path = $post->path;
unlink($image_path);
The second option is to use the File Facade.
use Illuminate\Support\Facades\File;
$filename = $post->path;
File::delete($filename);
Make sure that the image path is correct.

I Had to use the Illuminate\Support\Facades\File sugested by Aless
Fixed destroy funcion on PostController
public function destroy($id)
{
$post = Post::findOrFail($id);
$imagePath = public_path('images/') . $post->path;
if (File::isFile($imagePath))
File::delete($imagePath);
$post->delete();
return redirect(route('posts.index'));
}

Related

How can I add media files in laravel?

A user can register/sign up as either a Job Seeker or an Employer. If he is a Job Seeker, he can create a profile on the create profile page. On the form their are 4 inputs with the file type, among other inputs.
See screenshot below.
I have a Table called job_seeker_profiles, there are several columns in there, but only these 4 are relevant to my issue.
resume_id, video_one_id, video_two_id, video_three_id
I also have 2 Tables, Resumes and Videos, each have one column called 'file'.
This is working, the file paths are being inserted into the database.
In my public folder, I created 2 directories resumes and videos. This is where I want to store the files. This part is also working, when I upload a resume only (No Videos, they are optional) and click Create Profile, The file appears in the /resumes folder within my public folder.
The problem is, in the resume_id column in the job_seeker_profiles Table, I get this value inserted into my database "/Applications/XAMPP/xamppfiles/temp/phpx6Dmr" instead of the id of the file from the Resumes Table.
I think maybe it's a problem with my relationships?
Here is my code.
AdminJobSeekerProfilecontroller.php file:
public function store(JobSeekerCreateRequest $request)
{
if($file = $request->file('resume_id')) {
$name = time() . $file->getClientOriginalName();
$file->move('resumes', $name);
$resume = Resume::create(['file'=>$name]);
$input['resume_id'] = $resume->id;
}
$input = $request->all();
if($file = $request->file('video_one_id')) {
$name = time() . $file->getClientOriginalName();
$file->move('videos', $name);
$video = Video::create(['file'=>$name]);
$input2['video_one_id'] = $video->id;
}
$input2 = $request->all();
if($file = $request->file('video_two_id')) {
$name = time() . $file->getClientOriginalName();
$file->move('videos', $name);
$video = Video::create(['file'=>$name]);
$input3['video_two_id'] = $video->id;
}
$input3 = $request->all();
if($file = $request->file('video_three_id')) {
$name = time() . $file->getClientOriginalName();
$file->move('videos', $name);
$video = Video::create(['file'=>$name]);
$input4['video_three_id'] = $video->id;
}
$input4 = $request->all();
JobSeekerProfile::create($input, $input2, $input3, $input4);
return redirect('/admin/job-seeker/profile/create');
}
Resume.php Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Resume extends Model
{
protected $uploads = '/resumes/';
protected $fillable = ['file'];
//create an accessor
public function getFileAttribute($resumes){
return $this->uploads . $resumes;
}
}
JobSeekerProfile.php Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class JobSeekerProfile extends Model
{
protected $dates = ['date_of_birth'];
protected $fillable = [
'user_id',
'photo_id',
'resume_id',
'video_one_id',
'video_two_id',
'video_three_id',
'first_name',
'last_name',
'email',
'full_or_part_time',
'additional_skills',
'file'
];
public function user(){
return $this->belongsTo('App\User');
}
public function resume(){
return $this->belongsTo('App\Resume');
}
public function video(){
return $this->belongsTo('App\Video');
}
}
On a side note, I know I should store the video files on something like amazon s3, but I want to get it working this way for now. And if you have any recommendations for Laravel and hosting files on a cloud based system that would be great as well.
Thank you Tpojka. This worked for me now:
$input = $request->all();
$user = Auth::user();
if($file = $request->file('resume_id')) {
$name = time() . $file->getClientOriginalName();
$file->move('resumes', $name);
$resume = Resume::create(['file'=>$name]);
$input['resume_id'] = $resume->id;
}
$user->jobseekerprofile()->create($input);
return redirect('/admin/job-seeker/profile/create');

Image update and remove old image on Laravel

Trying to implement update article in my update controller it seems works, but the problem is when I only want to update the post without uploading an image the old always getting remove which is it shouldn't.
here's my store function
public function store(Post $post)
{
$post->update($this->validateRequest());
$this->storeImage($post);
return redirect('post/'.$post->id)->with('success', 'New ariticle has been posted');
}
}
here's my validation
private function validateRequest()
{
return request()->validate([
'title'=> 'required',
'content' => 'required',
'image' => 'sometimes|image|max:5000',
]);
}
here's my update function
public function update(Post $post)
{
File::delete(public_path('storage/'.$post->image));
$post->update($this->validateRequest());
$this->storeImage($post);
return redirect('post/'.$post->id)->with('success', 'This post has
been Edited');
}
}
I've tried to add File::delete to my storeImage function and delete it from my update function, it fix the problem but the old image is not removed from directory
private function storeImage($post)
{
if (request()->has('image')){
File::delete(public_path('storage/'.$post->image))
$post->update([
'image' => request()->image->store('uploads', 'public'),
]);
$image = Image::make(public_path('storage/'.$post->image))->fit(750, 300);
$image->save();
}
}
Ok since I use model binding in my controller I don't have to find the id right?
so I change my update function which is basically Akhtar munir suggested, and turn out to be something like this. The image update work, it also remove the old image when I update it. But I have found another issue, the problem is when I edit article and title it didn't change like when I update it, I hope you can take look at this is this correct?
public function update(Post $post){
$this->validateRequest();
if(request()->hasFile('image') && request('image') != ''){
$imagePath = public_path('storage/'.$post->image);
if(File::exists($imagePath)){
unlink($imagePath);
}
$image = request()->file('image')->store('uploads', 'public');
$post->update([
'title' => request()->title,
'content' => request()->content,
'image' => $image,
]);
}
}
This is what I have done in one of my method. It may help you.
public function update(Request $request, $id)
{
if (UserDocument::where('id',$id)->exists()) {
$this->validateUserDocument($request);
if ($request->hasFile('doc_file') && $request->doc_file != '') {
$doc = UserDocument::where('id',$id)->first();
// dd($doc);
$file_path = storage_path().'/app/'.$doc['doc_file'];
//You can also check existance of the file in storage.
if(Storage::exists($file_path)) {
unlink($file_path); //delete from storage
// Storage::delete($file_path); //Or you can do it as well
}
$file = $request->file('doc_file')->store('documents'); //new file path
$doc->update([
'title' => $request->title,
'doc_file' => $file //new file path updated
]);
session()->flash('success','Document updated successfully!');
return redirect()->route('userdocs');
}
session()->flash('error','Empty file can not be updated!');
return redirect()->back();
}
session()->flash('error','Record not found!');
return redirect()->back();
}
In this code, I just simply want to clearify to you that I have stored image path in database, first I have retrieved that path and with that path I have found image in my local storage, delete it first and then update it with the new one. But make sure to store image path in database in both cases ofcourse with insert and update.
So finally you can also optimize your code like this, it will do the same thing as you expect, whether image and all data or only title and content.
public function update(Post $post){
$this->validateRequest();
$data = [
'title' => request()->title,
'content' => request()->content
];
if (request()->hasFile('image') && request('image') != '') {
$imagePath = public_path('storage/'.$post->image);
if(File::exists($imagePath)){
unlink($imagePath);
}
$image = request()->file('image')->store('uploads', 'public');
$data['image'] = $image;
//$post->update($data);
}
$post->update($data);
}
Try this one
private function storeImage($post)
{
if (request()->hasFile('image')){
$image_path = "/storage/".'prev_img_name'; // prev image path
if(File::exists($image_path)) {
File::delete($image_path);
}
$post->update([
'image' => request()->image->store('uploads', 'public'),
]);
$image = Image::make(public_path('storage/'.$post->image))->fit(750, 300);
$image->save();
}
}

How to upload Image in Database in Laravel 5.7?

I'm making an app in Laravel 5.7 . I want to upload image in database through it and I want to show it from database.
I have tried different methods around the Internet as I was getting issues in
Intervention\Image\Facades\Image
I followed many advices from Internet make changes in config.app
made changes in Composer
At the end used
use Intervention\Image\Facades\Image as Image;
So I get resolved from issue "Undefined class Image"
but now I' m getting issues as "Undefined class File",
Method getClientOriginalExtension not found.
Method Upsize, make not found.
My code is
<?php
namespace App\Http\Controllers;
use File;
use Intervention\Image\Facades\Image as Image;
use App\User;
use Illuminate\Http\Request;
class UserController extends Controller
{
//
protected $user;
/**
* [__construct description]
* #param Photo $photo [description]
*/
public function __construct(
User $user )
{
$this->user = $user;
}
/**
* Display photo input and recent images
* #return view [description]
*/
public function index()
{
$users = User::all();
return view('profile', compact('users'));
}
public function uploadImage(Request $request)
{
$request->validate([
'image' => 'required',
'image.*' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048'
]);
//check if image exist
if ($request->hasFile('image')) {
$images = $request->file('image');
//setting flag for condition
$org_img = $thm_img = true;
// create new directory for uploading image if doesn't exist
if( ! File::exists('images/originals/')) {
$org_img = File::makeDirectory('images/originals/', 0777, true);
}
if ( ! File::exists('images/thumbnails/')) {
$thm_img = File::makeDirectory('images/thumbnails', 0777, true);
}
// loop through each image to save and upload
foreach($images as $key => $image) {
//create new instance of Photo class
$newPhoto = new $this->user;
//get file name of image and concatenate with 4 random integer for unique
$filename = rand(1111,9999).time().'.'.$image->getClientOriginalExtension();
//path of image for upload
$org_path = 'images/originals/' . $filename;
$thm_path = 'images/thumbnails/' . $filename;
$newPhoto->image = 'images/originals/'.$filename;
$newPhoto->thumbnail = 'images/thumbnails/'.$filename;
//don't upload file when unable to save name to database
if ( ! $newPhoto->save()) {
return false;
}
// upload image to server
if (($org_img && $thm_img) == true) {
Image::make($image)->fit(900, 500, function ($constraint) {
$constraint->upsize();
})->save($org_path);
Image::make($image)->fit(270, 160, function ($constraint) {
$constraint->upsize();
})->save($thm_path);
}
}
}
return redirect()->action('UserController#index');
}
}
Please suggest me any Image Upload code without updating repositories or suggest me how can I remove issues from this code.
The beginning of time read below link because laravel handled create directory and hash image and put directory
laravel file system
then read file name when stored on directory and holds name on table field when need image retrieve name field and call physical address on server
$upload_id = $request->file('FILENAME');
$file_name = time().$upload_id->getClientOriginalName();
$destination =
$_SERVER["DOCUMENT_ROOT"].'/adminbusinessplus/storage/uploads';
$request->file('FILENAME')->move($destination, $file_name);
$string="123456stringsawexs";
$extension = pathinfo($upload_id, PATHINFO_EXTENSION);
$path = $destination.'/'.$file_name;
$public =1;
$user_id = $request->logedin_user_id;
$hash = str_shuffle($string);
$request->user_id = $request->logedin_user_id;
$request->name = $file_name;
$request->extension = $extension;
$request->path = $path;
$request->public = $public;
$request->hash = $hash;
//$request INSERT INTO MODEL uploads
$file_id = Module::insert("uploads", $request);

Laravel 5 Validation in controller

I have 2 methods in my Controller and I need to validate it but I don't know how.
1st method which should allow all image extensions:
public function testing(Request $request) {
if($request->hasFile('img')) {
$image = Input::file('img');
$filename = time() . '.' . $image->getClientOriginalExtension();
$path = public_path('images/' . $filename);
Image::make($image->getRealPath())->resize(200, 200)->save($path);
$file = $request->file('img');
return ['url' => url('images/' . $filename)];
}
}
2nd method which should only allow 1 word and if there is space, trim it into 1 word:
public function postDB(Request $request) {
$newName = $request->input('newName');
$websites = new Website();
$websites->name = $newName;
$websites->save();
return redirect('template')->with('status', 'Website has been saved successfully!');
}
First write new Request for your data
php artisan make:request ImageRequest
Than write in ImageRequest:
public function authorize()
{
return true;
}
public function rules()
{
return [
'img' => 'file|image',
]
}
If you want to customize error messages:
public function messages()
{
return [
'img.image' => 'Some custom message ...',
];
}
Last inject request to your method (don`t forget about use App\Http\Requests):
public function testing(Requests\ImageRequest $request) {
//for retrieving validation errors use:
$imgErrors = $errors->first('img');
}
More information about Form Request Validation
Or you can use Validator facade (don`t forget about use Validator):
$validator = Validator::make(
$image, [
'img' => 'file|image',
]
);
More information about A Note On Optional Fields

NotReadableException in AbstractDecoder.php line 302: Image source not readable

I trying to follow tutorial about insert image and resize it, but i facing one problem showing image source not readable.
I am using PHP, Laravel 5 framework and mysql. When I run my code i stop on Image::make
Here is my controller code:
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Requests\FoodRequest;
use App\Http\Controllers\Controller;
use App\Photo;
use Image;
use App\Restaurant;
use Symfony\Component\HttpFoundation\File\UploadedFile;
public function addPhoto($zip, $street, Request $request)
{
$this->validate($request, [
'photo' => 'required|mimes:jpg,jpeg,png,bmp'
]);
$photo = $this->makePhoto($request->file('photo'));
Restaurant::locatedAt($zip, $street)->addPhoto($photo);
}
protected function makePhoto(UploadedFile $file)
{
return Photo::named($file->getClientOriginalName())
->move($file);
}
Here is Photo Code:
public static function named($name)
{
return (new static)->saveAs($name);
}
protected function saveAs($name)
{
$this->name = sprintf("%s-%s", time(), $name);
$this->path = sprintf("%s-%s", $this->baseDir, $this->name);
$this->thumbnail_path = sprintf("%s/tn-%s", $this->baseDir, $this->name);
return $this;
}
public function move(UploadedFile $file)
{
$file->move($this->baseDir, $this->name);
$this->makeThumbnail();
return $this;
}
protected function makeThumbnail()
{
Image::make($this->path)
->fit(200)
->save($this->thumbnail_path);
}
I did the same tutorial , you should do this:
Image::make($this->path.$this->name)->resize(128,
128)->save($this->thumbnail_path.$this->name);
instead of doing this:
Image::make($this->path)->fit(200)->save($this->thumbnail_path);
This is an example from my own code where I write the path to my pics
$destinationpath = 'img/' . $propertyid;
$frontpage = 'img/' . $propertyid. '/frontpage/' ;
$gallery = 'img/' . $propertyid. '/gallery/' ;
$thumbpath = 'img/' .$propertyid .'/thumbnails/';
move the image file to a place at which the Intervention Manipulation
code will process the image, change size etc. We will save the results
of the processing in their respective folders and then delete this image.
$image->move($destinationpath, $filename );
$dbImg = new Picture;
$dbImg->property_id = $propertyid;
$dbImg->name = $filename;
$dbImg->save();

Categories