SeasonalController.php 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. <?php
  2. namespace App\Http\Controllers;
  3. use Illuminate\Http\Request;
  4. use Auth;
  5. use App\AccountLog;
  6. use App\Follower;
  7. use App\Like;
  8. use App\Status;
  9. use App\StatusHashtag;
  10. use Illuminate\Support\Facades\Cache;
  11. class SeasonalController extends Controller
  12. {
  13. public function __construct()
  14. {
  15. $this->middleware('auth');
  16. }
  17. public function yearInReview()
  18. {
  19. abort_if(now()->gt('2021-03-01 00:00:00'), 404);
  20. abort_if(config('database.default') != 'mysql', 404);
  21. $profile = Auth::user()->profile;
  22. return view('account.yir', compact('profile'));
  23. }
  24. public function getData(Request $request)
  25. {
  26. abort_if(now()->gt('2021-03-01 00:00:00'), 404);
  27. abort_if(config('database.default') != 'mysql', 404);
  28. $uid = $request->user()->id;
  29. $pid = $request->user()->profile_id;
  30. $epoch = '2020-01-01 00:00:00';
  31. $epochStart = '2020-01-01 00:00:00';
  32. $epochEnd = '2020-12-31 23:59:59';
  33. $siteKey = 'seasonal:my2020:shared';
  34. $siteTtl = now()->addMonths(3);
  35. $userKey = 'seasonal:my2020:user:' . $uid;
  36. $userTtl = now()->addMonths(3);
  37. $shared = Cache::remember($siteKey, $siteTtl, function() use($epochStart, $epochEnd) {
  38. return [
  39. 'average' => [
  40. 'posts' => round(Status::selectRaw('*, count(profile_id) as count')
  41. ->whereNull('uri')
  42. ->whereIn('type', ['photo','photo:album','video','video:album','photo:video:album'])
  43. ->where('created_at', '>', $epochStart)
  44. ->where('created_at', '<', $epochEnd)
  45. ->groupBy('profile_id')
  46. ->pluck('count')
  47. ->avg()),
  48. 'likes' => round(Like::selectRaw('*, count(profile_id) as count')
  49. ->where('created_at', '>', $epochStart)
  50. ->where('created_at', '<', $epochEnd)
  51. ->groupBy('profile_id')
  52. ->pluck('count')
  53. ->avg()),
  54. ],
  55. 'popular' => [
  56. 'hashtag' => StatusHashtag::selectRaw('*,count(hashtag_id) as count')
  57. ->where('created_at', '>', $epochStart)
  58. ->where('created_at', '<', $epochEnd)
  59. ->groupBy('hashtag_id')
  60. ->orderByDesc('count')
  61. ->take(1)
  62. ->get()
  63. ->map(function($sh) {
  64. return [
  65. 'name' => $sh->hashtag->name,
  66. 'count' => $sh->count
  67. ];
  68. })
  69. ->first(),
  70. 'post' => Status::whereScope('public')
  71. ->where('likes_count', '>', 1)
  72. ->whereIsNsfw(false)
  73. ->where('created_at', '>', $epochStart)
  74. ->where('created_at', '<', $epochEnd)
  75. ->orderByDesc('likes_count')
  76. ->take(1)
  77. ->get()
  78. ->map(function($status) {
  79. return [
  80. 'id' => (string) $status->id,
  81. 'username' => (string) $status->profile->username,
  82. 'created_at' => $status->created_at->format('M d, Y'),
  83. 'type' => $status->type,
  84. 'url' => $status->url(),
  85. 'thumb' => $status->thumb(),
  86. 'likes_count' => $status->likes_count,
  87. 'reblogs_count' => $status->reblogs_count,
  88. 'reply_count' => $status->reply_count ?? 0,
  89. ];
  90. })
  91. ->first(),
  92. 'places' => Status::selectRaw('*, count(place_id) as count')
  93. ->whereNotNull('place_id')
  94. ->having('count', '>', 1)
  95. ->where('created_at', '>', $epochStart)
  96. ->where('created_at', '<', $epochEnd)
  97. ->groupBy('place_id')
  98. ->orderByDesc('count')
  99. ->take(1)
  100. ->get()
  101. ->map(function($sh) {
  102. return [
  103. 'name' => $sh->place->getName(),
  104. 'url' => $sh->place->url(),
  105. 'count' => $sh->count
  106. ];
  107. })
  108. ->first()
  109. ],
  110. ];
  111. });
  112. $res = Cache::remember($userKey, $userTtl, function() use($uid, $pid, $epochStart, $epochEnd, $request) {
  113. return [
  114. 'account' => [
  115. 'user_id' => $request->user()->id,
  116. 'created_at' => $request->user()->created_at->format('M d, Y'),
  117. 'created_this_year' => $request->user()->created_at->gt('2020-01-01 00:00:00'),
  118. 'created_months_ago' => $request->user()->created_at->diffInMonths(now()),
  119. 'followers_this_year' => Follower::whereFollowingId($pid)
  120. ->where('created_at', '>', $epochStart)
  121. ->where('created_at', '<', $epochEnd)
  122. ->count(),
  123. 'followed_this_year' => Follower::whereProfileId($pid)
  124. ->where('created_at', '>', $epochStart)
  125. ->where('created_at', '<', $epochEnd)
  126. ->count(),
  127. 'most_popular' => Status::whereProfileId($pid)
  128. ->where('likes_count', '>', 1)
  129. ->where('created_at', '>', $epochStart)
  130. ->where('created_at', '<', $epochEnd)
  131. ->orderByDesc('likes_count')
  132. ->take(1)
  133. ->get()
  134. ->map(function($status) {
  135. return [
  136. 'id' => (string) $status->id,
  137. 'username' => (string) $status->profile->username,
  138. 'created_at' => $status->created_at->format('M d, Y'),
  139. 'type' => $status->type,
  140. 'url' => $status->url(),
  141. 'thumb' => $status->thumb(),
  142. 'likes_count' => $status->likes_count,
  143. 'reblogs_count' => $status->reblogs_count,
  144. 'reply_count' => $status->reply_count ?? 0,
  145. ];
  146. })
  147. ->first(),
  148. 'posts_count' => Status::whereProfileId($pid)
  149. ->whereIn('type', ['photo','photo:album','video','video:album','photo:video:album'])
  150. ->where('created_at', '>', $epochStart)
  151. ->where('created_at', '<', $epochEnd)
  152. ->count(),
  153. 'likes_count' => Like::whereProfileId($pid)
  154. ->where('created_at', '>', $epochStart)
  155. ->where('created_at', '<', $epochEnd)
  156. ->count(),
  157. 'hashtag' => StatusHashtag::selectRaw('*, count(hashtag_id) as count')
  158. ->whereProfileId($pid)
  159. ->where('created_at', '>', $epochStart)
  160. ->where('created_at', '<', $epochEnd)
  161. ->groupBy('profile_id')
  162. ->orderByDesc('count')
  163. ->take(1)
  164. ->get()
  165. ->map(function($sh) {
  166. return [
  167. 'name' => $sh->hashtag->name,
  168. 'count' => $sh->count
  169. ];
  170. })
  171. ->first(),
  172. 'places' => Status::selectRaw('*, count(place_id) as count')
  173. ->whereNotNull('place_id')
  174. ->having('count', '>', 1)
  175. ->whereProfileId($pid)
  176. ->where('created_at', '>', $epochStart)
  177. ->where('created_at', '<', $epochEnd)
  178. ->groupBy('place_id')
  179. ->orderByDesc('count')
  180. ->take(1)
  181. ->get()
  182. ->map(function($sh) {
  183. return [
  184. 'name' => $sh->place->getName(),
  185. 'url' => $sh->place->url(),
  186. 'count' => $sh->count
  187. ];
  188. })
  189. ->first(),
  190. 'places_total' => Status::whereProfileId($pid)
  191. ->where('created_at', '>', $epochStart)
  192. ->where('created_at', '<', $epochEnd)
  193. ->whereNotNull('place_id')
  194. ->count()
  195. ]
  196. ];
  197. });
  198. return response()->json(array_merge($res, $shared));
  199. }
  200. public function store(Request $request)
  201. {
  202. abort_if(now()->gt('2021-03-01 00:00:00'), 404);
  203. abort_if(config('database.default') != 'mysql', 404);
  204. $user = $request->user();
  205. $log = AccountLog::firstOrCreate([
  206. [
  207. 'item_type' => 'App\User',
  208. 'item_id' => $user->id,
  209. 'user_id' => $user->id,
  210. 'action' => 'seasonal.my2020.view'
  211. ],
  212. [
  213. 'ip_address' => $request->ip(),
  214. 'user_agent' => $request->userAgent()
  215. ]
  216. ]);
  217. return response()->json(200);
  218. }
  219. }