Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel: Upload form data with images in a foreach loop using Intervention

Tags:

php

laravel

I'm using Laravel 5.1 and would like to have a form with a few rows of text fields with their corresponding image uploads.

Form:

<div id="row">
    <input name="description[]" type="text">
    <input name="image[]" type="file">
</div>
<div id="row">
    <input name="description[]" type="text">
    <input name="image[]" type="file">
</div>

Controller:

foreach($request->description as $key => $val){

if($val != null){
    $data = new Finding;
    $data->description = $val; //save description for each loop

    $file = array('image' => Input::file('image'));

    if (Input::file('image')->isValid()) {

        $destinationPath = 'uploads';
        $extension = Input::file('image')->getClientOriginalExtension();
        $fileName = rand(1000,1000).'.'.$extension;
        Input::file('image')->move($destinationPath, $fileName);
        $path = Input::file('image')->getRealPath();

        $data->image_location = $fileName[$key]; //save filename location to db
        $data->save();

        flash('success', 'Uploaded Successful');
        return Redirect::to('/upload');
     } else {
        flash('error', 'Uploaded File Is Not Valid');
        return Redirect::to('/upload');
    }
}

My question is, how do I use intervention with the $key value to save a new row in the table with the associated text description with the image upload and still use all the intervention classes? Is my code close?

I can easily do all this with just one form input with one image upload but my goal is to have a page with multiple rows with inputs. Thanks!

like image 502
Chad Priddle Avatar asked Mar 15 '16 15:03

Chad Priddle


1 Answers

I'm unsure of how you're managing the multiple fields, whether it's set in stone or can dynamically change. I have previously done dynamic approaches with javascript and kept track of how many dynamic fields I required with a hidden text field as a count.

Using this approach your html might look something like this:

<input name="imageAndDescriptionCount" type="hidden" value="2">
<div id="row">
    <input name="description[]" type="text">
    <input name="image[]" type="file">
</div>
<div id="row">
    <input name="description[]" type="text">
    <input name="image[]" type="file">
</div>

So here we have two image and description fields each and the counter is set at 2.

If we were to submit the form and checkout the request via dd() it would look something like this:

"imageAndDescriptionCount" => "2"
"description" => array:2 [▼
    0 => "description"
    1 => "description"
]
    "image" => array:2 [▼
    0 => UploadedFile {#154 ▶}
    1 => UploadedFile {#155 ▶}
]

This then sets you up nicely for a for loop in your controller:

$count = $request->get('imageAndDescriptionCount');
$description = $request->get('description'); // assign array of descriptions
$image = $request->file('image'); // assign array of images

// set upload path using https://laravel.com/docs/5.1/helpers#method-storage-path 
// make sure 'storage/uploads' exists first
$destinationPath = storage_path . '/uploads'; 

for($i = 0; $i < $count; $i++) {

    $data = new Finding;
    $data->description = [$i];

    $file = $image[$i];

    if ($file->isValid()) {
        $extension = $file->getClientOriginalExtension(); // file extension
        $fileName = uniqid(). '.' .$extension; // file name with extension
        $file->move($destinationPath, $fileName); // move file to our uploads path

        $data->image_location = $fileName;
        // or you could say $destinationPath . '/' . $fileName
        $data->save();
    } else {
        // handle error here
    }

}

flash('success', 'Uploads Successful');
return Redirect::to('/upload');

Please note there is no use of the intervention library in your code to my knowledge and I've just wrote the code to perform the upload. I hope this helps you!

Edit

If you really want to use a foreach loop and you know you'll have a description for each image you can do it like this (but I personally think having a counter is a better approach)

$descriptions = $request->get('description'); // assign array of descriptions
$images = $request->file('image'); // assign array of images

// loop through the descriptions array
foreach($descriptions as $key => $val) {

    // You can access the description like this
    $val
    // or this
    $descriptions[$key]

    // so naturally you can access the image like this:
    $images[$key]

}

You could also instead check the count of the descriptions/images and use that as a counter to loop through:

$descriptions = $request->get('description');
$images = $request->file('image'); // assign array of images

$descCount = count($descriptions);
$imgCount = count($images);

If however you may have a different layout, i.e. you don't have 1 description for 1 image then please clarify as you'd need to take a different approach.

like image 106
haakym Avatar answered Sep 28 '22 08:09

haakym