where('status', MemeGenerator::STATUS_COMPLETED)->inRandomOrder()->first(); $meme_media = MemeGenerator::getSuitableMemeMedia($meme, 15); return response()->json([ 'success' => [ 'data' => [ 'init' => [ 'info' => $meme, 'caption' => $meme->caption, 'meme' => $meme_media, 'background' => $meme->background_media, ], ], ], ]); } public function memes(Request $request) { $memes = MemeMedia::where('type', 'video')->where('sub_type', 'overlay')->take('30')->inRandomOrder()->get(); return response()->json([ 'success' => [ 'data' => [ 'memes' => $memes, ], ], ]); } public function background(Request $request) { $backgrounds = BackgroundMedia::where('status', 'completed')->take('30')->inRandomOrder()->get(); return response()->json([ 'success' => [ 'data' => [ 'backgrounds' => $backgrounds, ], ], ]); } public function searchMemes(Request $request) { $query = $request->input('query', ''); $limit = 30; // Track the search if there's a query if (! empty($query)) { try { $trackingService = app(TrackingAnalyticsService::class); $trackingService->trackSearch('meme', $query); } catch (\Exception $e) { // Silently ignore tracking errors } } if (empty($query)) { // Return random memes if no search query $memes = MemeMedia::where('type', 'video')->where('sub_type', 'overlay')->take($limit)->inRandomOrder()->get(); } else { // PostgreSQL full-text search with ranking $memes = MemeMedia::where('type', 'video') ->where('sub_type', 'overlay') ->where(function ($q) use ($query) { // Search in name and description using ILIKE for partial matches $q->where('name', 'ILIKE', "%{$query}%") ->orWhere('description', 'ILIKE', "%{$query}%") // Search in JSON arrays using PostgreSQL JSON operators ->orWhereRaw('keywords::text ILIKE ?', ["%{$query}%"]) ->orWhereRaw('action_keywords::text ILIKE ?', ["%{$query}%"]) ->orWhereRaw('emotion_keywords::text ILIKE ?', ["%{$query}%"]) ->orWhereRaw('misc_keywords::text ILIKE ?', ["%{$query}%"]); }) ->orderByRaw(' CASE WHEN name ILIKE ? THEN 1 WHEN description ILIKE ? THEN 2 WHEN keywords::text ILIKE ? THEN 3 WHEN action_keywords::text ILIKE ? THEN 4 WHEN emotion_keywords::text ILIKE ? THEN 5 WHEN misc_keywords::text ILIKE ? THEN 6 ELSE 7 END, name ASC ', ["%{$query}%", "%{$query}%", "%{$query}%", "%{$query}%", "%{$query}%", "%{$query}%"]) ->take($limit) ->get(); } return response()->json([ 'success' => [ 'data' => [ 'memes' => $memes, 'query' => $query, ], ], ]); } public function searchBackgrounds(Request $request) { $query = $request->input('query', ''); $limit = 30; // Track the search if there's a query if (! empty($query)) { try { $trackingService = app(TrackingAnalyticsService::class); $trackingService->trackSearch('background', $query); } catch (\Exception $e) { // Silently ignore tracking errors } } if (empty($query)) { // Return random backgrounds if no search query $backgrounds = BackgroundMedia::where('status', 'completed')->take($limit)->inRandomOrder()->get(); } else { // Search in prompt field using ILIKE for partial matches $backgrounds = BackgroundMedia::where('status', 'completed') ->where('prompt', 'ILIKE', "%{$query}%") ->orderByRaw(' CASE WHEN prompt ILIKE ? THEN 1 ELSE 2 END, prompt ASC ', ["%{$query}%"]) ->take($limit) ->get(); } return response()->json([ 'success' => [ 'data' => [ 'backgrounds' => $backgrounds, 'query' => $query, ], ], ]); } public function selectMeme(Request $request) { try { $request->validate([ 'meme_ids' => 'required|string', ]); // Decode the hashid to get the actual database ID $memeMediaId = hashids_decode($request->meme_ids); if ($memeMediaId) { // Get the meme media for the name $memeMedia = MemeMedia::find($memeMediaId); if ($memeMedia) { // Track the content selection $trackingService = app(TrackingAnalyticsService::class); $trackingService->trackContentSelection( 'meme', $memeMediaId, $memeMedia->name, 'browse' ); } } } catch (\Exception $e) { // Silently ignore all errors } return response()->json(['success' => true]); } public function selectBackground(Request $request) { try { $request->validate([ 'background_ids' => 'required|string', ]); // Decode the hashid to get the actual database ID $backgroundMediaId = hashids_decode($request->background_ids); if ($backgroundMediaId) { // Get the background media for the name $backgroundMedia = BackgroundMedia::find($backgroundMediaId); if ($backgroundMedia) { // Track the content selection $trackingService = app(TrackingAnalyticsService::class); $trackingService->trackContentSelection( 'background', $backgroundMediaId, $backgroundMedia->prompt ?? 'Background', 'browse' ); } } } catch (\Exception $e) { // Silently ignore all errors } return response()->json(['success' => true]); } public function saveMeme(Request $request) { try { $request->validate([ 'meme_media_ids' => 'nullable|string', 'background_media_ids' => 'nullable|string', 'caption_texts' => 'required|array', 'caption_texts.*' => 'string', 'is_premium_export' => 'boolean', ]); // Convert hashids to actual database IDs $memeMediaId = $request->meme_media_ids ? hashids_decode($request->meme_media_ids) : null; $backgroundMediaId = $request->background_media_ids ? hashids_decode($request->background_media_ids) : null; // Track the save action $trackingService = app(TrackingAnalyticsService::class); $trackingService->trackSave( null, // meme_id $memeMediaId, $backgroundMediaId, $request->caption_texts, $request->is_premium_export ?? false ); } catch (\Exception $e) { // Silently ignore all errors } return response()->json(['success' => true]); } }