From a12af09102e2324fe161214c4da33a21ccec8a70 Mon Sep 17 00:00:00 2001 From: Romulus21 Date: Sat, 18 Apr 2020 15:58:48 +0200 Subject: [PATCH] finish memos cover --- .idea/php.xml | 1 + .idea/portal.iml | 1 + app/Http/Controllers/ImageController.php | 57 ++++++ app/Http/Controllers/UserController.php | 5 + app/Http/Resources/Image.php | 33 +++ app/Http/Resources/Memo.php | 7 + app/Http/Resources/User.php | 3 + app/Models/Image.php | 15 ++ app/Models/Memo.php | 17 ++ app/Models/User.php | 22 ++ composer.json | 1 + composer.lock | 72 ++++++- .../2020_04_15_195531_create_images_table.php | 36 ++++ package.json | 1 + resources/js/components/UploadableImage.vue | 89 ++++++++ resources/js/router.js | 2 +- resources/js/views/Memo/MemoEdit.vue | 40 +++- resources/js/views/Memo/MemoIndex.vue | 7 +- resources/js/views/Memo/MemoShow.vue | 44 ++-- .../User/{UserProfil.vue => UserProfile.vue} | 0 resources/sass/app.scss | 1 + resources/sass/components/images.scss | 10 + resources/sass/pages/memos.scss | 12 ++ resources/sass/setup/_containers.scss | 2 +- resources/sass/setup/_positions.scss | 20 ++ routes/api.php | 4 + tests/Feature/ImagesTest.php | 191 ++++++++++++++++++ 27 files changed, 661 insertions(+), 32 deletions(-) create mode 100644 app/Http/Controllers/ImageController.php create mode 100644 app/Http/Resources/Image.php create mode 100644 app/Models/Image.php create mode 100644 database/migrations/2020_04_15_195531_create_images_table.php create mode 100644 resources/js/components/UploadableImage.vue rename resources/js/views/User/{UserProfil.vue => UserProfile.vue} (100%) create mode 100644 resources/sass/components/images.scss create mode 100644 tests/Feature/ImagesTest.php diff --git a/.idea/php.xml b/.idea/php.xml index 7a32347..a0f3284 100644 --- a/.idea/php.xml +++ b/.idea/php.xml @@ -111,6 +111,7 @@ + diff --git a/.idea/portal.iml b/.idea/portal.iml index 4f85efb..e4deccd 100644 --- a/.idea/portal.iml +++ b/.idea/portal.iml @@ -26,6 +26,7 @@ + diff --git a/app/Http/Controllers/ImageController.php b/app/Http/Controllers/ImageController.php new file mode 100644 index 0000000..a5e699b --- /dev/null +++ b/app/Http/Controllers/ImageController.php @@ -0,0 +1,57 @@ +storeImage(); + + $newImage = auth()->user()->images()->create([ + 'path' => $data['path'], + 'width' => $data['width'], + 'height' => $data['height'], + 'location' => $data['location'], + ]); + + return new ImageResource($newImage); + } + + public function memos(Memo $memo) + { + $data = $this->storeImage(); + + $newImage = $memo->images()->create([ + 'path' => $data['path'], + 'width' => $data['width'], + 'height' => $data['height'], + 'location' => $data['location'], + ]); + + return new ImageResource($newImage); + } + + private function storeImage() { + $data = request()->validate([ + 'image' => 'required', + 'width' => 'required', + 'height' => 'required', + 'location' => 'required', + ]); + + $data['path'] = $data['image']->store('images', 'public'); + + Image::make($data['image']) + ->fit($data['width'], $data['height']) + ->save(storage_path('app/public/images/'.$data['image']->hashName())); + + return $data; + } +} diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 6c707a3..2d35bc8 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -30,6 +30,11 @@ class UserController extends Controller ->setStatusCode(Response::HTTP_CREATED); } + public function show(User $user) + { + return New UserResource($user); + } + private function validateData() { return request()->validate([ diff --git a/app/Http/Resources/Image.php b/app/Http/Resources/Image.php new file mode 100644 index 0000000..731e801 --- /dev/null +++ b/app/Http/Resources/Image.php @@ -0,0 +1,33 @@ + [ + 'type' => 'images', + 'image_id' => $this->id, + 'attributes' => [ + 'path' => url('storage/'.$this->path), + 'width' => $this->width, + 'height' => $this->height, + 'location' => $this->location, + ] + ], + 'links' => [ + 'self' => url('/images/'.$this->id), + ] + ]; + } +} diff --git a/app/Http/Resources/Memo.php b/app/Http/Resources/Memo.php index d84761f..b95f4d8 100644 --- a/app/Http/Resources/Memo.php +++ b/app/Http/Resources/Memo.php @@ -2,6 +2,8 @@ namespace App\Http\Resources; +use App\Http\Resources\Image as ImageResource; +use App\Http\Resources\User as UserResource; use Illuminate\Http\Resources\Json\JsonResource; class Memo extends JsonResource @@ -16,10 +18,15 @@ class Memo extends JsonResource { return [ 'data' => [ + 'type' => 'memos', 'memo_id' => $this->id, 'name' => $this->name, 'memo' => $this->memo, 'last_updated' => $this->updated_at->diffForHumans(), + 'attributes' => [ + 'posted_by' => new UserResource($this->user), + 'cover_image' => new ImageResource($this->coverImage), + ] //'tags' => TagResource::collection($this->tags), ], 'links' => [ diff --git a/app/Http/Resources/User.php b/app/Http/Resources/User.php index 0383f5d..9512704 100644 --- a/app/Http/Resources/User.php +++ b/app/Http/Resources/User.php @@ -2,6 +2,7 @@ namespace App\Http\Resources; +use App\Http\Resources\Image as ImageResource; use Illuminate\Http\Resources\Json\JsonResource; class User extends JsonResource @@ -21,6 +22,8 @@ class User extends JsonResource 'attributes' => [ 'name' => $this->name, 'email' => $this->email, + 'profile_image' => new ImageResource($this->profileImage), + 'cover_image' => new ImageResource($this->coverImage), 'last_login' => optional($this->login_at)->diffForHumans(), 'is_admin' => $this->isAdmin(), ], diff --git a/app/Models/Image.php b/app/Models/Image.php new file mode 100644 index 0000000..59fdb61 --- /dev/null +++ b/app/Models/Image.php @@ -0,0 +1,15 @@ +morphTo(); + } +} diff --git a/app/Models/Memo.php b/app/Models/Memo.php index 6a7c591..7255120 100644 --- a/app/Models/Memo.php +++ b/app/Models/Memo.php @@ -4,6 +4,8 @@ namespace App\Models; use App\User; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\MorphMany; +use Illuminate\Database\Eloquent\Relations\MorphOne; use Illuminate\Database\Eloquent\Relations\MorphToMany; class Memo extends Model @@ -24,4 +26,19 @@ class Memo extends Model // { // return $this->morphToMany(Tag::class, 'taggable')->withTimestamps()->withPivot('user_id'); // } + + public function images(): MorphMany + { + return $this->morphMany(Image::class, 'imageable'); + } + + public function coverImage(): MorphOne + { + return $this->morphOne(Image::class, 'imageable') + ->orderBy('id', 'desc') + ->where('location', 'cover') + ->withDefault(function ($userImage) { + $userImage->path = 'images/default-cover.jpg'; + }); + } } diff --git a/app/Models/User.php b/app/Models/User.php index 223ef83..5772565 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -2,9 +2,12 @@ namespace App; +use App\Models\Image; use App\Models\Memo; use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Database\Eloquent\Relations\HasMany; +use Illuminate\Database\Eloquent\Relations\MorphMany; +use Illuminate\Database\Eloquent\Relations\MorphOne; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Laravel\Passport\HasApiTokens; @@ -54,4 +57,23 @@ class User extends Authenticatable { return $this->hasMany(Memo::class); } + + public function images(): MorphMany + { + return $this->morphMany(Image::class, 'imageable'); + } + + public function profileImage(): MorphOne + { + return $this->morphOne(Image::class, 'imageable') + ->where('location', 'profile') + ->orderBy('id', 'desc'); + } + + public function coverImage(): MorphOne + { + return $this->morphOne(Image::class, 'imageable') + ->where('location', 'cover') + ->orderBy('id', 'desc'); + } } diff --git a/composer.json b/composer.json index 083146b..f6ede49 100644 --- a/composer.json +++ b/composer.json @@ -12,6 +12,7 @@ "fideloper/proxy": "^4.2", "fruitcake/laravel-cors": "^1.0", "guzzlehttp/guzzle": "^6.5", + "intervention/image": "^2.5", "laravel/framework": "^7.0", "laravel/passport": "^8.4", "laravel/tinker": "^2.0", diff --git a/composer.lock b/composer.lock index 87a3ea1..05b7362 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "bc656763558a52327994265003e73f70", + "content-hash": "2c4223d87e78990cf94811823ed227a9", "packages": [ { "name": "asm89/stack-cors", @@ -752,6 +752,76 @@ ], "time": "2019-07-01T23:21:34+00:00" }, + { + "name": "intervention/image", + "version": "2.5.1", + "source": { + "type": "git", + "url": "https://github.com/Intervention/image.git", + "reference": "abbf18d5ab8367f96b3205ca3c89fb2fa598c69e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Intervention/image/zipball/abbf18d5ab8367f96b3205ca3c89fb2fa598c69e", + "reference": "abbf18d5ab8367f96b3205ca3c89fb2fa598c69e", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "guzzlehttp/psr7": "~1.1", + "php": ">=5.4.0" + }, + "require-dev": { + "mockery/mockery": "~0.9.2", + "phpunit/phpunit": "^4.8 || ^5.7" + }, + "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.4-dev" + }, + "laravel": { + "providers": [ + "Intervention\\Image\\ImageServiceProvider" + ], + "aliases": { + "Image": "Intervention\\Image\\Facades\\Image" + } + } + }, + "autoload": { + "psr-4": { + "Intervention\\Image\\": "src/Intervention/Image" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Oliver Vogel", + "email": "oliver@olivervogel.com", + "homepage": "http://olivervogel.com/" + } + ], + "description": "Image handling and manipulation library with support for Laravel integration", + "homepage": "http://image.intervention.io/", + "keywords": [ + "gd", + "image", + "imagick", + "laravel", + "thumbnail", + "watermark" + ], + "time": "2019-11-02T09:15:47+00:00" + }, { "name": "jakub-onderka/php-console-color", "version": "v0.2", diff --git a/database/migrations/2020_04_15_195531_create_images_table.php b/database/migrations/2020_04_15_195531_create_images_table.php new file mode 100644 index 0000000..14e7848 --- /dev/null +++ b/database/migrations/2020_04_15_195531_create_images_table.php @@ -0,0 +1,36 @@ +id(); + $table->morphs('imageable'); + $table->string('path'); + $table->smallInteger('width'); + $table->smallInteger('height'); + $table->string('location'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('images'); + } +} diff --git a/package.json b/package.json index 058103c..d06d4b6 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "vuex": "^3.1.3" }, "dependencies": { + "dropzone": "^5.7.0", "laravel-mix-svg-vue": "^0.2.6", "markdown-it": "^10.0.0", "markdown-it-checkbox": "^1.1.0" diff --git a/resources/js/components/UploadableImage.vue b/resources/js/components/UploadableImage.vue new file mode 100644 index 0000000..a6cf762 --- /dev/null +++ b/resources/js/components/UploadableImage.vue @@ -0,0 +1,89 @@ + + + diff --git a/resources/js/router.js b/resources/js/router.js index c172149..8eeaca9 100644 --- a/resources/js/router.js +++ b/resources/js/router.js @@ -1,7 +1,7 @@ import Vue from 'vue' import VueRouter from 'vue-router' import Home from "./views/Home" -import Profil from "./views/User/UserProfil"; +import Profil from "./views/User/UserProfile"; import DashBoard from "./views/DashBoard"; import CssTesteur from "./views/CssTesteur"; import MemoIndex from "./views/Memo/MemoIndex"; diff --git a/resources/js/views/Memo/MemoEdit.vue b/resources/js/views/Memo/MemoEdit.vue index b968c40..746449d 100755 --- a/resources/js/views/Memo/MemoEdit.vue +++ b/resources/js/views/Memo/MemoEdit.vue @@ -1,33 +1,51 @@