Skip to content

Commit 74def64

Browse files
committed
initial implementation
1 parent 0109863 commit 74def64

File tree

17 files changed

+364
-2
lines changed

17 files changed

+364
-2
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,5 @@ Homestead.yaml
1111
.env
1212
/aliases
1313
/after.sh
14+
.idea/
15+
.vagrant/

Homestead.yaml.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ keys:
77
- ~/.ssh/id_rsa
88
folders:
99
-
10-
map: ~/Sites/laravelio
10+
map: ~/code/laravelio
1111
to: /home/vagrant/Code/laravelio
1212
sites:
1313
-
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace App\Exceptions;
4+
5+
use Exception;
6+
7+
class CannotLikeReplyTwice extends Exception
8+
{
9+
10+
}

app/Helpers/HasLikes.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: bobbyborisov
5+
* Date: 12/3/17
6+
* Time: 1:51 PM
7+
*/
8+
9+
namespace App\Helpers;
10+
11+
use App\Models\Like;
12+
use App\User;
13+
14+
trait HasLikes
15+
{
16+
protected static function bootHasLikes()
17+
{
18+
static::deleting(function ($model){
19+
$model->likes->each->delete();
20+
});
21+
}
22+
23+
public function likedBy(User $user)
24+
{
25+
$this->likes()->create(['user_id' => $user->id]);
26+
}
27+
28+
public function dislikedBy(User $user)
29+
{
30+
$this->likes()->where('user_id', $user->id)->get()->first()->delete();
31+
}
32+
33+
public function likes()
34+
{
35+
return $this->morphMany(Like::class, 'liked');
36+
}
37+
38+
public function isLikedBy(User $user)
39+
{
40+
return $this->likes()->where('user_id', $user->id)->exists();
41+
}
42+
43+
public function getLikesCountAttribute()
44+
{
45+
return $this->likes->count();
46+
}
47+
}

app/Http/Controllers/ReplyController.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace App\Http\Controllers;
44

5+
use App\Jobs\DislikeReply;
6+
use App\Jobs\LikeReply;
57
use App\Models\Reply;
68
use App\Models\Thread;
79
use App\Jobs\CreateReply;
@@ -62,6 +64,20 @@ public function delete(Reply $reply)
6264
return $this->redirectToReplyAble($reply->replyAble());
6365
}
6466

67+
public function like(Reply $reply)
68+
{
69+
$this->dispatchNow(new LikeReply($reply, auth()->user()));
70+
71+
return back();
72+
}
73+
74+
public function dislike(Reply $reply)
75+
{
76+
$this->dispatchNow(new DislikeReply($reply, auth()->user()));
77+
78+
return back();
79+
}
80+
6581
private function redirectToReplyAble(ReplyAble $replyAble): RedirectResponse
6682
{
6783
if ($replyAble instanceof Thread) {

app/Jobs/DislikeReply.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
namespace App\Jobs;
4+
5+
use App\Models\Reply;
6+
use App\User;
7+
use Illuminate\Bus\Queueable;
8+
use Illuminate\Queue\SerializesModels;
9+
use Illuminate\Queue\InteractsWithQueue;
10+
use Illuminate\Contracts\Queue\ShouldQueue;
11+
use Illuminate\Foundation\Bus\Dispatchable;
12+
13+
class DislikeReply implements ShouldQueue
14+
{
15+
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
16+
17+
/**
18+
* @var \App\Models\Reply
19+
*/
20+
private $reply;
21+
22+
/**
23+
* @var \App\Jobs\User
24+
*/
25+
private $user;
26+
27+
/**
28+
* Create a new job instance.
29+
*
30+
* @param \App\Models\Reply $reply
31+
* @param \App\Jobs\User $user
32+
*/
33+
public function __construct(Reply $reply, User $user)
34+
{
35+
$this->reply = $reply;
36+
$this->user = $user;
37+
}
38+
39+
/**
40+
* Execute the job.
41+
*
42+
* @return void
43+
*/
44+
public function handle()
45+
{
46+
$this->reply->dislikedBy($this->user);
47+
}
48+
}

app/Jobs/LikeReply.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
namespace App\Jobs;
4+
5+
use App\Exceptions\CannotLikeReplyTwice;
6+
use App\Models\Reply;
7+
use App\User;
8+
use Illuminate\Bus\Queueable;
9+
use Illuminate\Database\QueryException;
10+
use Illuminate\Queue\SerializesModels;
11+
use Illuminate\Queue\InteractsWithQueue;
12+
use Illuminate\Contracts\Queue\ShouldQueue;
13+
use Illuminate\Foundation\Bus\Dispatchable;
14+
15+
class LikeReply implements ShouldQueue
16+
{
17+
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
18+
19+
/**
20+
* @var \App\Models\Reply
21+
*/
22+
private $reply;
23+
24+
/**
25+
* @var \App\User
26+
*/
27+
private $user;
28+
29+
/**
30+
* Create a new job instance.
31+
*
32+
* @param \App\Models\Reply $reply
33+
* @param \App\User $user
34+
*/
35+
public function __construct(Reply $reply, User $user)
36+
{
37+
$this->reply = $reply;
38+
$this->user = $user;
39+
}
40+
41+
/**
42+
* Execute the job.
43+
*
44+
* @return void
45+
* @throws \App\Exceptions\CannotLikeReplyTwice
46+
*/
47+
public function handle()
48+
{
49+
try {
50+
$this->reply->likedBy($this->user);
51+
} catch (QueryException $exception) {
52+
throw new CannotLikeReplyTwice('Sorry, you cannot like a reply twice');
53+
}
54+
}
55+
}

app/Models/Like.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace App\Models;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
7+
class Like extends Model
8+
{
9+
protected $fillable = ['user_id'];
10+
}

app/Models/Reply.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@
33
namespace App\Models;
44

55
use App\Helpers\HasAuthor;
6+
use App\Helpers\HasLikes;
67
use App\Helpers\ModelHelpers;
78
use App\Helpers\HasTimestamps;
89
use Illuminate\Database\Eloquent\Model;
910
use Illuminate\Database\Eloquent\Relations\MorphTo;
1011

1112
class Reply extends Model
1213
{
13-
use HasAuthor, HasTimestamps, ModelHelpers;
14+
use HasLikes,
15+
HasAuthor, HasTimestamps, ModelHelpers;
1416

1517
/**
1618
* {@inheritdoc}
@@ -22,6 +24,10 @@ class Reply extends Model
2224
*/
2325
protected $fillable = ['body', 'ip'];
2426

27+
protected $with = ['likes'];
28+
29+
protected $appends = ['likes_count'];
30+
2531
public function id(): int
2632
{
2733
return $this->id;
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
use Illuminate\Support\Facades\Schema;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Database\Migrations\Migration;
6+
7+
class CreateLikesTable extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*
12+
* @return void
13+
*/
14+
public function up()
15+
{
16+
Schema::create('likes', function (Blueprint $table) {
17+
$table->increments('id');
18+
$table->unsignedInteger('user_id');
19+
$table->unsignedInteger('liked_id');
20+
$table->string('liked_type');
21+
$table->timestamps();
22+
23+
$table->unique(['user_id', 'liked_id' , 'liked_type']);
24+
});
25+
}
26+
27+
/**
28+
* Reverse the migrations.
29+
*
30+
* @return void
31+
*/
32+
public function down()
33+
{
34+
Schema::dropIfExists('likes');
35+
}
36+
}

0 commit comments

Comments
 (0)