1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace PHPHub\Repositories\Eloquent; |
4
|
|
|
|
5
|
|
|
use Auth; |
6
|
|
|
use DB; |
7
|
|
|
use Illuminate\Foundation\Bus\DispatchesJobs; |
8
|
|
|
use Illuminate\Pagination\Paginator; |
9
|
|
|
use PHPHub\Events\TopicUpVoted; |
10
|
|
|
use PHPHub\Reply; |
11
|
|
|
use PHPHub\Repositories\Criteria\TopicCriteria; |
12
|
|
|
use PHPHub\Repositories\Eloquent\Traits\IncludeUserTrait; |
13
|
|
|
use PHPHub\Repositories\TopicRepositoryInterface; |
14
|
|
|
use PHPHub\Topic; |
15
|
|
|
use PHPHub\Transformers\IncludeManager\Includable; |
16
|
|
|
use PHPHub\Transformers\IncludeManager\IncludeManager; |
17
|
|
|
use PHPHub\User; |
18
|
|
|
use PHPHub\Vote; |
19
|
|
|
use Prettus\Validator\Contracts\ValidatorInterface; |
20
|
|
|
use ReflectionObject; |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* Class TopicRepositoryEloquent. |
24
|
|
|
*/ |
25
|
|
|
class TopicRepository extends BaseRepository implements TopicRepositoryInterface |
26
|
|
|
{ |
27
|
|
|
use IncludeUserTrait, DispatchesJobs; |
28
|
|
|
|
29
|
|
|
protected $favorite_table = 'favorites'; |
30
|
|
|
protected $attention_table = 'attentions'; |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* Specify Validator Rules. |
34
|
|
|
* |
35
|
|
|
* @var array |
36
|
|
|
*/ |
37
|
|
|
protected $rules = [ |
38
|
|
|
ValidatorInterface::RULE_CREATE => [ |
39
|
|
|
'title' => 'required|min:2', |
40
|
|
|
'body' => 'required|min:2', |
41
|
|
|
'node_id' => 'required|integer|exists:nodes,id', |
42
|
|
|
], |
43
|
|
|
ValidatorInterface::RULE_UPDATE => [ |
44
|
|
|
|
45
|
|
|
], |
46
|
|
|
]; |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* Specify Model class name. |
50
|
|
|
* |
51
|
|
|
* @return string |
52
|
|
|
*/ |
53
|
|
|
public function model() |
54
|
|
|
{ |
55
|
|
|
return Topic::class; |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* 引入帖子最后评论者. |
60
|
|
|
* |
61
|
|
|
* @param $default_columns |
62
|
|
|
*/ |
63
|
|
View Code Duplication |
public function includeLastReplyUser($default_columns) |
|
|
|
|
64
|
|
|
{ |
65
|
|
|
$available_include = Includable::make('last_reply_user') |
66
|
|
|
->setDefaultColumns($default_columns) |
67
|
|
|
->setAllowColumns(Reply::$includable) |
68
|
|
|
->setForeignKey('last_reply_user_id'); |
69
|
|
|
|
70
|
|
|
app(IncludeManager::class)->add($available_include); |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
/** |
74
|
|
|
* 引入帖子所属节点. |
75
|
|
|
* |
76
|
|
|
* @param $default_columns |
77
|
|
|
*/ |
78
|
|
View Code Duplication |
public function includeNode($default_columns) |
|
|
|
|
79
|
|
|
{ |
80
|
|
|
$available_include = Includable::make('node') |
81
|
|
|
->setDefaultColumns($default_columns) |
82
|
|
|
->setAllowColumns(Reply::$includable) |
83
|
|
|
->setForeignKey('node_id'); |
84
|
|
|
|
85
|
|
|
app(IncludeManager::class)->add($available_include); |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
/** |
89
|
|
|
* 引入帖子的评论. |
90
|
|
|
* |
91
|
|
|
* @param $default_columns |
92
|
|
|
*/ |
93
|
|
View Code Duplication |
public function includeReplies($default_columns) |
|
|
|
|
94
|
|
|
{ |
95
|
|
|
$available_include = Includable::make('replies') |
96
|
|
|
->setDefaultColumns($default_columns) |
97
|
|
|
->setAllowColumns(Reply::$includable) |
98
|
|
|
->setLimit(per_page()); |
99
|
|
|
|
100
|
|
|
app(IncludeManager::class)->add($available_include); |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
/** |
104
|
|
|
* 引入帖子每个的评论发布者. |
105
|
|
|
* |
106
|
|
|
* @param $default_columns |
107
|
|
|
*/ |
108
|
|
|
public function includeRepliesUser($default_columns) |
109
|
|
|
{ |
110
|
|
|
$available_include = Includable::make('replies.user') |
111
|
|
|
->setDefaultColumns($default_columns) |
112
|
|
|
->setAllowColumns(User::$includable) |
113
|
|
|
->nested('replies'); |
114
|
|
|
|
115
|
|
|
app(IncludeManager::class)->add($available_include); |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* Boot up the repository, pushing criteria. |
120
|
|
|
*/ |
121
|
|
|
public function boot() |
122
|
|
|
{ |
123
|
|
|
$this->pushCriteria(app(TopicCriteria::class)); |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* 支持帖子. |
128
|
|
|
* |
129
|
|
|
* @param Topic $topic |
130
|
|
|
* |
131
|
|
|
* @return bool |
132
|
|
|
*/ |
133
|
|
|
public function voteUp(Topic $topic) |
134
|
|
|
{ |
135
|
|
View Code Duplication |
if ($this->userUpVoted($topic->id, Auth::id())) { |
|
|
|
|
136
|
|
|
$this->resetVote($topic->id, Auth::id()); |
|
|
|
|
137
|
|
|
$topic->decrement('vote_count', 1); |
|
|
|
|
138
|
|
|
|
139
|
|
|
return false; |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
$vote_count = 0; |
143
|
|
|
|
144
|
|
View Code Duplication |
if ($this->userDownVoted($topic->id, Auth::id())) { |
|
|
|
|
145
|
|
|
$this->resetVote($topic->id, Auth::id()); |
|
|
|
|
146
|
|
|
$vote_count = 1; |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
$topic->votes()->create([ |
150
|
|
|
'is' => 'upvote', |
151
|
|
|
'user_id' => Auth::id(), |
152
|
|
|
]); |
153
|
|
|
|
154
|
|
|
$topic->increment('vote_count', $vote_count + 1); |
|
|
|
|
155
|
|
|
|
156
|
|
|
\Event::fire(new TopicUpVoted($topic, Auth::id())); |
157
|
|
|
|
158
|
|
|
return true; |
159
|
|
|
} |
160
|
|
|
|
161
|
|
|
/** |
162
|
|
|
* 反对帖子. |
163
|
|
|
* |
164
|
|
|
* @param Topic $topic |
165
|
|
|
* |
166
|
|
|
* @return bool |
167
|
|
|
*/ |
168
|
|
|
public function voteDown(Topic $topic) |
169
|
|
|
{ |
170
|
|
View Code Duplication |
if ($this->userDownVoted($topic->id, Auth::id())) { |
|
|
|
|
171
|
|
|
$this->resetVote($topic->id, Auth::id()); |
|
|
|
|
172
|
|
|
$topic->increment('vote_count', 1); |
|
|
|
|
173
|
|
|
|
174
|
|
|
return false; |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
$vote_count = 0; |
178
|
|
|
|
179
|
|
View Code Duplication |
if ($this->userUpVoted($topic->id, Auth::id())) { |
|
|
|
|
180
|
|
|
$this->resetVote($topic->id, Auth::id()); |
|
|
|
|
181
|
|
|
$vote_count = 1; |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
$topic->votes()->create([ |
185
|
|
|
'is' => 'downvote', |
186
|
|
|
'user_id' => Auth::id(), |
187
|
|
|
]); |
188
|
|
|
|
189
|
|
|
$topic->decrement('vote_count', $vote_count + 1); |
|
|
|
|
190
|
|
|
|
191
|
|
|
return true; |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
/** |
195
|
|
|
* 重置投票. |
196
|
|
|
* |
197
|
|
|
* @param $topic_id |
198
|
|
|
* @param $user_id |
199
|
|
|
* |
200
|
|
|
* @return mixed |
201
|
|
|
*/ |
202
|
|
|
protected function resetVote($topic_id, $user_id) |
203
|
|
|
{ |
204
|
|
|
return Vote::query()->where([ |
205
|
|
|
'user_id' => $user_id, |
206
|
|
|
'votable_id' => $topic_id, |
207
|
|
|
'votable_type' => 'Topic', |
208
|
|
|
])->delete(); |
209
|
|
|
} |
210
|
|
|
|
211
|
|
|
/** |
212
|
|
|
* 是否已经支持帖子. |
213
|
|
|
* |
214
|
|
|
* @param $topic_id |
215
|
|
|
* @param $user_id |
216
|
|
|
* |
217
|
|
|
* @return bool |
218
|
|
|
*/ |
219
|
|
View Code Duplication |
public function userUpVoted($topic_id, $user_id) |
|
|
|
|
220
|
|
|
{ |
221
|
|
|
return Vote::query()->where([ |
222
|
|
|
'user_id' => $user_id, |
223
|
|
|
'votable_id' => $topic_id, |
224
|
|
|
'votable_type' => 'Topic', |
225
|
|
|
'is' => 'upvote', |
226
|
|
|
])->exists(); |
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
/** |
230
|
|
|
* 是否已经反对帖子. |
231
|
|
|
* |
232
|
|
|
* @param $topic_id |
233
|
|
|
* @param $user_id |
234
|
|
|
* |
235
|
|
|
* @return bool |
236
|
|
|
*/ |
237
|
|
View Code Duplication |
public function userDownVoted($topic_id, $user_id) |
|
|
|
|
238
|
|
|
{ |
239
|
|
|
return Vote::query()->where([ |
240
|
|
|
'user_id' => $user_id, |
241
|
|
|
'votable_id' => $topic_id, |
242
|
|
|
'votable_type' => 'Topic', |
243
|
|
|
'is' => 'downvote', |
244
|
|
|
])->exists(); |
245
|
|
|
} |
246
|
|
|
|
247
|
|
|
/** |
248
|
|
|
* 用户是否已经收藏帖子. |
249
|
|
|
* |
250
|
|
|
* @param $topic_id |
251
|
|
|
* @param $user_id |
252
|
|
|
* |
253
|
|
|
* @return bool |
254
|
|
|
*/ |
255
|
|
|
public function userFavorite($topic_id, $user_id) |
256
|
|
|
{ |
257
|
|
|
return DB::table($this->favorite_table)->where(compact('topic_id', 'user_id'))->exists(); |
258
|
|
|
} |
259
|
|
|
|
260
|
|
|
/** |
261
|
|
|
* 用户是否已经关注帖子. |
262
|
|
|
* |
263
|
|
|
* @param $topic_id |
264
|
|
|
* @param $user_id |
265
|
|
|
* |
266
|
|
|
* @return bool |
267
|
|
|
*/ |
268
|
|
|
public function userAttention($topic_id, $user_id) |
269
|
|
|
{ |
270
|
|
|
return DB::table($this->attention_table)->where(compact('topic_id', 'user_id'))->exists(); |
271
|
|
|
} |
272
|
|
|
|
273
|
|
|
/** |
274
|
|
|
* 用户收藏的帖子. |
275
|
|
|
* |
276
|
|
|
* @param $user_id |
277
|
|
|
* @param $columns |
278
|
|
|
* |
279
|
|
|
* @return Paginator |
280
|
|
|
*/ |
281
|
|
|
public function favoriteTopicsWithPaginator($user_id, $columns = ['*']) |
282
|
|
|
{ |
283
|
|
|
return $this->getTopicsWithPaginatorBy($this->favorite_table, $user_id, $columns); |
284
|
|
|
} |
285
|
|
|
|
286
|
|
|
/** |
287
|
|
|
* 用户关注的帖子. |
288
|
|
|
* |
289
|
|
|
* @param $user_id |
290
|
|
|
* @param $columns |
291
|
|
|
* |
292
|
|
|
* @return Paginator |
293
|
|
|
*/ |
294
|
|
|
public function attentionTopicsWithPaginator($user_id, $columns = ['*']) |
295
|
|
|
{ |
296
|
|
|
return $this->getTopicsWithPaginatorBy($this->attention_table, $user_id, $columns); |
297
|
|
|
} |
298
|
|
|
|
299
|
|
|
/** |
300
|
|
|
* 通过 attentions 或 favorites 查找帖子. |
301
|
|
|
* |
302
|
|
|
* @param $table |
303
|
|
|
* @param $user_id |
304
|
|
|
* @param $columns |
305
|
|
|
* |
306
|
|
|
* @return Paginator |
307
|
|
|
*/ |
308
|
|
|
public function getTopicsWithPaginatorBy($table, $user_id, $columns = ['*']) |
309
|
|
|
{ |
310
|
|
|
$paginator = DB::table($table) |
311
|
|
|
->orderBy('created_at', 'desc') |
312
|
|
|
->where(compact('user_id')) |
313
|
|
|
->paginate(per_page(), ['topic_id']); |
314
|
|
|
|
315
|
|
|
if ($paginator->count() === 0) { |
316
|
|
|
return $paginator; |
317
|
|
|
} |
318
|
|
|
|
319
|
|
|
$topic_ids = array_pluck($paginator->items(), 'topic_id'); |
320
|
|
|
$topics = $this->whereInAndOrderBy($topic_ids) |
321
|
|
|
->autoWith() |
322
|
|
|
->autoWithRootColumns($columns) |
323
|
|
|
->get(); |
324
|
|
|
|
325
|
|
|
$items = (new ReflectionObject($paginator))->getProperty('items'); |
326
|
|
|
$items->setAccessible(true); |
327
|
|
|
$items->setValue($paginator, $topics); |
328
|
|
|
|
329
|
|
|
return $paginator; |
330
|
|
|
} |
331
|
|
|
|
332
|
|
|
/** |
333
|
|
|
* 添加 node_id 过滤条件. |
334
|
|
|
* |
335
|
|
|
* @param $node_id |
336
|
|
|
* |
337
|
|
|
* @return $this |
338
|
|
|
*/ |
339
|
|
|
public function byNodeId($node_id) |
340
|
|
|
{ |
341
|
|
|
$this->model = $this->model->where(compact('node_id')); |
342
|
|
|
|
343
|
|
|
return $this; |
344
|
|
|
} |
345
|
|
|
|
346
|
|
|
/** |
347
|
|
|
* 添加 user_id 过滤条件. |
348
|
|
|
* |
349
|
|
|
* @param $user_id |
350
|
|
|
* |
351
|
|
|
* @return $this |
352
|
|
|
*/ |
353
|
|
|
public function byUserId($user_id) |
354
|
|
|
{ |
355
|
|
|
$this->model = $this->model->where(compact('user_id')); |
356
|
|
|
|
357
|
|
|
return $this; |
358
|
|
|
} |
359
|
|
|
|
360
|
|
|
/** |
361
|
|
|
* 收藏帖子. |
362
|
|
|
* |
363
|
|
|
* @param $topic_id |
364
|
|
|
* @param $user_id |
365
|
|
|
*/ |
366
|
|
View Code Duplication |
public function favorite($topic_id, $user_id) |
|
|
|
|
367
|
|
|
{ |
368
|
|
|
$topic = new Topic(); |
369
|
|
|
$topic->id = $topic_id; |
|
|
|
|
370
|
|
|
|
371
|
|
|
if ($topic->favoriteBy()->wherePivot('user_id', $user_id)->exists()) { |
372
|
|
|
return; |
373
|
|
|
} |
374
|
|
|
|
375
|
|
|
$topic->favoriteBy()->attach($user_id); |
376
|
|
|
} |
377
|
|
|
|
378
|
|
|
/** |
379
|
|
|
* 取消收藏帖子. |
380
|
|
|
* |
381
|
|
|
* @param $topic_id |
382
|
|
|
* @param $user_id |
383
|
|
|
*/ |
384
|
|
|
public function unFavorite($topic_id, $user_id) |
385
|
|
|
{ |
386
|
|
|
$topic = new Topic(); |
387
|
|
|
$topic->id = $topic_id; |
|
|
|
|
388
|
|
|
$topic->favoriteBy()->detach($user_id); |
389
|
|
|
} |
390
|
|
|
|
391
|
|
|
/** |
392
|
|
|
* 关注帖子. |
393
|
|
|
* |
394
|
|
|
* @param $topic_id |
395
|
|
|
* @param $user_id |
396
|
|
|
*/ |
397
|
|
View Code Duplication |
public function attention($topic_id, $user_id) |
|
|
|
|
398
|
|
|
{ |
399
|
|
|
$topic = new Topic(); |
400
|
|
|
$topic->id = $topic_id; |
|
|
|
|
401
|
|
|
|
402
|
|
|
if ($topic->attentionBy()->wherePivot('user_id', $user_id)->exists()) { |
403
|
|
|
return; |
404
|
|
|
} |
405
|
|
|
|
406
|
|
|
$topic->attentionBy()->attach($user_id); |
407
|
|
|
} |
408
|
|
|
|
409
|
|
|
/** |
410
|
|
|
* 取消关注帖子. |
411
|
|
|
* |
412
|
|
|
* @param $topic_id |
413
|
|
|
* @param $user_id |
414
|
|
|
*/ |
415
|
|
|
public function unAttention($topic_id, $user_id) |
416
|
|
|
{ |
417
|
|
|
$topic = new Topic(); |
418
|
|
|
$topic->id = $topic_id; |
|
|
|
|
419
|
|
|
$topic->attentionBy()->detach($user_id); |
420
|
|
|
} |
421
|
|
|
} |
422
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.