cfkane
cfkane

Reputation: 733

Can't upload images to a public directory in laravel

I'm trying to upload images into a Laravel app that will then need to be publicly displayed. However, I seem to only be able to upload to a folder within the application root. Any attempt to upload to the public directory throws the following error:

protected function getTargetFile($directory, $name = null)
{
    if (!is_dir($directory)) {
        if (false === @mkdir($directory, 0777, true)) {
            throw new FileException(sprintf('Unable to create the "%s" directory', $directory));

I'm assuming this means that Laravel is going to prevent me from uploading to any file that is publicly accessible. I actually rather like this, however, how can I link to images that are outside of the public directory I've tried to ../ my way out of the public folder, but appropriately, that didn't work.

Alternately, anything that will let me uploaded directly to the public folder would be great too.

If it helps, here is my controller method that puts the file in public folder:

$thumbnail_file = Input::file('thumbnail'); 
$destinationPath = '/uploads/'. str_random(8);
$thumbnail_filename = $thumbnail_file->getClientOriginalName();
$uploadSuccess = Input::file('thumbnail_url')->move($destinationPath, $thumbnail_filename);

Upvotes: 5

Views: 16862

Answers (5)

Zainul Abedin
Zainul Abedin

Reputation: 1

You need to give permission the laravel folder where you want to store images. The commend is:

sudo chown www-data:www-data /var/www/html/project-name/path/to/folder.

Upvotes: -1

Cherma Ramalho
Cherma Ramalho

Reputation: 395

In the ImageProductController.php (Controller) file insert the following code:

public function store(Request $request, $id)
{
if ($request->hasFile('image')){
  $rules = [
    'image'  => 'required|image|mimes:jpeg,png,jpg,gif,svg'
  ];

  $this->validate($request, $rules);

// Save file in directory
  $file = $request->file('image');
  $path = public_path() . '/images';
  $fileName = md5(rand(0,9999)).'.'.$file->getClientOriginalExtension();
  $file->move($path, $fileName);

  $imageProduct = new ImageProduct();
  $imageProduct->image = $fileName;
}

In the file create.blade.php (View) insert the following code:

<form enctype="multipart/form-data" method="post" action=" " >
 {{ csrf_field() }}

      <label for="image" class="btn btn-primary">Inserir Imagem</label> 

      <input type="file" name="image" id="image"  accept="image/*" 
        class="form-control" value="{{ old('image') }}>   
</form>

In the ImageProduct.php file (Model) insert the following code:

public function getUrlAttribute()
{
    if(substr($this->image, 0, 4) === "http"){
        return $this->image;
    }

    return '/images/'.$this->image;
}

Good luck!

Upvotes: 0

Steve Bauman
Steve Bauman

Reputation: 8678

Your destination path should be:

 $destinationPath = public_path(sprintf("\\uploads\\%s\\", str_random(8)));

Upvotes: 4

Tongi
Tongi

Reputation: 51

Try using this one in your controller after creating a folder called uploads in your public and another folder called photos in uploads.

 $data = Input::all();
    $rules = array(           
        'photo' => 'between:1,5000|upload:image/gif,image/jpg,image/png,image/jpeg',            
    );
    $messages = array(
        'upload' => 'The :attribute must be one of the following types .jpg .gif .png .jpeg',
        'between' => 'The :attribute file size must be 1kb - 5mb'
    );

    $validator = Validator::make($data, $rules, $messages);
    if($validator->passes())
    {
        $uploads = public_path() . '/uploads/photos';
        $photo = Input::file('photo');
        $photodestinationPath = $uploads;

        $photoname = null;

        if($photo != null)
        {
            $photoname = $photo->getClientOriginalName();
            Input::file('photo')->move($photodestinationPath, $photoname);
        }

        $thumbnail = new Model_name();          
        $thumbnail ->column_name_in_table = $photoname;

and then put this in your routes

 Validator::extend('upload', function($attribute,$value, $parameters){
$count = 0;
for($i = 0; $i < count($parameters); $i++)
{
    if($value->getMimeType() == $parameters[$i])
    {
        $count++;
    }
}

if($count !=0)
{
    return true;
}
return false;});

Upvotes: 1

vuhung3990
vuhung3990

Reputation: 6819

Route::post('upload', function(){
   $avarta = Input::file('avatar');
   if(strpos($avarta->getClientMimeType(),'image') !== FALSE){

      $upload_folder = '/assets/uploads/';

      $file_name = str_random(). '.' . $avarta->getClientOriginalExtension();

      $avarta->move(public_path() . $upload_folder, $file_name);

      echo URL::asset($upload_folder . $file_name);  // get upload file url

      return Response::make('Success', 200);
   }else{
     return Response::make('Avatar must be image', 400); // bad request
  }});

will upload to /public/assets/uploads folder, maybe help you

Upvotes: 8

Related Questions