Skip to content

Instantly share code, notes, and snippets.

@jpadilla
Last active November 28, 2015 15:09
Show Gist options
  • Save jpadilla/8e41adc19b7f3bda4d7a to your computer and use it in GitHub Desktop.
Save jpadilla/8e41adc19b7f3bda4d7a to your computer and use it in GitHub Desktop.
$ composer create-project laravel/laravel --prefer-dist filepreviews-laravel-example
$ composer require league/flysystem-aws-s3-v3
's3' => [
    'driver' => 's3',
    'key'    => env('S3_KEY'),
    'secret' => env('S3_SECRET'),
    'region' => env('S3_REGION'),
    'bucket' => env('S3_BUCKET'),
],
S3_KEY=YOUR_AWS_S3_ACCESS_KEY
S3_SECRET=YOUR_AWS_S3_SECRET_KEY
S3_REGION=us-east-1
S3_BUCKET=YOUR_AWS_S3_BUCKET
$ php artisan make:model Document --migration
public function up()
{
    Schema::create('documents', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->string('file');
        $table->string('preview_url')->nullable();
        $table->json('preview')->nullable();
        $table->timestamps();
    });
}
$ php artisan migrate
$ php artisan make:controller DocumentController
Route::resource('documents', 'DocumentController');
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Document;
use App\Http\Requests;
use App\Http\Controllers\Controller;

class DocumentController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $documents = Document::all();

        return view('documents.index', compact('documents'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        return view('documents.create');
    }
}
<html>
<head></head>
<body>
  <h1>Documents</h1>
  <p><a href="{{ route('documents.create') }}">Create Document</a></p>
  @foreach ($documents as $document)
    <ul id="document-{{ $document->id }}">
      <li>ID: {{ $document->id }}</li>
      <li>Name: <a href="{{ $document->url }}">{{ $document->name }}</a></li>
      <li class="preview-url">
        @if ($document->preview_url)
            <a href="{{ $document->preview_url }}">Preview</a>
        @else
          No Preview
        @endif
      </li>
    </ul>
  @endforeach
</body>
</html>
<html>
<head></head>
<body>
  <h1>Create Document</h1>
  @if (count($errors) > 0)
    <div>
      <ul>
        @foreach ($errors->all() as $error)
          <li>{{ $error }}</li>
        @endforeach
      </ul>
    </div>
  @endif

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

    <p>
      <label for="file">File</label>
      <input type="file" name="file">
    </p>

    <input type="submit">
  </form>
</body>
</html>
<?php

namespace App\Http\Controllers;

use Storage;
use Illuminate\Http\Request;

use App\Document;
use App\Http\Requests;
use App\Http\Controllers\Controller;

class DocumentController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $documents = Document::all();

        return view('documents.index', compact('documents'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        return view('documents.create');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $this->validate($request, [
            'file' => 'required'
        ]);

        $file = $request->file('file');

        if ($file->isValid()) {
            $name = $file->getClientOriginalName();
            $key = 'documents/' . $name;
            Storage::disk('s3')->put($key, file_get_contents($file));

            $document = new Document;

            $document->name = $name;
            $document->file = $key;
            $document->save();
        }

        return redirect('documents');
    }
}
<?php

namespace App;

use Storage;
use Config;
use Illuminate\Database\Eloquent\Model;

class Document extends Model
{
    protected $appends = ['url'];

    public function getUrlAttribute()
    {
        return $this->getFileUrl($this->attributes['file']);
    }

    private function getFileUrl($key) {
        $s3 = Storage::disk('s3');
        $client = $s3->getDriver()->getAdapter()->getClient();
        $bucket = Config::get('filesystems.disks.s3.bucket');

        $command = $client->getCommand('GetObject', [
            'Bucket' => $bucket,
            'Key' => $key
        ]);

        $request = $client->createPresignedRequest($command, '+20 minutes');

        return (string) $request->getUri();
    }
}
$ composer require filepreviews/filepreviews-laravel
    'providers' => [
        // ...
        
        FilePreviews\Laravel\FilePreviewsServiceProvider::class,
    ],
    
    'aliases' => [
        // ...
        
        'FilePreviews' => FilePreviews\Laravel\FilePreviewsFacade::class,
    ]
