FollowerService.php 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. <?php
  2. namespace App\Services;
  3. use Illuminate\Support\Facades\Redis;
  4. use App\{
  5. Follower,
  6. Profile
  7. };
  8. class FollowerService {
  9. protected $profile;
  10. public static $follower_prefix = 'px:profile:followers-v1.3:';
  11. public static $following_prefix = 'px:profile:following-v1.3:';
  12. public static function build()
  13. {
  14. return new self();
  15. }
  16. public function profile(Profile $profile)
  17. {
  18. $this->profile = $profile;
  19. self::$follower_prefix .= $profile->id;
  20. self::$following_prefix .= $profile->id;
  21. return $this;
  22. }
  23. public function followers($limit = 100, $offset = 1)
  24. {
  25. if(Redis::zcard(self::$follower_prefix) == 0) {
  26. $followers = $this->profile->followers()->pluck('profile_id');
  27. $followers->map(function($i) {
  28. Redis::zadd(self::$follower_prefix, $i, $i);
  29. });
  30. return Redis::zrevrange(self::$follower_prefix, $offset, $limit);
  31. } else {
  32. return Redis::zrevrange(self::$follower_prefix, $offset, $limit);
  33. }
  34. }
  35. public function following($limit = 100, $offset = 1)
  36. {
  37. if(Redis::zcard(self::$following_prefix) == 0) {
  38. $following = $this->profile->following()->pluck('following_id');
  39. $following->map(function($i) {
  40. Redis::zadd(self::$following_prefix, $i, $i);
  41. });
  42. return Redis::zrevrange(self::$following_prefix, $offset, $limit);
  43. } else {
  44. return Redis::zrevrange(self::$following_prefix, $offset, $limit);
  45. }
  46. }
  47. public static function follows(string $actor, string $target)
  48. {
  49. $key = self::$follower_prefix . $target;
  50. if(Redis::zcard($key) == 0) {
  51. $p = Profile::findOrFail($target);
  52. self::build()->profile($p)->followers(1);
  53. self::build()->profile($p)->following(1);
  54. return (bool) Redis::zrank($key, $actor);
  55. } else {
  56. return (bool) Redis::zrank($key, $actor);
  57. }
  58. }
  59. }