diff --git a/app/Http/Controllers/PostsController.php b/app/Http/Controllers/PostsController.php index 7fe82e3..eaaa25c 100644 --- a/app/Http/Controllers/PostsController.php +++ b/app/Http/Controllers/PostsController.php @@ -3,13 +3,15 @@ namespace App\Http\Controllers; use App\Post; +use App\Post_tag; +use App\Tag; use Illuminate\Http\Request; class PostsController extends Controller { public function index() { - $posts = Post::all(); + $posts = Post::with('tags')->latest()->get(); return view('/posts.index', compact('posts')); } @@ -57,6 +59,32 @@ public function update(Request $request, Post $post) $post->update($values); + $postTags = $post->tags->keyBy('name'); + + if (!is_null($request['tags'])) { + $requestTags = collect(explode(', ', $request['tags']))->keyBy(function ($item) { return $item; }); + } else { + $requestTags = collect([]); + } + + $deleteTags = $postTags->diffKeys($requestTags); + $addTags = $requestTags->diffKeys($postTags); + + if ($addTags->isNotEmpty()) { + foreach ($addTags as $tag) { + $tag = Tag::firstOrCreate(['name' => $tag]); + $post->tags()->attach($tag); + }; + } + + if ($deleteTags->isNotEmpty()) { + foreach ($deleteTags as $tag) { + $post->tags()->detach($tag); + $isLastTag = Post_tag::where('tag_id', $tag->id)->first(); + if (!$isLastTag) $tag->delete(); + }; + } + return back(); } diff --git a/app/Post.php b/app/Post.php index c225efb..0da7d71 100644 --- a/app/Post.php +++ b/app/Post.php @@ -9,4 +9,9 @@ class Post extends Model protected $table = 'posts'; protected $guarded = []; + + public function tags() + { + return $this->belongsToMany(Tag::class); + } } diff --git a/app/Post_tag.php b/app/Post_tag.php new file mode 100644 index 0000000..895f968 --- /dev/null +++ b/app/Post_tag.php @@ -0,0 +1,11 @@ +belongsToMany(Post::class); + } +} diff --git a/database/dumps/apsky-laravel.sql b/database/dumps/apsky-laravel.sql index ee5ee00..9fcc4a2 100644 --- a/database/dumps/apsky-laravel.sql +++ b/database/dumps/apsky-laravel.sql @@ -82,7 +82,7 @@ CREATE TABLE `feedback` ( `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -91,7 +91,7 @@ CREATE TABLE `feedback` ( LOCK TABLES `feedback` WRITE; /*!40000 ALTER TABLE `feedback` DISABLE KEYS */; -INSERT INTO `feedback` VALUES (3,'qwe@mail.ru','Lorem','2020-08-28 13:08:36','2020-08-28 13:08:36'),(4,'qadz@mail.ru','Lorem2','2020-08-28 13:08:36','2020-08-28 13:08:36'); +INSERT INTO `feedback` VALUES (3,'qwe@mail.ru','Lorem ipsum dolor sit amet, consectetur adipisicing elit. Commodi exercitationem nisi tempora temporibus. Alias architecto asperiores, consequatur culpa deleniti enim facilis fuga necessitatibus, nisi repellendus rerum sit? Distinctio, fuga, recusandae.','2020-08-28 13:08:36','2020-08-28 13:08:36'),(4,'qadz@mail.ru','Lorem ipsum dolor sit amet, consectetur adipisicing elit. Commodi exercitationem nisi tempora temporibus. Alias architecto asperiores, consequatur culpa deleniti enim facilis fuga necessitatibus, nisi repellendus rerum sit? Distinctio, fuga, recusandae.','2020-08-28 13:08:36','2020-08-28 13:08:36'),(5,'qweqe@mail.ru','qweqeqe','2020-08-28 11:12:28','2020-08-28 11:12:28'); /*!40000 ALTER TABLE `feedback` ENABLE KEYS */; UNLOCK TABLES; @@ -107,7 +107,7 @@ CREATE TABLE `migrations` ( `migration` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, `batch` int NOT NULL, PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -116,7 +116,7 @@ CREATE TABLE `migrations` ( LOCK TABLES `migrations` WRITE; /*!40000 ALTER TABLE `migrations` DISABLE KEYS */; -INSERT INTO `migrations` VALUES (7,'2014_10_12_000000_create_users_table',1),(8,'2014_10_12_100000_create_password_resets_table',1),(9,'2019_08_19_000000_create_failed_jobs_table',1),(10,'2020_08_26_090725_create_posts_table',1),(11,'2020_08_26_103233_create_contacts_table',1),(12,'2020_08_28_124336_create_feedback_table',2); +INSERT INTO `migrations` VALUES (7,'2014_10_12_000000_create_users_table',1),(8,'2014_10_12_100000_create_password_resets_table',1),(9,'2019_08_19_000000_create_failed_jobs_table',1),(10,'2020_08_26_090725_create_posts_table',1),(11,'2020_08_26_103233_create_contacts_table',1),(12,'2020_08_28_124336_create_feedback_table',2),(14,'2020_09_07_173528_create_tags_table',3),(15,'2020_09_07_185537_create_post_tag_table',4); /*!40000 ALTER TABLE `migrations` ENABLE KEYS */; UNLOCK TABLES; @@ -144,6 +144,33 @@ LOCK TABLES `password_resets` WRITE; /*!40000 ALTER TABLE `password_resets` ENABLE KEYS */; UNLOCK TABLES; +-- +-- Table structure for table `post_tag` +-- + +DROP TABLE IF EXISTS `post_tag`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `post_tag` ( + `post_id` bigint unsigned NOT NULL, + `tag_id` bigint unsigned NOT NULL, + PRIMARY KEY (`post_id`,`tag_id`), + KEY `post_tag_tag_id_foreign` (`tag_id`), + CONSTRAINT `post_tag_post_id_foreign` FOREIGN KEY (`post_id`) REFERENCES `posts` (`id`) ON DELETE CASCADE, + CONSTRAINT `post_tag_tag_id_foreign` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `post_tag` +-- + +LOCK TABLES `post_tag` WRITE; +/*!40000 ALTER TABLE `post_tag` DISABLE KEYS */; +INSERT INTO `post_tag` VALUES (4,1),(5,1),(6,1),(4,2),(5,3),(6,4); +/*!40000 ALTER TABLE `post_tag` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `posts` -- @@ -171,10 +198,37 @@ CREATE TABLE `posts` ( LOCK TABLES `posts` WRITE; /*!40000 ALTER TABLE `posts` DISABLE KEYS */; -INSERT INTO `posts` VALUES (3,'123','Post','Post desc','Lorem ipsum dolor sit amet, consectetur adipisicing elit. Alias beatae consequatur consequuntur, debitis dicta eos explicabo fugit labore molestiae, nam nemo odit placeat quae quisquam quos repellat repellendus tempore, voluptates?',0,'2020-08-26 17:05:56','2020-08-28 06:43:25'),(4,'4123','Post','Post desc','Lorem ipsum dolor sit amet, consectetur adipisicing elit. Alias beatae consequatur consequuntur, debitis dicta eos explicabo fugit labore molestiae, nam nemo odit placeat quae quisquam quos repellat repellendus tempore, voluptates?',0,'2020-08-26 17:05:56','2020-08-28 06:43:25'),(5,'12313','qweqe','qweqe','qweqeq',0,'2020-08-28 05:05:04','2020-08-28 05:05:04'),(6,'qweqe','qweqe','qweqe','qweqweqe',0,'2020-08-28 06:58:18','2020-08-28 06:58:18'),(7,'qweq','qweqe','qweqe','qweqe',0,'2020-08-28 07:01:17','2020-08-28 07:01:17'),(8,'1231qweq','qweqe','qweqeq','qweqeqe',0,'2020-08-28 07:20:33','2020-08-28 07:20:33'),(9,'qweqeqeqweqw','eeqweqeqe','qweqe','11',0,'2020-08-28 07:28:29','2020-08-28 07:28:29'),(10,'qweq12','qweqe','qw','aqewqe',1,'2020-08-28 08:17:11','2020-08-28 08:17:11'),(11,'qweqezz','qwezzz','qqweq','1qwe',1,'2020-08-28 08:39:17','2020-08-28 08:39:17'),(12,'qweqezz??','qwezzzq','qqweq','1qwe',1,'2020-08-28 08:39:24','2020-08-28 08:39:24'),(13,'1qweq','qweqeq','1231','312313',1,'2020-08-28 08:46:49','2020-08-28 08:46:49'); +INSERT INTO `posts` VALUES (4,'4123','Post4','Post desc4','Lorem ipsum dolor sit amet, consectetur adipisicing elit. Alias beatae consequatur consequuntur, debitis dicta eos explicabo fugit labore molestiae, nam nemo odit placeat quae quisquam quos repellat repellendus tempore, voluptates?',1,'2020-08-26 17:05:56','2020-09-07 14:10:35'),(5,'12313','qweqe','qweqe','qweqeq',0,'2020-08-28 05:05:04','2020-08-28 05:05:04'),(6,'qweqe','qweqe','qweqe','qweqweqe',0,'2020-08-28 06:58:18','2020-08-28 06:58:18'),(7,'qweq','qweqe','qweqe','qweqe',0,'2020-08-28 07:01:17','2020-08-28 07:01:17'),(8,'1231qweq','qweqe','qweqeq','qweqeqe',0,'2020-08-28 07:20:33','2020-08-28 07:20:33'),(9,'qweqeqeqweqw','eeqweqeqe','qweqe','11',0,'2020-08-28 07:28:29','2020-08-28 07:28:29'); /*!40000 ALTER TABLE `posts` ENABLE KEYS */; UNLOCK TABLES; +-- +-- Table structure for table `tags` +-- + +DROP TABLE IF EXISTS `tags`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `tags` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `tags_name_unique` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `tags` +-- + +LOCK TABLES `tags` WRITE; +/*!40000 ALTER TABLE `tags` DISABLE KEYS */; +INSERT INTO `tags` VALUES (1,'Tag1','2020-09-07 18:37:02','2020-09-07 18:37:02'),(2,'Tag2','2020-09-07 18:37:02','2020-09-07 18:37:02'),(3,'Tag3','2020-09-07 18:37:02','2020-09-07 18:37:02'),(4,'Tag4','2020-09-07 18:37:02','2020-09-07 18:37:02'); +/*!40000 ALTER TABLE `tags` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `users` -- @@ -214,4 +268,4 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2020-08-28 16:08:40 +-- Dump completed on 2020-09-07 23:02:08 diff --git a/database/migrations/2020_09_07_173528_create_tags_table.php b/database/migrations/2020_09_07_173528_create_tags_table.php new file mode 100644 index 0000000..f27c55c --- /dev/null +++ b/database/migrations/2020_09_07_173528_create_tags_table.php @@ -0,0 +1,34 @@ +id(); + $table->string('name')->unique(); + $table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP')); + $table->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP')); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('tags'); + } +} diff --git a/database/migrations/2020_09_07_185537_create_post_tag_table.php b/database/migrations/2020_09_07_185537_create_post_tag_table.php new file mode 100644 index 0000000..ca1f0ea --- /dev/null +++ b/database/migrations/2020_09_07_185537_create_post_tag_table.php @@ -0,0 +1,34 @@ +unsignedBigInteger('post_id'); + $table->unsignedBigInteger('tag_id'); + $table->primary(['post_id', 'tag_id']); + $table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade'); + $table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('post_tag'); + } +} diff --git a/resources/views/index.blade.php b/resources/views/index.blade.php index cce3fb7..b37f383 100644 --- a/resources/views/index.blade.php +++ b/resources/views/index.blade.php @@ -7,15 +7,15 @@ @section('content')
-
-

Most recent posts

+
+

Most recent posts

@if ($posts->count()) -
+
@foreach($posts as $post) -
+
-
+
Post #{{ $post->id }}

{{ $post->name }}

@@ -24,7 +24,15 @@

{{ str_limit($post->text, $limit = 100, $end = '...') }}

- Continue reading + @if($post->tags->isNotEmpty()) + + @endif + + Continue reading
@@ -38,6 +46,17 @@
@endforeach
+ +
+

Available Tags

+ +
+ @foreach($tags as $tag) + {{ strtoupper($tag->name) }} + @endforeach +
+
+ @else

Not available posts yet

@endif diff --git a/resources/views/posts/edit.blade.php b/resources/views/posts/edit.blade.php index 536f8e1..56e488f 100644 --- a/resources/views/posts/edit.blade.php +++ b/resources/views/posts/edit.blade.php @@ -21,7 +21,7 @@ class="form-control @error('name') is-invalid @enderror" id="form-name" name="name" - value="{{ $post->name }}" + value="{{ old('name', $post->name) }}" required="" > @@ -42,7 +42,7 @@ class="form-control @error('name') is-invalid @enderror" class="form-control @error('description') is-invalid @enderror" id="form-description" name="description" - value="{{ $post->description }}" + value="{{ old('description', $post->description) }}" required="" > @@ -65,7 +65,7 @@ class="form-control @error('text') is-invalid @enderror" cols="30" rows="10" placeholder="Post content here" - required="">{{ $post->text }} + required="">{{ old('text', $post->text) }}
Post Description is required. @@ -78,6 +78,27 @@ class="form-control @error('text') is-invalid @enderror" @enderror
+
+ + + +
+ Post Description is required. +
+ + @error('description') +
+ {{ $message }} +
+ @enderror +
+
get(); - - return view('/index', compact('posts')); + $tags = Tag::all(); + return view('/index', compact('posts', 'tags')); })->name('home');