Dan Brown

Got image uploads working

...@@ -5,4 +5,5 @@ Homestead.yaml ...@@ -5,4 +5,5 @@ Homestead.yaml
5 /public/dist 5 /public/dist
6 .idea 6 .idea
7 /public/plugins 7 /public/plugins
8 -/public/css
...\ No newline at end of file ...\ No newline at end of file
8 +/public/css
9 +/storage/images
...\ No newline at end of file ...\ No newline at end of file
......
1 +<?php
2 +
3 +namespace Oxbow\Http\Controllers;
4 +
5 +use Illuminate\Filesystem\Filesystem as File;
6 +use Illuminate\Http\Request;
7 +
8 +use Oxbow\Http\Requests;
9 +use Oxbow\Image;
10 +
11 +class ImageController extends Controller
12 +{
13 + protected $image;
14 + protected $file;
15 +
16 + /**
17 + * ImageController constructor.
18 + * @param Image $image
19 + * @param File $file
20 + */
21 + public function __construct(Image $image, File $file)
22 + {
23 + $this->image = $image;
24 + $this->file = $file;
25 + }
26 +
27 + /**
28 + * Returns an image from behind the public-facing application.
29 + * @param Request $request
30 + * @return \Illuminate\Http\Response
31 + */
32 + public function getImage(Request $request)
33 + {
34 + $cacheTime = 60*60*24;
35 + $path = storage_path() . '/' . $request->path();
36 + $modifiedTime = $this->file->lastModified($path);
37 + $eTag = md5($modifiedTime . $path);
38 + $headerLastModified = gmdate('r', $modifiedTime);
39 + $headerExpires = gmdate('r', $modifiedTime + $cacheTime);
40 +
41 + $headers = [
42 + 'Last-Modified' => $headerLastModified,
43 + 'Cache-Control' => 'must-revalidate',
44 + 'Pragma' => 'public',
45 + 'Expires' => $headerExpires,
46 + 'Etag' => $eTag
47 + ];
48 +
49 + $browserModifiedSince = $request->header('If-Modified-Since');
50 + $browserNoneMatch = $request->header('If-None-Match');
51 + if($browserModifiedSince !== null && file_exists($path) && ($browserModifiedSince == $headerLastModified || $browserNoneMatch == $eTag)) {
52 + return response()->make('', 304, $headers);
53 + }
54 +
55 + if(file_exists($path)) {
56 + return response()->make(file_get_contents($path), 200, array_merge($headers, [
57 + 'Content-Type' => $this->file->mimeType($path),
58 + 'Content-Length' => filesize($path),
59 + ]));
60 + }
61 + abort(404);
62 + }
63 +
64 + /**
65 + * Handles image uploads for use on pages.
66 + * @param Request $request
67 + * @return \Illuminate\Http\JsonResponse
68 + */
69 + public function upload(Request $request)
70 + {
71 + $imageUpload = $request->file('file');
72 + $name = $imageUpload->getClientOriginalName();
73 + $imagePath = '/images/' . Date('Y-m-M') . '/';
74 + $storagePath = storage_path(). $imagePath;
75 + $fullPath = $storagePath . $name;
76 + while(file_exists($fullPath)) {
77 + $name = substr(sha1(rand()), 0, 3) . $name;
78 + $fullPath = $storagePath . $name;
79 + }
80 + $imageUpload->move($storagePath, $name);
81 + // Create and save image object
82 + $this->image->name = $name;
83 + $this->image->url = $imagePath . $name;
84 + $this->image->save();
85 + return response()->json(['link' => $this->image->url]);
86 + }
87 +
88 +
89 +}
...@@ -29,6 +29,10 @@ Route::group(['prefix' => 'books'], function() { ...@@ -29,6 +29,10 @@ Route::group(['prefix' => 'books'], function() {
29 Route::put('/{bookSlug}/{pageSlug}', 'PageController@update'); 29 Route::put('/{bookSlug}/{pageSlug}', 'PageController@update');
30 }); 30 });
31 31
32 +Route::post('/upload/image', 'ImageController@upload');
33 +
34 +Route::get('/images/{any}', 'ImageController@getImage')->where('any', '.*');
35 +
32 Route::get('/', function () { 36 Route::get('/', function () {
33 return view('base'); 37 return view('base');
34 }); 38 });
......
1 +<?php
2 +
3 +namespace Oxbow;
4 +
5 +use Illuminate\Database\Eloquent\Model;
6 +
7 +class Image extends Model
8 +{
9 + //
10 +}
File mode changed
...@@ -6,7 +6,8 @@ ...@@ -6,7 +6,8 @@
6 "type": "project", 6 "type": "project",
7 "require": { 7 "require": {
8 "php": ">=5.5.9", 8 "php": ">=5.5.9",
9 - "laravel/framework": "5.1.*" 9 + "laravel/framework": "5.1.*",
10 + "intervention/image": "^2.3"
10 }, 11 },
11 "require-dev": { 12 "require-dev": {
12 "fzaninotto/faker": "~1.4", 13 "fzaninotto/faker": "~1.4",
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
4 "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 4 "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5 "This file is @generated automatically" 5 "This file is @generated automatically"
6 ], 6 ],
7 - "hash": "5c6026b96e6fa11a641b51a6ba976f5e", 7 + "hash": "f1c04613ce972bfab5c142cb0b588385",
8 "packages": [ 8 "packages": [
9 { 9 {
10 "name": "classpreloader/classpreloader", 10 "name": "classpreloader/classpreloader",
...@@ -217,6 +217,126 @@ ...@@ -217,6 +217,126 @@
217 "time": "2014-12-20 21:24:13" 217 "time": "2014-12-20 21:24:13"
218 }, 218 },
219 { 219 {
220 + "name": "guzzlehttp/psr7",
221 + "version": "1.1.0",
222 + "source": {
223 + "type": "git",
224 + "url": "https://github.com/guzzle/psr7.git",
225 + "reference": "af0e1758de355eb113917ad79c3c0e3604bce4bd"
226 + },
227 + "dist": {
228 + "type": "zip",
229 + "url": "https://api.github.com/repos/guzzle/psr7/zipball/af0e1758de355eb113917ad79c3c0e3604bce4bd",
230 + "reference": "af0e1758de355eb113917ad79c3c0e3604bce4bd",
231 + "shasum": ""
232 + },
233 + "require": {
234 + "php": ">=5.4.0",
235 + "psr/http-message": "~1.0"
236 + },
237 + "provide": {
238 + "psr/http-message-implementation": "1.0"
239 + },
240 + "require-dev": {
241 + "phpunit/phpunit": "~4.0"
242 + },
243 + "type": "library",
244 + "extra": {
245 + "branch-alias": {
246 + "dev-master": "1.0-dev"
247 + }
248 + },
249 + "autoload": {
250 + "psr-4": {
251 + "GuzzleHttp\\Psr7\\": "src/"
252 + },
253 + "files": [
254 + "src/functions.php"
255 + ]
256 + },
257 + "notification-url": "https://packagist.org/downloads/",
258 + "license": [
259 + "MIT"
260 + ],
261 + "authors": [
262 + {
263 + "name": "Michael Dowling",
264 + "email": "mtdowling@gmail.com",
265 + "homepage": "https://github.com/mtdowling"
266 + }
267 + ],
268 + "description": "PSR-7 message implementation",
269 + "keywords": [
270 + "http",
271 + "message",
272 + "stream",
273 + "uri"
274 + ],
275 + "time": "2015-06-24 19:55:15"
276 + },
277 + {
278 + "name": "intervention/image",
279 + "version": "2.3.1",
280 + "source": {
281 + "type": "git",
282 + "url": "https://github.com/Intervention/image.git",
283 + "reference": "156f9d6f8a186c68b92f0c50084718f02dae1b5f"
284 + },
285 + "dist": {
286 + "type": "zip",
287 + "url": "https://api.github.com/repos/Intervention/image/zipball/156f9d6f8a186c68b92f0c50084718f02dae1b5f",
288 + "reference": "156f9d6f8a186c68b92f0c50084718f02dae1b5f",
289 + "shasum": ""
290 + },
291 + "require": {
292 + "ext-fileinfo": "*",
293 + "guzzlehttp/psr7": "~1.1",
294 + "php": ">=5.4.0"
295 + },
296 + "require-dev": {
297 + "mockery/mockery": "~0.9.2",
298 + "phpunit/phpunit": "3.*"
299 + },
300 + "suggest": {
301 + "ext-gd": "to use GD library based image processing.",
302 + "ext-imagick": "to use Imagick based image processing.",
303 + "intervention/imagecache": "Caching extension for the Intervention Image library"
304 + },
305 + "type": "library",
306 + "extra": {
307 + "branch-alias": {
308 + "dev-master": "2.3-dev"
309 + }
310 + },
311 + "autoload": {
312 + "psr-4": {
313 + "Intervention\\Image\\": "src/Intervention/Image"
314 + }
315 + },
316 + "notification-url": "https://packagist.org/downloads/",
317 + "license": [
318 + "MIT"
319 + ],
320 + "authors": [
321 + {
322 + "name": "Oliver Vogel",
323 + "email": "oliver@olivervogel.net",
324 + "homepage": "http://olivervogel.net/"
325 + }
326 + ],
327 + "description": "Image handling and manipulation library with support for Laravel integration",
328 + "homepage": "http://image.intervention.io/",
329 + "keywords": [
330 + "gd",
331 + "image",
332 + "imagick",
333 + "laravel",
334 + "thumbnail",
335 + "watermark"
336 + ],
337 + "time": "2015-07-10 15:03:58"
338 + },
339 + {
220 "name": "jakub-onderka/php-console-color", 340 "name": "jakub-onderka/php-console-color",
221 "version": "0.1", 341 "version": "0.1",
222 "source": { 342 "source": {
...@@ -783,6 +903,55 @@ ...@@ -783,6 +903,55 @@
783 "time": "2015-05-02 15:40:40" 903 "time": "2015-05-02 15:40:40"
784 }, 904 },
785 { 905 {
906 + "name": "psr/http-message",
907 + "version": "1.0",
908 + "source": {
909 + "type": "git",
910 + "url": "https://github.com/php-fig/http-message.git",
911 + "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298"
912 + },
913 + "dist": {
914 + "type": "zip",
915 + "url": "https://api.github.com/repos/php-fig/http-message/zipball/85d63699f0dbedb190bbd4b0d2b9dc707ea4c298",
916 + "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298",
917 + "shasum": ""
918 + },
919 + "require": {
920 + "php": ">=5.3.0"
921 + },
922 + "type": "library",
923 + "extra": {
924 + "branch-alias": {
925 + "dev-master": "1.0.x-dev"
926 + }
927 + },
928 + "autoload": {
929 + "psr-4": {
930 + "Psr\\Http\\Message\\": "src/"
931 + }
932 + },
933 + "notification-url": "https://packagist.org/downloads/",
934 + "license": [
935 + "MIT"
936 + ],
937 + "authors": [
938 + {
939 + "name": "PHP-FIG",
940 + "homepage": "http://www.php-fig.org/"
941 + }
942 + ],
943 + "description": "Common interface for HTTP messages",
944 + "keywords": [
945 + "http",
946 + "http-message",
947 + "psr",
948 + "psr-7",
949 + "request",
950 + "response"
951 + ],
952 + "time": "2015-05-04 20:22:00"
953 + },
954 + {
786 "name": "psr/log", 955 "name": "psr/log",
787 "version": "1.0.0", 956 "version": "1.0.0",
788 "source": { 957 "source": {
......
...@@ -137,6 +137,11 @@ return [ ...@@ -137,6 +137,11 @@ return [
137 Illuminate\Validation\ValidationServiceProvider::class, 137 Illuminate\Validation\ValidationServiceProvider::class,
138 Illuminate\View\ViewServiceProvider::class, 138 Illuminate\View\ViewServiceProvider::class,
139 139
140 + /**
141 + * Third Party
142 + */
143 + Intervention\Image\ImageServiceProvider::class,
144 +
140 /* 145 /*
141 * Application Service Providers... 146 * Application Service Providers...
142 */ 147 */
...@@ -192,6 +197,12 @@ return [ ...@@ -192,6 +197,12 @@ return [
192 'Validator' => Illuminate\Support\Facades\Validator::class, 197 'Validator' => Illuminate\Support\Facades\Validator::class,
193 'View' => Illuminate\Support\Facades\View::class, 198 'View' => Illuminate\Support\Facades\View::class,
194 199
200 + /**
201 + * Third Party
202 + */
203 +
204 + 'ImageTool' => Intervention\Image\Facades\Image::class,
205 +
195 ], 206 ],
196 207
197 ]; 208 ];
......
1 +<?php
2 +
3 +use Illuminate\Database\Schema\Blueprint;
4 +use Illuminate\Database\Migrations\Migration;
5 +
6 +class CreateImagesTable extends Migration
7 +{
8 + /**
9 + * Run the migrations.
10 + *
11 + * @return void
12 + */
13 + public function up()
14 + {
15 + Schema::create('images', function (Blueprint $table) {
16 + $table->increments('id');
17 + $table->string('name');
18 + $table->string('url');
19 + $table->timestamps();
20 + });
21 + }
22 +
23 + /**
24 + * Reverse the migrations.
25 + *
26 + * @return void
27 + */
28 + public function down()
29 + {
30 + Schema::drop('images');
31 + }
32 +}
...@@ -3,13 +3,13 @@ ...@@ -3,13 +3,13 @@
3 */ 3 */
4 4
5 h1 { 5 h1 {
6 - font-size: 5.625em; 6 + font-size: 3.625em;
7 line-height: 1.22222222em; 7 line-height: 1.22222222em;
8 margin-top: 0.48888889em; 8 margin-top: 0.48888889em;
9 margin-bottom: 0.24444444em; 9 margin-bottom: 0.24444444em;
10 } 10 }
11 h2 { 11 h2 {
12 - font-size: 3.1875em; 12 + font-size: 2.8275em;
13 line-height: 1.294117647em; 13 line-height: 1.294117647em;
14 margin-top: 0.8627451em; 14 margin-top: 0.8627451em;
15 margin-bottom: 0.43137255em; 15 margin-bottom: 0.43137255em;
......
...@@ -14,7 +14,13 @@ ...@@ -14,7 +14,13 @@
14 14
15 <script> 15 <script>
16 $(function() { 16 $(function() {
17 - $('#html').editable({inlineMode: false}); 17 + $('#html').editable({
18 + inlineMode: false,
19 + imageUploadURL: '/upload/image',
20 + imageUploadParams: {
21 + '_token': '{{ csrf_token() }}'
22 + }
23 + });
18 }); 24 });
19 </script> 25 </script>
20 @stop 26 @stop
...\ No newline at end of file ...\ No newline at end of file
......