Files
memefast/app/Http/Controllers/FrontMediaController.php
2025-07-17 14:55:15 +08:00

268 lines
9.0 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Helpers\FirstParty\Meme\MemeGenerator;
use App\Models\BackgroundMedia;
use App\Models\Meme;
use App\Models\MemeMedia;
use App\Services\TrackingAnalyticsService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
class FrontMediaController extends Controller
{
public function init(Request $request)
{
$skipCache = $request->input('sc') == '1';
$cacheKey = 'front_media_init';
if (! $skipCache && Cache::has($cacheKey)) {
return response()->json(Cache::get($cacheKey));
}
$meme = Meme::with('meme_media', 'background_media')->where('status', MemeGenerator::STATUS_COMPLETED)->inRandomOrder()->first();
$meme_media = MemeGenerator::getSuitableMemeMedia($meme, 15);
$response = [
'success' => [
'data' => [
'init' => [
'info' => $meme,
'caption' => $meme->caption,
'meme' => $meme_media,
'background' => $meme->background_media,
],
],
],
];
if (! $skipCache) {
Cache::put($cacheKey, $response, 300); // Cache for 5 minutes
}
return response()->json($response);
}
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]);
}
}