SearchController.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <?php
  2. namespace App\Http\Controllers;
  3. use Auth;
  4. use App\Hashtag;
  5. use App\Profile;
  6. use App\Status;
  7. use Illuminate\Http\Request;
  8. use App\Util\ActivityPub\Helpers;
  9. use Illuminate\Support\Facades\Cache;
  10. use App\Transformer\Api\{
  11. AccountTransformer,
  12. HashtagTransformer,
  13. StatusTransformer,
  14. };
  15. class SearchController extends Controller
  16. {
  17. public function __construct()
  18. {
  19. $this->middleware('auth');
  20. }
  21. public function searchAPI(Request $request, $tag)
  22. {
  23. if(mb_strlen($tag) < 3) {
  24. return;
  25. }
  26. $tag = e(urldecode($tag));
  27. $hash = hash('sha256', $tag);
  28. $tokens = Cache::remember('api:search:tag:'.$hash, now()->addMinutes(5), function () use ($tag) {
  29. $tokens = [];
  30. if(Helpers::validateUrl($tag) != false && config('pixelfed.activitypub_enabled') == true) {
  31. $remote = Helpers::fetchFromUrl($tag);
  32. if(isset($remote['type']) && in_array($remote['type'], ['Create', 'Person']) == true) {
  33. $type = $remote['type'];
  34. if($type == 'Person') {
  35. $item = Helpers::profileFirstOrNew($tag);
  36. $tokens['profiles'] = [[
  37. 'count' => 1,
  38. 'url' => $item->url(),
  39. 'type' => 'profile',
  40. 'value' => $item->username,
  41. 'tokens' => [$item->username],
  42. 'name' => $item->name,
  43. 'entity' => [
  44. 'id' => $item->id,
  45. 'following' => $item->followedBy(Auth::user()->profile),
  46. 'thumb' => $item->avatarUrl()
  47. ]
  48. ]];
  49. } else if ($type == 'Create') {
  50. $item = Helpers::statusFirstOrFetch($tag, false);
  51. $tokens['posts'] = [[
  52. 'count' => 0,
  53. 'url' => $item->url(),
  54. 'type' => 'status',
  55. 'value' => "by {$item->profile->username} <span class='float-right'>{$item->created_at->diffForHumans(null, true, true)}</span>",
  56. 'tokens' => [$item->caption],
  57. 'name' => $item->caption,
  58. 'thumb' => $item->thumb(),
  59. ]];
  60. }
  61. }
  62. }
  63. $hashtags = Hashtag::select('id', 'name', 'slug')->where('slug', 'like', '%'.$tag.'%')->whereHas('posts')->limit(20)->get();
  64. if($hashtags->count() > 0) {
  65. $tags = $hashtags->map(function ($item, $key) {
  66. return [
  67. 'count' => $item->posts()->count(),
  68. 'url' => $item->url(),
  69. 'type' => 'hashtag',
  70. 'value' => $item->name,
  71. 'tokens' => '',
  72. 'name' => null,
  73. ];
  74. });
  75. $tokens['hashtags'] = $tags;
  76. }
  77. return $tokens;
  78. });
  79. $users = Profile::select('username', 'name', 'id')
  80. ->whereNull('status')
  81. ->where('id', '!=', Auth::user()->profile->id)
  82. ->where('username', 'like', '%'.$tag.'%')
  83. ->whereNull('domain')
  84. //->orWhere('remote_url', $tag)
  85. ->limit(20)
  86. ->get();
  87. if($users->count() > 0) {
  88. $profiles = $users->map(function ($item, $key) {
  89. return [
  90. 'count' => 0,
  91. 'url' => $item->url(),
  92. 'type' => 'profile',
  93. 'value' => $item->username,
  94. 'tokens' => [$item->username],
  95. 'name' => $item->name,
  96. 'avatar' => $item->avatarUrl(),
  97. 'id' => $item->id,
  98. 'entity' => [
  99. 'id' => $item->id,
  100. 'following' => $item->followedBy(Auth::user()->profile),
  101. 'thumb' => $item->avatarUrl()
  102. ]
  103. ];
  104. });
  105. if(isset($tokens['profiles'])) {
  106. array_push($tokens['profiles'], $profiles);
  107. } else {
  108. $tokens['profiles'] = $profiles;
  109. }
  110. }
  111. $posts = Status::select('id', 'profile_id', 'caption', 'created_at')
  112. ->whereHas('media')
  113. ->whereNull('in_reply_to_id')
  114. ->whereNull('reblog_of_id')
  115. ->whereProfileId(Auth::user()->profile->id)
  116. ->where('caption', 'like', '%'.$tag.'%')
  117. ->orWhere('uri', $tag)
  118. ->latest()
  119. ->limit(10)
  120. ->get();
  121. if($posts->count() > 0) {
  122. $posts = $posts->map(function($item, $key) {
  123. return [
  124. 'count' => 0,
  125. 'url' => $item->url(),
  126. 'type' => 'status',
  127. 'value' => "by {$item->profile->username} <span class='float-right'>{$item->created_at->diffForHumans(null, true, true)}</span>",
  128. 'tokens' => [$item->caption],
  129. 'name' => $item->caption,
  130. 'thumb' => $item->thumb(),
  131. ];
  132. });
  133. $tokens['posts'] = $posts;
  134. }
  135. return response()->json($tokens);
  136. }
  137. public function results(Request $request)
  138. {
  139. $this->validate($request, [
  140. 'q' => 'required|string|min:1',
  141. ]);
  142. return view('search.results');
  143. }
  144. }