From 1ec9466c2935f9f19eb6c76936f42340475eae12 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Mon, 13 Jul 2015 21:52:56 +0100 Subject: [PATCH] Got image uploads working --- .gitignore | 3 +- app/Http/Controllers/ImageController.php | 89 +++++++++ app/Http/routes.php | 4 + app/Image.php | 10 + bootstrap/cache/.gitignore | 0 composer.json | 3 +- composer.lock | 171 +++++++++++++++++- config/app.php | 11 ++ .../2015_07_13_172121_create_images_table.php | 32 ++++ resources/assets/sass/_text.scss | 4 +- resources/views/pages/edit.blade.php | 8 +- 11 files changed, 329 insertions(+), 6 deletions(-) create mode 100644 app/Http/Controllers/ImageController.php create mode 100644 app/Image.php mode change 100644 => 100755 bootstrap/cache/.gitignore create mode 100644 database/migrations/2015_07_13_172121_create_images_table.php diff --git a/.gitignore b/.gitignore index e5011ccbc..9a50d0172 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ Homestead.yaml /public/dist .idea /public/plugins -/public/css \ No newline at end of file +/public/css +/storage/images \ No newline at end of file diff --git a/app/Http/Controllers/ImageController.php b/app/Http/Controllers/ImageController.php new file mode 100644 index 000000000..941f2ad39 --- /dev/null +++ b/app/Http/Controllers/ImageController.php @@ -0,0 +1,89 @@ +image = $image; + $this->file = $file; + } + + /** + * Returns an image from behind the public-facing application. + * @param Request $request + * @return \Illuminate\Http\Response + */ + public function getImage(Request $request) + { + $cacheTime = 60*60*24; + $path = storage_path() . '/' . $request->path(); + $modifiedTime = $this->file->lastModified($path); + $eTag = md5($modifiedTime . $path); + $headerLastModified = gmdate('r', $modifiedTime); + $headerExpires = gmdate('r', $modifiedTime + $cacheTime); + + $headers = [ + 'Last-Modified' => $headerLastModified, + 'Cache-Control' => 'must-revalidate', + 'Pragma' => 'public', + 'Expires' => $headerExpires, + 'Etag' => $eTag + ]; + + $browserModifiedSince = $request->header('If-Modified-Since'); + $browserNoneMatch = $request->header('If-None-Match'); + if($browserModifiedSince !== null && file_exists($path) && ($browserModifiedSince == $headerLastModified || $browserNoneMatch == $eTag)) { + return response()->make('', 304, $headers); + } + + if(file_exists($path)) { + return response()->make(file_get_contents($path), 200, array_merge($headers, [ + 'Content-Type' => $this->file->mimeType($path), + 'Content-Length' => filesize($path), + ])); + } + abort(404); + } + + /** + * Handles image uploads for use on pages. + * @param Request $request + * @return \Illuminate\Http\JsonResponse + */ + public function upload(Request $request) + { + $imageUpload = $request->file('file'); + $name = $imageUpload->getClientOriginalName(); + $imagePath = '/images/' . Date('Y-m-M') . '/'; + $storagePath = storage_path(). $imagePath; + $fullPath = $storagePath . $name; + while(file_exists($fullPath)) { + $name = substr(sha1(rand()), 0, 3) . $name; + $fullPath = $storagePath . $name; + } + $imageUpload->move($storagePath, $name); + // Create and save image object + $this->image->name = $name; + $this->image->url = $imagePath . $name; + $this->image->save(); + return response()->json(['link' => $this->image->url]); + } + + +} diff --git a/app/Http/routes.php b/app/Http/routes.php index ec9cb7c6f..8840a62d5 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -29,6 +29,10 @@ Route::group(['prefix' => 'books'], function() { Route::put('/{bookSlug}/{pageSlug}', 'PageController@update'); }); +Route::post('/upload/image', 'ImageController@upload'); + +Route::get('/images/{any}', 'ImageController@getImage')->where('any', '.*'); + Route::get('/', function () { return view('base'); }); diff --git a/app/Image.php b/app/Image.php new file mode 100644 index 000000000..4600e5b1b --- /dev/null +++ b/app/Image.php @@ -0,0 +1,10 @@ +=5.5.9", - "laravel/framework": "5.1.*" + "laravel/framework": "5.1.*", + "intervention/image": "^2.3" }, "require-dev": { "fzaninotto/faker": "~1.4", diff --git a/composer.lock b/composer.lock index 4d9f5869c..79eb195ed 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "5c6026b96e6fa11a641b51a6ba976f5e", + "hash": "f1c04613ce972bfab5c142cb0b588385", "packages": [ { "name": "classpreloader/classpreloader", @@ -216,6 +216,126 @@ ], "time": "2014-12-20 21:24:13" }, + { + "name": "guzzlehttp/psr7", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "af0e1758de355eb113917ad79c3c0e3604bce4bd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/af0e1758de355eb113917ad79c3c0e3604bce4bd", + "reference": "af0e1758de355eb113917ad79c3c0e3604bce4bd", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "PSR-7 message implementation", + "keywords": [ + "http", + "message", + "stream", + "uri" + ], + "time": "2015-06-24 19:55:15" + }, + { + "name": "intervention/image", + "version": "2.3.1", + "source": { + "type": "git", + "url": "https://github.com/Intervention/image.git", + "reference": "156f9d6f8a186c68b92f0c50084718f02dae1b5f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Intervention/image/zipball/156f9d6f8a186c68b92f0c50084718f02dae1b5f", + "reference": "156f9d6f8a186c68b92f0c50084718f02dae1b5f", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "guzzlehttp/psr7": "~1.1", + "php": ">=5.4.0" + }, + "require-dev": { + "mockery/mockery": "~0.9.2", + "phpunit/phpunit": "3.*" + }, + "suggest": { + "ext-gd": "to use GD library based image processing.", + "ext-imagick": "to use Imagick based image processing.", + "intervention/imagecache": "Caching extension for the Intervention Image library" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3-dev" + } + }, + "autoload": { + "psr-4": { + "Intervention\\Image\\": "src/Intervention/Image" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Oliver Vogel", + "email": "oliver@olivervogel.net", + "homepage": "http://olivervogel.net/" + } + ], + "description": "Image handling and manipulation library with support for Laravel integration", + "homepage": "http://image.intervention.io/", + "keywords": [ + "gd", + "image", + "imagick", + "laravel", + "thumbnail", + "watermark" + ], + "time": "2015-07-10 15:03:58" + }, { "name": "jakub-onderka/php-console-color", "version": "0.1", @@ -782,6 +902,55 @@ ], "time": "2015-05-02 15:40:40" }, + { + "name": "psr/http-message", + "version": "1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", + "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2015-05-04 20:22:00" + }, { "name": "psr/log", "version": "1.0.0", diff --git a/config/app.php b/config/app.php index a7457bd1f..690d5fb96 100644 --- a/config/app.php +++ b/config/app.php @@ -137,6 +137,11 @@ return [ Illuminate\Validation\ValidationServiceProvider::class, Illuminate\View\ViewServiceProvider::class, + /** + * Third Party + */ + Intervention\Image\ImageServiceProvider::class, + /* * Application Service Providers... */ @@ -192,6 +197,12 @@ return [ 'Validator' => Illuminate\Support\Facades\Validator::class, 'View' => Illuminate\Support\Facades\View::class, + /** + * Third Party + */ + + 'ImageTool' => Intervention\Image\Facades\Image::class, + ], ]; diff --git a/database/migrations/2015_07_13_172121_create_images_table.php b/database/migrations/2015_07_13_172121_create_images_table.php new file mode 100644 index 000000000..ecd074a9b --- /dev/null +++ b/database/migrations/2015_07_13_172121_create_images_table.php @@ -0,0 +1,32 @@ +increments('id'); + $table->string('name'); + $table->string('url'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('images'); + } +} diff --git a/resources/assets/sass/_text.scss b/resources/assets/sass/_text.scss index 72f4f7b8e..4cd440a11 100644 --- a/resources/assets/sass/_text.scss +++ b/resources/assets/sass/_text.scss @@ -3,13 +3,13 @@ */ h1 { - font-size: 5.625em; + font-size: 3.625em; line-height: 1.22222222em; margin-top: 0.48888889em; margin-bottom: 0.24444444em; } h2 { - font-size: 3.1875em; + font-size: 2.8275em; line-height: 1.294117647em; margin-top: 0.8627451em; margin-bottom: 0.43137255em; diff --git a/resources/views/pages/edit.blade.php b/resources/views/pages/edit.blade.php index 021b43aae..832d3f8ad 100644 --- a/resources/views/pages/edit.blade.php +++ b/resources/views/pages/edit.blade.php @@ -14,7 +14,13 @@ @stop \ No newline at end of file