From e62b9188dbf9abd4ae3fc3beee8628c9ead89aa7 Mon Sep 17 00:00:00 2001 From: Sergey Markov Date: Wed, 16 Nov 2022 11:27:32 +1000 Subject: [PATCH 1/2] save a post to the database using a form, redirect with a success message to the user --- .../Auth/AuthenticatedSessionController.php | 2 + app/Http/Controllers/PostController.php | 47 ++++++++++ app/Http/Requests/PostCreateRequest.php | 31 +++++++ app/Models/Post.php | 23 +++++ composer.json | 1 + composer.lock | 86 ++++++++++++++++++- database/factories/PostFactory.php | 25 ++++++ database/factories/UserFactory.php | 2 +- .../2022_11_16_001950_create_posts_table.php | 34 ++++++++ ...6_004650_add_image_path_to_posts_table.php | 32 +++++++ database/seeders/DatabaseSeeder.php | 11 ++- database/seeders/PostSeeder.php | 22 +++++ public/uploads/empty | 0 .../views/components/input-file.blade.php | 14 +++ resources/views/components/textarea.blade.php | 3 + resources/views/dashboard.blade.php | 10 +-- resources/views/home.blade.php | 45 ++++++++++ resources/views/layouts/app.blade.php | 67 ++++++++------- resources/views/layouts/navigation.blade.php | 29 ++++--- resources/views/messages/flash.blade.php | 11 +++ routes/web.php | 2 + tests/Feature/PostTest.php | 23 +++++ 22 files changed, 462 insertions(+), 58 deletions(-) create mode 100644 app/Http/Controllers/PostController.php create mode 100644 app/Http/Requests/PostCreateRequest.php create mode 100644 app/Models/Post.php create mode 100644 database/factories/PostFactory.php create mode 100644 database/migrations/2022_11_16_001950_create_posts_table.php create mode 100644 database/migrations/2022_11_16_004650_add_image_path_to_posts_table.php create mode 100644 database/seeders/PostSeeder.php create mode 100644 public/uploads/empty create mode 100644 resources/views/components/input-file.blade.php create mode 100644 resources/views/components/textarea.blade.php create mode 100644 resources/views/home.blade.php create mode 100644 resources/views/messages/flash.blade.php create mode 100644 tests/Feature/PostTest.php diff --git a/app/Http/Controllers/Auth/AuthenticatedSessionController.php b/app/Http/Controllers/Auth/AuthenticatedSessionController.php index 09abe8765..f1966a274 100644 --- a/app/Http/Controllers/Auth/AuthenticatedSessionController.php +++ b/app/Http/Controllers/Auth/AuthenticatedSessionController.php @@ -32,6 +32,8 @@ public function store(LoginRequest $request) $request->session()->regenerate(); + session()->flash('success', "You're logged in!"); + return redirect()->intended(RouteServiceProvider::HOME); } diff --git a/app/Http/Controllers/PostController.php b/app/Http/Controllers/PostController.php new file mode 100644 index 000000000..7e009dc56 --- /dev/null +++ b/app/Http/Controllers/PostController.php @@ -0,0 +1,47 @@ +hasFile('image')) { + $file = $request->file('image'); + $imagePath = '/uploads/' . pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME) . '-' . date('mdhis') . '.' . $file->getClientOriginalExtension(); + Image::make($request->file('image'))->resize($this::RESIZE_FILE_WIDTH, $this::RESIZE_FILE_HEIGHT)->save(public_path() . $imagePath); + } + $post = Post::create([ + 'user_id' => Auth::user()->id, + 'name' => $request->name, + 'description' => $request->description, + 'image_path' => $imagePath + ]); + } catch (QueryException $e) { + session()->flash('exception', "Error has occured."); + } + + session()->flash('success', "Post #{$post->id} was successfully created"); + + return redirect(route('post.create')); + } +} diff --git a/app/Http/Requests/PostCreateRequest.php b/app/Http/Requests/PostCreateRequest.php new file mode 100644 index 000000000..0d30f547e --- /dev/null +++ b/app/Http/Requests/PostCreateRequest.php @@ -0,0 +1,31 @@ + + */ + public function rules() + { + return [ + 'name' => 'required', + 'image' => 'image|mimes:jpg,png,jpeg,gif,svg' + ]; + } +} diff --git a/app/Models/Post.php b/app/Models/Post.php new file mode 100644 index 000000000..a31d5b4b7 --- /dev/null +++ b/app/Models/Post.php @@ -0,0 +1,23 @@ +belongsTo(User::class); + } +} diff --git a/composer.json b/composer.json index f45b5b916..d1c6e2672 100644 --- a/composer.json +++ b/composer.json @@ -7,6 +7,7 @@ "require": { "php": "^8.0.2", "guzzlehttp/guzzle": "^7.2", + "intervention/image": "^2.7", "laravel/framework": "^9.19", "laravel/sanctum": "^3.0", "laravel/tinker": "^2.7" diff --git a/composer.lock b/composer.lock index b5c88b445..8832c8ab8 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": "5d5b387077098f2f11ded0abfe855eae", + "content-hash": "3a7ecfc4c7a9a6c2db4e374466501ec2", "packages": [ { "name": "brick/math", @@ -889,6 +889,90 @@ ], "time": "2022-06-20T21:43:11+00:00" }, + { + "name": "intervention/image", + "version": "2.7.2", + "source": { + "type": "git", + "url": "https://github.com/Intervention/image.git", + "reference": "04be355f8d6734c826045d02a1079ad658322dad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Intervention/image/zipball/04be355f8d6734c826045d02a1079ad658322dad", + "reference": "04be355f8d6734c826045d02a1079ad658322dad", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "guzzlehttp/psr7": "~1.1 || ^2.0", + "php": ">=5.4.0" + }, + "require-dev": { + "mockery/mockery": "~0.9.2", + "phpunit/phpunit": "^4.8 || ^5.7 || ^7.5.15" + }, + "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@intervention.io", + "homepage": "https://intervention.io/" + } + ], + "description": "Image handling and manipulation library with support for Laravel integration", + "homepage": "http://image.intervention.io/", + "keywords": [ + "gd", + "image", + "imagick", + "laravel", + "thumbnail", + "watermark" + ], + "support": { + "issues": "https://github.com/Intervention/image/issues", + "source": "https://github.com/Intervention/image/tree/2.7.2" + }, + "funding": [ + { + "url": "https://paypal.me/interventionio", + "type": "custom" + }, + { + "url": "https://github.com/Intervention", + "type": "github" + } + ], + "time": "2022-05-21T17:30:32+00:00" + }, { "name": "laravel/framework", "version": "v9.23.0", diff --git a/database/factories/PostFactory.php b/database/factories/PostFactory.php new file mode 100644 index 000000000..0713b3cc8 --- /dev/null +++ b/database/factories/PostFactory.php @@ -0,0 +1,25 @@ + + */ +class PostFactory extends Factory +{ + /** + * Define the model's default state. + * + * @return array + */ + public function definition() + { + return [ + 'user_id' => 1, + 'name' => fake()->name(), + 'description' => fake()->sentence() + ]; + } +} diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php index 20b35322d..751109b74 100644 --- a/database/factories/UserFactory.php +++ b/database/factories/UserFactory.php @@ -21,7 +21,7 @@ public function definition() 'name' => fake()->name(), 'email' => fake()->safeEmail(), 'email_verified_at' => now(), - 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password + 'password' => bcrypt('password'), 'remember_token' => Str::random(10), ]; } diff --git a/database/migrations/2022_11_16_001950_create_posts_table.php b/database/migrations/2022_11_16_001950_create_posts_table.php new file mode 100644 index 000000000..788c3ee45 --- /dev/null +++ b/database/migrations/2022_11_16_001950_create_posts_table.php @@ -0,0 +1,34 @@ +id(); + $table->string('name')->nullable(false); + $table->text('description'); + $table->foreignId('user_id')->constrained('users')->cascadeOnDelete(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('posts'); + } +}; diff --git a/database/migrations/2022_11_16_004650_add_image_path_to_posts_table.php b/database/migrations/2022_11_16_004650_add_image_path_to_posts_table.php new file mode 100644 index 000000000..22a57526d --- /dev/null +++ b/database/migrations/2022_11_16_004650_add_image_path_to_posts_table.php @@ -0,0 +1,32 @@ +string('image_path')->nullable()->after('description'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('posts', function (Blueprint $table) { + $table->dropColumn('image_path'); + }); + } +}; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index a9aafbf99..676d4bf2f 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -14,11 +14,10 @@ class DatabaseSeeder extends Seeder */ public function run() { - // \App\Models\User::factory(10)->create(); - -// \App\Models\User::factory()->create([ -// 'name' => 'Test User', -// 'email' => 'user@codinglabs.test', -// ]); + \App\Models\User::factory()->create([ + 'id' => 1, + 'name' => 'Test User', + 'email' => 'user@codinglabs.test' + ]); } } diff --git a/database/seeders/PostSeeder.php b/database/seeders/PostSeeder.php new file mode 100644 index 000000000..035fdb2e5 --- /dev/null +++ b/database/seeders/PostSeeder.php @@ -0,0 +1,22 @@ +create([ + 'user_id' => 1, + 'name' => 'Post Title', + 'description' => 'some description', + ]); + } +} diff --git a/public/uploads/empty b/public/uploads/empty new file mode 100644 index 000000000..e69de29bb diff --git a/resources/views/components/input-file.blade.php b/resources/views/components/input-file.blade.php new file mode 100644 index 000000000..06864231d --- /dev/null +++ b/resources/views/components/input-file.blade.php @@ -0,0 +1,14 @@ +merge(['class' => 'block +w-full +px-3 +py-1.5 +text-base +font-normal +text-gray-700 +bg-gray-100 bg-clip-padding +border border-solid border-gray-300 +rounded +transition +ease-in-out +m-0 +focus:text-gray-700 focus:bg-white focus:border-blue-600 focus:outline-none']) !!}> \ No newline at end of file diff --git a/resources/views/components/textarea.blade.php b/resources/views/components/textarea.blade.php new file mode 100644 index 000000000..54e71efb3 --- /dev/null +++ b/resources/views/components/textarea.blade.php @@ -0,0 +1,3 @@ +@props(['disabled' => false]) + + \ No newline at end of file diff --git a/resources/views/dashboard.blade.php b/resources/views/dashboard.blade.php index 025a79a45..e5b286f0e 100644 --- a/resources/views/dashboard.blade.php +++ b/resources/views/dashboard.blade.php @@ -1,17 +1,17 @@ -

+

{{ __('Dashboard') }}

-
-
+
+
- You're logged in! +
- + \ No newline at end of file diff --git a/resources/views/home.blade.php b/resources/views/home.blade.php new file mode 100644 index 000000000..fd4def514 --- /dev/null +++ b/resources/views/home.blade.php @@ -0,0 +1,45 @@ + + + +

+ {{ __('Posts') }} +

+
+ +
+
+
+
+
+ +

Create New Post

+ +
+ @csrf +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + {{ __('Create') }} + +
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index 6ae3c8cbb..5b9998028 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -1,33 +1,38 @@ - - - - - - {{ config('app.name', 'Laravel') }} - - - - - - @vite(['resources/css/app.css', 'resources/js/app.js']) - - -
- @include('layouts.navigation') - - -
-
- {{ $header }} -
-
- - -
- {{ $slot }} -
-
- - + + + + + + + {{ config('app.name', 'Laravel') }} + + + + + + @vite(['resources/css/app.css', 'resources/js/app.js']) + + + +
+ @include('layouts.navigation') + + +
+
+ {{ $header }} +
+
+ + +
+ @include('messages.flash') + + {{ $slot }} +
+
+ + + \ No newline at end of file diff --git a/resources/views/layouts/navigation.blade.php b/resources/views/layouts/navigation.blade.php index 3355c7dde..4b5e1b96c 100644 --- a/resources/views/layouts/navigation.blade.php +++ b/resources/views/layouts/navigation.blade.php @@ -1,12 +1,12 @@