0

I'm building a small asset management system in Laravel 5.2

A user can upload images, video etc to the app and the asset meta data gets stored in the assets table. While that's happening, the asset is renamed to match the asset id (I'm storing the original filename too), I'm storing the mime type and uploading the file to S3.

Where I've come unstuck is storing the S3 url in database.

This is my method

public function store(AssetRequest $request)
    {

        // Initialise new asset and set the name
        // from the form
        $asset = new Asset(array(
            'name' => $request->get('name')
        ));

        $asset->user_id = Auth::user()->id;

        // save the asset to the db
        $asset->save();
        // set the file var = form input
        $file = $request->file('asset_path');
        $extension = $file->getClientOriginalExtension();
        // modify the asset name
        $assetFile = $asset->id . '.' . $request->file('asset_path')->getClientOriginalExtension();
        // push the new asset to s3
        Storage::disk('s3')->put('uploads/' . $assetFile, file_get_contents($file));
        $asset->mime = $file->getClientMimeType();
        $s3Url = Storage::url($file);
        $asset->s3_url = $s3Url;
        $asset->original_filename = $file->getClientOriginalName();
        $asset->filename = $assetFile;
        $asset->file_extension = $extension;
        // return ok
        $asset->save();
        return \Redirect::route('asset.create')->with('message', 'Asset added!');
    }

The lines relating to my attempt at storing the S3 url

$s3Url = Storage::url($file); $asset->s3_url = $s3Url; Only seems to store a temporary path /storage//tmp/php8su2r0 rather than an actual S3 url. I'd like to avoid having to set the bucket manually, rather hoping I can use what is configured in config/filesystem.php

Any ideas?

Steven Grant
  • 1,236
  • 3
  • 15
  • 32

2 Answers2

1

you can get everything from the config using the config(key) function helper so to get the s3 public url of file, do this:

function publicUrl($filename){
        return "http://".config('filesystems.disks.s3.bucket').".s3-website.".config('filesystems.disks.s3.region').".amazonaws.com/".$filename;
    }

or you can use the underlying S3Client:(taken from here)

$filesystem->getAdapter()->getClient()->getObjectUrl($bucket, $key);
Community
  • 1
  • 1
Amir Bar
  • 3,007
  • 2
  • 29
  • 47
0

What your are trying to achieve, I have been doing that in many projects.

All you need to do is create image_url column in database. And pass the s3 bucket link + the name of the file + the extension.

You should know the bit that is constant for me like : https://s3-eu-west-1.amazonaws.com/backnine8/fitness/events/ then I have the id and the extension. in your case it could be name and extension.

if(Input::get('file')) {

        $extension = pathinfo(Input::get('filename'), PATHINFO_EXTENSION);
        $file = file_get_contents(Input::get('file'));

        $s3 = AWS::get('s3');

        $s3->putObject(array(
            'ACL'        => 'public-read',
            'Bucket'     => 'backnine8',
            'Key'        => '/fitness/events/'.$event->id.'.'.$extension,
            'Body' => $file,
        ));

        $event->image_url = 'https://s3-eu-west-1.amazonaws.com/backnine8/fitness/events/'.$event->id.'.'.$extension;

        $event->save();

        }
Murlidhar Fichadia
  • 2,589
  • 6
  • 43
  • 93
  • Yeah I already have the url column in the database. It would be easy enough for me to do `$event->image_url = 'https://s3-eu-west-1.amazonaws.com/backnine8/fitness/events/'.$event->id.'.'.$extension;` but you've effectively hardcoded the bucket twice. I'd rather not have any of that hard coded – Steven Grant May 05 '16 at 17:41
  • @StevenGrant just use what I gave you the put the bucket in the config and get its name from the config so the only place to change if you need to switch bucket name is in the config – Amir Bar May 05 '16 at 20:01