Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion app/Http/Controllers/PostsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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'));
}
Expand Down Expand Up @@ -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();
}

Expand Down
5 changes: 5 additions & 0 deletions app/Post.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,9 @@ class Post extends Model
protected $table = 'posts';

protected $guarded = [];

public function tags()
{
return $this->belongsToMany(Tag::class);
}
}
11 changes: 11 additions & 0 deletions app/Post_tag.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post_tag extends Model
{
protected $table = 'post_tag';
protected $guarded = [];
}
17 changes: 17 additions & 0 deletions app/Tag.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Tag extends Model
{
protected $table = 'tags';

protected $guarded = [];

public function posts()
{
return $this->belongsToMany(Post::class);
}
}
66 changes: 60 additions & 6 deletions database/dumps/apsky-laravel.sql
Original file line number Diff line number Diff line change
Expand Up @@ -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 */;

--
Expand All @@ -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;

Expand All @@ -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 */;

--
Expand All @@ -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;

Expand Down Expand Up @@ -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`
--
Expand Down Expand Up @@ -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?<script>hello</script>',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`
--
Expand Down Expand Up @@ -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
34 changes: 34 additions & 0 deletions database/migrations/2020_09_07_173528_create_tags_table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

class CreateTagsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('tags', function (Blueprint $table) {
$table->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');
}
}
34 changes: 34 additions & 0 deletions database/migrations/2020_09_07_185537_create_post_tag_table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreatePostTagTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('post_tag', function (Blueprint $table) {
$table->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');
}
}
31 changes: 25 additions & 6 deletions resources/views/index.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
@section('content')
<main class="py-4" style="min-height: 88vh">
<div class="container">
<section class="posts-section mb-2">
<h2 class="posts-section__header">Most recent posts</h2>
<section class="posts-section mb-2 row flex-column flex-sm-row">
<h3 class="posts-section__header col-12 order-2 order-sm-0 text-center">Most recent posts</h3>

@if ($posts->count())
<div class="posts-section__posts row post">
<div class="posts-section__posts order-2 order-sm-0 col-12 col-sm-8 col-lg-10 post">
@foreach($posts as $post)
<div class="post__item col-md-6">
<div class="post__item">
<div class="post__intro text-break row no-gutters border rounded overflow-hidden flex-md-row mb-4 shadow-sm h-md-250 position-relative">
<div class="post__heading col-6 p-4 d-flex flex-column position-static">
<div class="post__heading col-12 col-lg-6 p-4 d-flex flex-column">
<strong class="d-inline-block mb-2 text-primary">Post #{{ $post->id }}</strong>

<h3 class="post__name mb-0">{{ $post->name }}</h3>
Expand All @@ -24,7 +24,15 @@

<p class="post__preview card-text mb-auto text-justify" style="height: 115px"> {{ str_limit($post->text, $limit = 100, $end = '...') }} </p>

<a href="{{ route('post-show', $post->id) }}" class="post__view stretched-link">Continue reading</a>
@if($post->tags->isNotEmpty())
<div class="post__tags mb-2">
@foreach($post->tags as $tag)
<a href="#" class="badge badge-info text-white">{{ $tag->name }}</a>
@endforeach
</div>
@endif

<a href="{{ route('post-show', $post->id) }}" class="post__view">Continue reading</a>
</div>

<div class="post__photo col-6 d-none d-lg-flex align-items-center p-2">
Expand All @@ -38,6 +46,17 @@
</div>
@endforeach
</div>

<div class="tags-cloud d-flex flex-column col-12 col-sm-4 col-lg-2 order-1">
<h3 class="tags-cloud__header text-center">Available Tags</h3>

<div class="tags-cloud__tags list-group flex-row flex-wrap flex-sm-column justify-content-start mb-3 mb-sm-0">
@foreach($tags as $tag)
<a href="#" class="btn btn-sm btn-info text-white m-1">{{ strtoupper($tag->name) }}</a>
@endforeach
</div>
</div>

@else
<p class="no-posts">Not available posts yet</p>
@endif
Expand Down
27 changes: 24 additions & 3 deletions resources/views/posts/edit.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -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=""
>

Expand All @@ -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=""
>

Expand All @@ -65,7 +65,7 @@ class="form-control @error('text') is-invalid @enderror"
cols="30"
rows="10"
placeholder="Post content here"
required="">{{ $post->text }}</textarea>
required="">{{ old('text', $post->text) }}</textarea>

<div class="invalid-feedback">
Post Description is required.
Expand All @@ -78,6 +78,27 @@ class="form-control @error('text') is-invalid @enderror"
@enderror
</div>

<div class="form__field col-6 mb-3">
<label for="form-tags">Tags</label>
<input type="text"
class="form-control @error('description') is-invalid @enderror"
id="form-tags"
name="tags"
value="{{ old('tags', $post->tags->pluck('name'))->implode(', ') }}"
required=""
>

<div class="invalid-feedback">
Post Description is required.
</div>

@error('description')
<div class="alert alert-danger">
{{ $message }}
</div>
@enderror
</div>

<div class="form__field form-check mb-2">
<input class="form__checkbox"
id="form-checkbox"
Expand Down
Loading