FILEPREVIEWS_API_KEY=YOUR_FILEPREVIEWS_SERVER_API_KEY
FILEPREVIEWS_API_SECRET=YOUR_FILEPREVIEWS_SERVER_SECRET_KEY
    public function requestPreview()
    {
        $fp = app('FilePreviews');

        $options = [
            'metadata' => ['checksum', 'ocr'],
            'data' => [
                'document_id' => $this->attributes['id']
            ]
        ];

        $url = $this->getFileUrl($this->attributes['file']);

        return $fp->generate($url, $options);
    }
    public function store(Request $request)
    {
        $this->validate($request, [
            'file' => 'required'
        ]);

        $file = $request->file('file');

        if ($file->isValid()) {
            $name = $file->getClientOriginalName();
            $key = 'documents/' . $name;
            Storage::disk('s3')->put($key, file_get_contents($file));

            $document = new Document;

            $document->name = $name;
            $document->file = $key;
            $document->save();

            $document->requestPreview();
        }

        return redirect('documents');
    }
Route::post('filepreviews/webhook', '\FilePreviews\Laravel\WebhookController@handleWebhook');
<?php

namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;

class VerifyCsrfToken extends BaseVerifier
{
    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array
     */
    protected $except = [
        'filepreviews/webhook'
    ];
}
<?php

namespace App\Listeners;

use Event;

use App\Document;

class FilePreviewsSuccess
{
    /**
     * Handle the event.
     *
     * @param  array  $results
     * @return void
     */
    public function handle($results)
    {
        $document_id = $results['user_data']['document_id'];
        $document = Document::find($document_id);
        $document->preview_url = $results['preview']['url'];
        $document->preview = json_encode($results);
        $document->save();
    }
}
    protected $listen = [
            'filepreviews.success' => [
                'App\Listeners\FilePreviewsSuccess'
        ]
    ];
$ composer require pusher/pusher-php-server
PUSHER_KEY=YOUR_PUSHER_APP_KEY
PUSHER_SECRET=YOUR_PUSHER_APP_SECRET
PUSHER_APP_ID=YOUR_PUSHER_APP_ID
<?php

namespace App\Events;

use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;

use App\Events\Event;
use App\Document;

class FilePreviewsGenerated extends Event implements ShouldBroadcast
{
    use SerializesModels;

    public $document;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct(Document $document)
    {
        $this->document = $document;
    }

    /**
     * Get the channels the event should be broadcast on.
     *
     * @return array
     */
    public function broadcastOn()
    {
        return ['filepreviews'];
    }

    /**
     * Get the broadcast event name.
     *
     * @return string
     */
    public function broadcastAs()
    {
        return 'filepreviews.generated';
    }
}
<?php

namespace App\Listeners;

use Event;

use App\Document;
use App\Events\FilePreviewsGenerated;

class FilePreviewsSuccess
{
    /**
     * Handle the event.
     *
     * @param  array  $results
     * @return void
     */
    public function handle($results)
    {
        $document_id = $results['user_data']['document_id'];
        $document = Document::find($document_id);
        $document->preview_url = $results['preview']['url'];
        $document->preview = json_encode($results);
        $document->save();

        Event::fire(new FilePreviewsGenerated($document));
    }
}
<html>
<head></head>
<body>
  <h1>Documents</h1>
  <p><a href="{{ route('documents.create') }}">Create Document</a></p>
  @foreach ($documents as $document)
    <ul id="document-{{ $document->id }}">
      <li>ID: {{ $document->id }}</li>
      <li>Name: <a href="{{ $document->url }}">{{ $document->name }}</a></li>
      <li class="preview-url">
        @if ($document->preview_url)
            <a href="{{ $document->preview_url }}">Preview</a>
        @else
          No Preview
        @endif
      </li>
    </ul>
  @endforeach

  <script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
  <script src="https://js.pusher.com/3.0/pusher.min.js"></script>
  <script>
    $(function() {
      // Enable pusher logging - don't include this in production
      Pusher.log = function(message) {
        if (window.console && window.console.log) {
          window.console.log(message);
        }
      };

      var pusherKey = '{{ config('broadcasting.connections.pusher.key') }}',
          pusher = new Pusher(pusherKey, { encrypted: true }),
          channel = pusher.subscribe('filepreviews');

      channel.bind('filepreviews.generated', function(data) {
        var $doc = $('#document-' + data.document.id),
            $previewUrl = $doc.find('.preview-url');

        $previewUrl.html('<a href="' + data.document.preview_url + '">Preview</a>');
      });
    });
  </script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment