Skip to content

Commit 46a2a1b

Browse files
committed
- added feature for like/dislike post.
1 parent 6fe5aab commit 46a2a1b

File tree

3 files changed

+239
-0
lines changed

3 files changed

+239
-0
lines changed

app/Follow.php

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
<?php
2+
3+
namespace App;
4+
5+
use Carbon\Carbon;
6+
use Illuminate\Database\Eloquent\Model;
7+
use Illuminate\Database\Eloquent\Relations\MorphToMany;
8+
use stdClass;
9+
10+
/**
11+
* Class Follow.
12+
*/
13+
class Follow
14+
{
15+
const RELATION_LIKE = 'like';
16+
17+
const RELATION_FOLLOW = 'follow';
18+
19+
const RELATION_TYPES = [
20+
'likes' => 'like',
21+
'likers' => 'like',
22+
'fans' => 'like',
23+
'followings' => 'follow',
24+
'followers' => 'follow',
25+
];
26+
27+
/**
28+
* @param \Illuminate\Database\Eloquent\Model $model
29+
* @param string $relation
30+
* @param array|string|\Illuminate\Database\Eloquent\Model $target
31+
* @param string $class
32+
*
33+
* @return bool
34+
*/
35+
public static function isRelationExists(Model $model, $relation, $target, $class = null)
36+
{
37+
$target = self::formatTargets($target, $class ?: User::class);
38+
39+
if ($model->relationLoaded($relation)) {
40+
return $model->{$relation}->where($target->tableName . '.id', head($target->ids))->isNotEmpty();
41+
}
42+
43+
return $model->{$relation}($target->classname)->where($target->tableName . '.id', head($target->ids))->exists();
44+
}
45+
46+
/**
47+
* @param \Illuminate\Database\Eloquent\Model $model
48+
* @param string $relation
49+
* @param array|string|\Illuminate\Database\Eloquent\Model $targets
50+
* @param string $class
51+
*
52+
* @throws \Exception
53+
*
54+
* @return array
55+
*/
56+
public static function attachRelations(Model $model, $relation, $targets, $class)
57+
{
58+
$targets = self::attachPivotsFromRelation($model->{$relation}(), $targets, $class);
59+
60+
return $model->{$relation}($targets->classname)->sync($targets->targets, false);
61+
}
62+
63+
/**
64+
* @param \Illuminate\Database\Eloquent\Model $model
65+
* @param string $relation
66+
* @param array|string|\Illuminate\Database\Eloquent\Model $targets
67+
* @param string $class
68+
*
69+
* @return array
70+
*/
71+
public static function detachRelations(Model $model, $relation, $targets, $class)
72+
{
73+
$targets = self::formatTargets($targets, $class);
74+
75+
return $model->{$relation}($targets->classname)->detach($targets->ids);
76+
}
77+
78+
/**
79+
* @param \Illuminate\Database\Eloquent\Model $model
80+
* @param string $relation
81+
* @param array|string|\Illuminate\Database\Eloquent\Model $targets
82+
* @param string $class
83+
*
84+
* @throws \Exception
85+
*
86+
* @return array
87+
*/
88+
public static function toggleRelations(Model $model, $relation, $targets, $class)
89+
{
90+
$targets = self::attachPivotsFromRelation($model->{$relation}(), $targets, $class);
91+
92+
$results = $model->{$relation}($targets->classname)->toggle($targets->targets);
93+
94+
return $results;
95+
}
96+
97+
/**
98+
* @param \Illuminate\Database\Eloquent\Relations\MorphToMany $morph
99+
* @param array|string|\Illuminate\Database\Eloquent\Model $targets
100+
* @param string $class
101+
*
102+
* @throws \Exception
103+
*
104+
* @return \stdClass
105+
*/
106+
public static function attachPivotsFromRelation(MorphToMany $morph, $targets, $class)
107+
{
108+
return self::formatTargets($targets, $class, [
109+
'relation' => self::getRelationTypeFromRelation($morph),
110+
'created_at' => Carbon::now()->format('Y-m-d H:i:s'),
111+
]);
112+
}
113+
114+
/**
115+
* @param array|string|\Illuminate\Database\Eloquent\Model $targets
116+
* @param string $classname
117+
* @param array $update
118+
*
119+
* @return \stdClass
120+
*/
121+
public static function formatTargets($targets, $classname, array $update = [])
122+
{
123+
$result = new stdClass();
124+
$result->classname = $classname;
125+
$result->tableName = null;
126+
127+
if (!is_array($targets)) {
128+
$targets = [$targets];
129+
}
130+
131+
$result->ids = array_map(function ($target) use ($result) {
132+
if ($target instanceof Model) {
133+
$result->classname = get_class($target);
134+
$result->tableName = $target->getTable();
135+
136+
return $target->getKey();
137+
}
138+
139+
return intval($target);
140+
}, $targets);
141+
142+
$result->targets = empty($update) ? $result->ids : array_combine($result->ids, array_pad([], count($result->ids), $update));
143+
144+
return $result;
145+
}
146+
147+
/**
148+
* @param \Illuminate\Database\Eloquent\Relations\MorphToMany $relation
149+
*
150+
* @throws \Exception
151+
*
152+
* @return array
153+
*/
154+
protected static function getRelationTypeFromRelation(MorphToMany $relation)
155+
{
156+
if (!\array_key_exists($relation->getRelationName(), self::RELATION_TYPES)) {
157+
throw new \Exception('Invalid relation definition.');
158+
}
159+
160+
return self::RELATION_TYPES[$relation->getRelationName()];
161+
}
162+
163+
/**
164+
* @param string $field
165+
*
166+
* @return string
167+
*/
168+
protected static function tablePrefixedField($field)
169+
{
170+
return \sprintf('%s.%s', config('follow.followable_table'), $field);
171+
}
172+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace App\Http\Controllers\Api;
4+
5+
use App\Post;
6+
use Illuminate\Http\Request;
7+
use App\Http\Controllers\Controller;
8+
9+
class LikeController extends Controller
10+
{
11+
/**
12+
* @param \Illuminate\Http\Request $request
13+
* @param $id
14+
*
15+
* @return \Illuminate\Http\JsonResponse
16+
*/
17+
public function store(Request $request, $id)
18+
{
19+
$post = Post::findOrFail($id);
20+
21+
$request->user()->toggleLike($post);
22+
23+
return response()->json([
24+
'success' => true,
25+
]);
26+
}
27+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
use Illuminate\Support\Facades\Schema;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Database\Migrations\Migration;
6+
7+
class CreateFollowableTable extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*
12+
* @return void
13+
*/
14+
public function up()
15+
{
16+
Schema::create('followables', function (Blueprint $table) {
17+
$table->unsignedInteger('user_id');
18+
$table->unsignedInteger('followable_id');
19+
$table->string('followable_type')->index();
20+
$table->string('relation')->default('follow')->comment('follow | like');
21+
$table->timestamps();
22+
23+
$table->foreign('user_id')
24+
->on('users')
25+
->references('id')
26+
->onUpdate('cascade')
27+
->onDelete('cascade');
28+
});
29+
}
30+
31+
/**
32+
* Reverse the migrations.
33+
*
34+
* @return void
35+
*/
36+
public function down()
37+
{
38+
Schema::dropIfExists('followable');
39+
}
40+
}

0 commit comments

Comments
 (0)