This commit is contained in:
ct
2025-06-13 09:44:18 +08:00
parent 8d6e86ebb3
commit 2fd4d42aec
54 changed files with 9917 additions and 184 deletions

View File

@@ -19,6 +19,12 @@ class MediaEngine
public static function getMediaCloudUrl($media)
{
// Check for uploaded_url first (URL-based media)
if (! empty($media->uploaded_url)) {
return $media->uploaded_url;
}
// Fallback to storage disk URL (file-based media)
return Storage::disk($media->disk)->url($media->file_path.$media->file_name);
}
@@ -37,11 +43,31 @@ public static function loadMediaToLocalTemp($uuid)
return $result;
}
$tempPath = 'temp_'.$media->file_name;
// Handle URL-based media
if (! empty($media->uploaded_url)) {
if (! Storage::disk(self::LOCAL_TEMP_DISK)->exists($tempPath)) {
$fileContent = @file_get_contents($media->uploaded_url);
if ($fileContent !== false) {
if (Storage::disk(self::LOCAL_TEMP_DISK)->put($tempPath, $fileContent)) {
$result['temp_path'] = $tempPath;
$result['temp'] = Storage::disk(self::LOCAL_TEMP_DISK)->path($tempPath);
}
}
} else {
$result['temp_path'] = $tempPath;
$result['temp'] = Storage::disk(self::LOCAL_TEMP_DISK)->path($tempPath);
}
return $result;
}
// Handle file-based media (existing behavior)
if (! Storage::disk($media->disk)->exists($media->file_path.$media->file_name)) {
return $result;
}
$tempPath = 'temp_'.$media->file_name;
$fileContent = Storage::disk($media->disk)->get($media->file_path.$media->file_name);
if (! Storage::disk(self::LOCAL_TEMP_DISK)->exists($tempPath)) {
@@ -73,9 +99,31 @@ public static function loadMediasToLocalTemp(array $uuids)
'uuid' => $media->uuid,
'temp_path' => null,
'temp' => null,
'cloud_url' => Storage::disk($media->disk)->url($media->file_path.$media->file_name),
'cloud_url' => self::getMediaCloudUrl($media),
];
// Handle URL-based media
if (! empty($media->uploaded_url)) {
if (Storage::disk(self::LOCAL_TEMP_DISK)->exists($tempPath)) {
// File already exists in temp, just set the paths
$singleResult['temp_path'] = $tempPath;
$singleResult['temp'] = Storage::disk(self::LOCAL_TEMP_DISK)->path($tempPath);
} else {
// File needs to be downloaded to temp
$fileContent = @file_get_contents($media->uploaded_url);
if ($fileContent !== false) {
if (Storage::disk(self::LOCAL_TEMP_DISK)->put($tempPath, $fileContent)) {
$singleResult['temp_path'] = $tempPath;
$singleResult['temp'] = Storage::disk(self::LOCAL_TEMP_DISK)->path($tempPath);
}
}
}
$result[] = $singleResult;
continue;
}
// Handle file-based media (existing behavior)
// Check if file exists in cloud storage
if (! Storage::disk($media->disk)->exists($media->file_path.$media->file_name)) {
$result[] = $singleResult; // Add to results but with null temp paths
@@ -148,11 +196,14 @@ public static function deleteMediasFromLocalTemp(array $uuids)
* 'bgm',
* 'user_upload',
* 'web_app',
* 'background_music.mp3',
* $fileContent,
* $fileContent, // File content or null
* $url, // URL or null
* 'save_file', // Mode: 'save_file'|'download'|'save_url'
* 'background_music.mp3', // Optional - auto-generated if null
* 'r2',
* 'name of file',
* $user_id,
* $mimeType // Optional MIME type
* );
*/
public static function addMedia(
@@ -160,12 +211,14 @@ public static function addMedia(
string $mediaType,
string $mediaSource,
string $mediaProvider,
string $fileName,
string $fileContent,
?string $fileContent = null,
?string $url = null,
?string $mode = 'save_file',
?string $fileName = null,
string $disk = 'r2',
?string $name = null,
?int $userId = null,
?string $mimeType = null
) {
$mediaCollection = MediaCollection::where('key', $mediaCollectionKey)->first();
@@ -175,6 +228,97 @@ public static function addMedia(
$config = config("platform.media.{$mediaCollectionKey}");
// Smart mode detection for backward compatibility
if ($mode === 'save_file') {
// If mode is default but we have URL and no fileContent, switch to save_url for backward compatibility
if (! empty($url) && empty($fileContent)) {
$mode = 'save_url';
}
}
// Validate mode parameter
$validModes = ['save_file', 'download', 'save_url'];
if (! in_array($mode, $validModes)) {
throw new \InvalidArgumentException("Invalid mode '{$mode}'. Valid modes are: ".implode(', ', $validModes));
}
// Validate required parameters based on mode
if ($mode === 'save_file' && empty($fileContent)) {
throw new \InvalidArgumentException("fileContent is required when mode is 'save_file'.");
}
if (($mode === 'download' || $mode === 'save_url') && empty($url)) {
throw new \InvalidArgumentException("url is required when mode is '{$mode}'.");
}
// Auto-generate fileName if not provided
if (empty($fileName)) {
if (! empty($url)) {
// Extract filename from URL
$pathInfo = pathinfo(parse_url($url, PHP_URL_PATH));
$fileName = $pathInfo['basename'] ?? null;
// If no filename in URL, generate one
if (empty($fileName) || $fileName === '/') {
$extension = ! empty($config['extension']) ? $config['extension'] : 'file';
$fileName = $mediaType.'_'.epoch_now_timestamp().'.'.$extension;
}
} else {
// Generate filename for file-based media
$extension = ! empty($config['extension']) ? $config['extension'] : 'file';
$fileName = $mediaType.'_'.epoch_now_timestamp().'.'.$extension;
}
}
// Handle different modes
if ($mode === 'save_url') {
// URL-based media handling - just save URL reference
$adjustedFileName = $config['prefix'].epoch_now_timestamp().'-'.$fileName;
// Auto-detect MIME type from URL if not provided
if (empty($mimeType)) {
$fileDetails = self::getFileDetailsbyUrl($url);
$mimeType = $fileDetails->mimetype;
// Fallback to config mime if detection fails
if (empty($mimeType) || $mimeType === 'application/octet-stream') {
$mimeType = $config['mime'];
}
}
$media = new Media([
'uuid' => Str::uuid(),
'media_collection_id' => $mediaCollection->id,
'user_id' => $userId,
'media_type' => $mediaType,
'media_source' => $mediaSource,
'media_provider' => $mediaProvider,
'mime_type' => $mimeType,
'file_name' => $adjustedFileName,
'file_path' => $config['location'], // Keep for consistency
'disk' => $disk,
'name' => $name,
'uploaded_url' => $url,
]);
$media->save();
return $media;
}
// For 'save_file' and 'download' modes, we need to store file content
if ($mode === 'download') {
// Download content from URL
$fileContent = @file_get_contents($url);
if ($fileContent === false) {
throw new \RuntimeException("Failed to download file from URL: {$url}");
}
}
// File-based media handling (for both 'save_file' and 'download' modes)
if (empty($fileContent)) {
throw new \InvalidArgumentException('fileContent is required for file storage.');
}
// Adjust fileName with prefix, postfix, and ensure extension
$adjustedFileName = $config['prefix'].epoch_now_timestamp().'-'.$fileName;
@@ -189,12 +333,12 @@ public static function addMedia(
}
// Get filetype
$mimeType = null;
$detectedMimeType = null;
$tempFile = tempnam(sys_get_temp_dir(), 'mime_');
try {
file_put_contents($tempFile, $fileContent);
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimeType = finfo_file($finfo, $tempFile);
$detectedMimeType = finfo_file($finfo, $tempFile);
finfo_close($finfo);
} finally {
// This ensures the file is deleted even if an exception occurs
@@ -202,8 +346,8 @@ public static function addMedia(
unlink($tempFile);
}
}
if (is_empty($mimeType)) {
$mimeType = $config['mime'];
if (is_empty($detectedMimeType)) {
$detectedMimeType = $config['mime'];
}
$media = new Media([
@@ -213,11 +357,12 @@ public static function addMedia(
'media_type' => $mediaType,
'media_source' => $mediaSource,
'media_provider' => $mediaProvider,
'mime_type' => $mimeType,
'mime_type' => $detectedMimeType,
'file_name' => $adjustedFileName,
'file_path' => $filePath,
'disk' => $disk,
'name' => $name,
'uploaded_url' => null,
]);
$media->save();

View File

@@ -0,0 +1,833 @@
<?php
/**
* MediaEngine Example Codes - Clean Version
*
* This file contains comprehensive examples of how to use the MediaEngine
* for both URL-based and file-based media handling.
*
* Features:
* - Three modes: 'save_file', 'download', 'save_url'
* - Full backward compatibility
* - Auto-generated filenames (optional)
* - Auto-detected MIME types
* - Smart mode detection
*
* Parameter Order:
* addMedia(mediaCollectionKey, mediaType, mediaSource, mediaProvider,
* fileContent, url, mode, fileName, disk, name, userId, mimeType)
*/
namespace App\Examples;
use App\Helpers\FirstParty\MediaEngine\MediaEngine;
class MediaEngineExampleCodes
{
/**
* ============================================
* MODE-BASED EXAMPLES
* ============================================
*/
/**
* Basic examples showing all three modes
*/
public function basicModeExamples()
{
$userId = 123;
// MODE: 'save_file' (default) - Store file content directly
$fileContent = file_get_contents('/path/to/image.jpg');
$saveFileExample = MediaEngine::addMedia(
'user-i',
'image',
'user_uploaded',
'web_app',
$fileContent, // fileContent provided
null, // url null
'save_file' // mode: save file content to disk
);
// MODE: 'download' - Download from URL and store locally
$downloadExample = MediaEngine::addMedia(
'user-i',
'image',
'user_uploaded',
'web_app',
null, // fileContent null
'https://example.com/image.jpg', // url provided
'download' // mode: download URL and store to disk
);
// MODE: 'save_url' - Just save URL reference (no download)
$saveUrlExample = MediaEngine::addMedia(
'user-i',
'image',
'user_uploaded',
'web_app',
null, // fileContent null
'https://example.com/image.jpg', // url provided
'save_url' // mode: just save URL reference
);
return [$saveFileExample, $downloadExample, $saveUrlExample];
}
/**
* Practical scenarios for each mode
*/
public function practicalModeScenarios()
{
$userId = 456;
// SAVE_URL: Fast external references (CDNs, social media)
$cdnReference = MediaEngine::addMedia(
'user-i',
'image',
'user_uploaded',
'web_app',
null,
'https://cdn.example.com/fast-image.jpg',
'save_url'
);
// DOWNLOAD: Critical content that needs local backup
$criticalDownload = MediaEngine::addMedia(
'user-i',
'document',
'user_uploaded',
'web_app',
null,
'https://external-site.com/important-doc.pdf',
'download'
);
// SAVE_FILE: Direct user uploads
$directUpload = MediaEngine::addMedia(
'user-i',
'image',
'user_uploaded',
'web_app',
file_get_contents($_FILES['upload']['tmp_name'])
);
// AI content that might expire - download for safety
$aiContentBackup = MediaEngine::addMedia(
'user-v',
'video',
'ai_generated',
'runway_ml',
null,
'https://temp-ai-api.com/video_123.mp4',
'download'
);
return [$cdnReference, $criticalDownload, $directUpload, $aiContentBackup];
}
/**
* ============================================
* MINIMAL EXAMPLES
* ============================================
*/
/**
* Absolute minimal calls with smart mode detection
*/
public function minimalExamples()
{
// URL-based - auto-detects to 'save_url'
$urlMinimal = MediaEngine::addMedia(
'user-i',
'image',
'user_uploaded',
'web_app',
null,
'https://example.com/photo.jpg'
);
// File-based - uses default 'save_file'
$fileContent = file_get_contents('/path/to/file.jpg');
$fileMinimal = MediaEngine::addMedia(
'user-i',
'image',
'user_uploaded',
'web_app',
$fileContent
);
// Download - explicit mode required
$downloadMinimal = MediaEngine::addMedia(
'user-i',
'image',
'user_uploaded',
'web_app',
null,
'https://example.com/photo.jpg',
'download'
);
return [$urlMinimal, $fileMinimal, $downloadMinimal];
}
/**
* Clean one-liners for common use cases
*/
public function oneLineExamples()
{
$userId = 999;
// Social media import
$social = MediaEngine::addMedia('user-i', 'image', 'user_uploaded', 'social', null, 'https://instagram.com/photo.jpg');
// AI content generation
$ai = MediaEngine::addMedia('user-v', 'video', 'ai_generated', 'runway', null, 'https://ai-api.com/video.mp4', 'download');
// File upload
$upload = MediaEngine::addMedia('user-a', 'audio', 'user_uploaded', 'web_app', file_get_contents('/tmp/audio.mp3'));
// Background music
$bgm = MediaEngine::addMedia('user-a', 'audio', 'system', 'library', null, 'https://music.com/track.mp3');
return [$social, $ai, $upload, $bgm];
}
/**
* ============================================
* URL-BASED EXAMPLES
* ============================================
*/
/**
* URL examples with save_url mode (reference only)
*/
public function urlReferenceExamples()
{
// Basic URL reference
$imageRef = MediaEngine::addMedia(
'user-i',
'image',
'user_uploaded',
'web_app',
null,
'https://example.com/sunset.jpg',
'save_url'
);
// Video reference with user
$videoRef = MediaEngine::addMedia(
'user-v',
'video',
'user_uploaded',
'web_app',
null,
'https://example.com/vacation.mp4',
'save_url',
null,
'r2',
null,
123
);
// Audio reference
$audioRef = MediaEngine::addMedia(
'user-a',
'audio',
'user_uploaded',
'web_app',
null,
'https://example.com/song.mp3',
'save_url'
);
return [$imageRef, $videoRef, $audioRef];
}
/**
* URL examples with download mode (download and store)
*/
public function urlDownloadExamples()
{
// Download image and store
$downloadedImage = MediaEngine::addMedia(
'user-i',
'image',
'user_uploaded',
'web_app',
null,
'https://example.com/important.jpg',
'download'
);
// Download with custom settings
$customDownload = MediaEngine::addMedia(
'user-i',
'image',
'user_uploaded',
'web_app',
null,
'https://example.com/avatar.jpg',
'download',
'user-avatar.jpg',
'r2',
'User Avatar',
456,
'image/jpeg'
);
return [$downloadedImage, $customDownload];
}
/**
* ============================================
* FILE-BASED EXAMPLES
* ============================================
*/
/**
* File-based examples with auto-generated names
*/
public function fileBasedExamples()
{
// Basic file upload with auto-generated name
$fileContent = file_get_contents('/path/to/image.jpg');
$autoFile = MediaEngine::addMedia(
'user-i',
'image',
'user_uploaded',
'web_app',
$fileContent
);
// File with explicit mode
$explicitFile = MediaEngine::addMedia(
'user-i',
'image',
'user_uploaded',
'web_app',
$fileContent,
null,
'save_file'
);
// File with custom settings
$customFile = MediaEngine::addMedia(
'user-i',
'document',
'user_uploaded',
'web_app',
file_get_contents('/path/to/doc.pdf'),
null,
'save_file',
'important-doc.pdf',
'r2',
'Important Document',
789
);
return [$autoFile, $explicitFile, $customFile];
}
/**
* Laravel file upload handling
*/
public function laravelFileUploadExamples()
{
$userId = 101;
// Basic Laravel upload with original filename
$uploadedFile = request()->file('media');
if ($uploadedFile) {
$fileContent = file_get_contents($uploadedFile->getPathname());
$originalName = MediaEngine::addMedia(
'user-i',
'image',
'user_uploaded',
'web_app',
$fileContent,
null,
'save_file',
$uploadedFile->getClientOriginalName(),
'r2',
null,
$userId
);
}
// Laravel upload with auto-generated filename
$uploadedFile2 = request()->file('another_media');
if ($uploadedFile2) {
$fileContent = file_get_contents($uploadedFile2->getPathname());
$autoName = MediaEngine::addMedia(
'user-i',
'image',
'user_uploaded',
'web_app',
$fileContent,
null,
'save_file',
null,
'r2',
null,
$userId
);
}
return [$originalName ?? null, $autoName ?? null];
}
/**
* ============================================
* REAL-WORLD SCENARIOS
* ============================================
*/
/**
* Social media integration examples
*/
public function socialMediaIntegration()
{
$userId = 202;
// Instagram - save reference (fast)
$instagram = MediaEngine::addMedia(
'user-i',
'image',
'user_uploaded',
'instagram',
null,
'https://instagram.com/photos/abc123.jpg',
'save_url',
null,
'r2',
null,
$userId
);
// YouTube thumbnail - download (reliable)
$youtube = MediaEngine::addMedia(
'user-i',
'image',
'system_uploaded',
'youtube_api',
null,
'https://img.youtube.com/vi/VIDEO_ID/maxresdefault.jpg',
'download'
);
// TikTok - backward compatible
$tiktok = MediaEngine::addMedia(
'user-v',
'video',
'user_uploaded',
'tiktok',
null,
'https://tiktok.com/videos/dance.mp4'
);
return [$instagram, $youtube, $tiktok];
}
/**
* AI-generated content examples
*/
public function aiContentExamples()
{
$userId = 303;
// ElevenLabs voice - save reference
$voice = MediaEngine::addMedia(
'user-a',
'audio',
'ai_generated',
'elevenlabs',
null,
'https://api.elevenlabs.io/voice_sample.mp3'
);
// Runway video - download for backup
$video = MediaEngine::addMedia(
'user-v',
'video',
'ai_generated',
'runway_ml',
null,
'https://api.runwayml.com/video_abc.mp4',
'download',
null,
'r2',
null,
$userId
);
// Midjourney image - save reference
$image = MediaEngine::addMedia(
'user-i',
'image',
'ai_generated',
'midjourney',
null,
'https://cdn.midjourney.com/artwork_def.png',
'save_url',
null,
'r2',
null,
$userId
);
return [$voice, $video, $image];
}
/**
* Enterprise/business scenarios
*/
public function enterpriseExamples()
{
$userId = 404;
// CDN assets - reference only
$cdnAsset = MediaEngine::addMedia(
'user-i',
'image',
'system_uploaded',
'cdn',
null,
'https://cdn.company.com/logo.png',
'save_url'
);
// Important documents - download and backup
$document = MediaEngine::addMedia(
'user-d',
'document',
'user_uploaded',
'web_app',
null,
'https://external-api.com/contract.pdf',
'download',
'contract-2024.pdf',
'r2',
'Business Contract',
$userId
);
// User profile photo - flexible handling
$profile = MediaEngine::addMedia(
'user-i',
'image',
'user_uploaded',
'web_app',
null,
'https://social-login.com/avatar.jpg',
'download',
null,
'r2',
'Profile Photo',
$userId
);
return [$cdnAsset, $document, $profile];
}
/**
* ============================================
* BACKWARD COMPATIBILITY
* ============================================
*/
/**
* Examples showing backward compatibility with auto-detection
*/
public function backwardCompatibilityExamples()
{
// OLD CODE - still works with auto-detection
$oldUrl = MediaEngine::addMedia(
'user-i',
'image',
'user_uploaded',
'web_app',
null,
'https://example.com/photo.jpg' // Auto-detects 'save_url'
);
$oldFile = MediaEngine::addMedia(
'user-i',
'image',
'user_uploaded',
'web_app',
file_get_contents('/path/to/image.jpg') // Uses default 'save_file'
);
// NEW CODE - explicit modes
$newUrlRef = MediaEngine::addMedia(
'user-i',
'image',
'user_uploaded',
'web_app',
null,
'https://example.com/photo.jpg',
'save_url'
);
$newDownload = MediaEngine::addMedia(
'user-i',
'image',
'user_uploaded',
'web_app',
null,
'https://example.com/photo.jpg',
'download'
);
$newFile = MediaEngine::addMedia(
'user-i',
'image',
'user_uploaded',
'web_app',
file_get_contents('/path/to/image.jpg'),
null,
'save_file'
);
return [$oldUrl, $oldFile, $newUrlRef, $newDownload, $newFile];
}
/**
* ============================================
* BULK OPERATIONS
* ============================================
*/
/**
* Bulk processing examples
*/
public function bulkOperationExamples()
{
$userId = 505;
$urls = [
'https://example.com/photo1.jpg',
'https://example.com/photo2.png',
'https://example.com/photo3.gif',
];
$results = [];
// Bulk URL references
foreach ($urls as $url) {
$media = MediaEngine::addMedia(
'user-i',
'image',
'user_uploaded',
'bulk_import',
null,
$url,
'save_url',
null,
'r2',
null,
$userId
);
$results[] = $media;
}
// Bulk downloads with error handling
$downloadResults = [];
foreach ($urls as $url) {
try {
$media = MediaEngine::addMedia(
'user-i',
'image',
'user_uploaded',
'bulk_download',
null,
$url,
'download',
null,
'r2',
null,
$userId
);
$downloadResults[] = $media;
} catch (\Exception $e) {
$downloadResults[] = ['error' => $e->getMessage(), 'url' => $url];
}
}
return [$results, $downloadResults];
}
/**
* ============================================
* ERROR HANDLING
* ============================================
*/
/**
* Comprehensive error handling examples
*/
public function errorHandlingExamples()
{
try {
// Invalid URL
$invalidUrl = MediaEngine::addMedia(
'user-i',
'image',
'user_uploaded',
'web_app',
null,
'https://invalid-domain-12345.com/image.jpg',
'download'
);
} catch (\RuntimeException $e) {
// Handle download failure
$error1 = ['error' => 'Download failed: '.$e->getMessage()];
}
try {
// Invalid collection key
$invalidCollection = MediaEngine::addMedia(
'invalid-collection',
'image',
'user_uploaded',
'web_app',
null,
'https://example.com/image.jpg'
);
} catch (\InvalidArgumentException $e) {
// Handle invalid collection
$error2 = ['error' => 'Invalid collection: '.$e->getMessage()];
}
try {
// Invalid mode
$invalidMode = MediaEngine::addMedia(
'user-i',
'image',
'user_uploaded',
'web_app',
null,
'https://example.com/image.jpg',
'invalid_mode'
);
} catch (\InvalidArgumentException $e) {
// Handle invalid mode
$error3 = ['error' => 'Invalid mode: '.$e->getMessage()];
}
return [$error1 ?? null, $error2 ?? null, $error3 ?? null];
}
/**
* ============================================
* ADVANCED USE CASES
* ============================================
*/
/**
* Advanced scenarios with custom settings
*/
public function advancedExamples()
{
$userId = 606;
// Custom filename and MIME type
$customized = MediaEngine::addMedia(
'user-i',
'image',
'user_uploaded',
'web_app',
null,
'https://example.com/photo.jpg',
'download',
'custom-avatar-2024.jpg',
'r2',
'Profile Avatar',
$userId,
'image/jpeg'
);
// Multiple disk storage
$s3Storage = MediaEngine::addMedia(
'user-v',
'video',
'user_uploaded',
'web_app',
file_get_contents('/path/to/video.mp4'),
null,
'save_file',
'presentation-video.mp4',
's3',
'Presentation Video',
$userId
);
// Complex AI workflow
$aiWorkflow = MediaEngine::addMedia(
'user-a',
'audio',
'ai_generated',
'custom_pipeline',
null,
'https://ai-pipeline.com/processed-audio.wav',
'download',
'processed-voice-'.time().'.wav',
'r2',
'AI Processed Voice',
$userId,
'audio/wav'
);
return [$customized, $s3Storage, $aiWorkflow];
}
/**
* Performance optimization examples
*/
public function performanceExamples()
{
$userId = 707;
// Fast CDN reference (no download overhead)
$fastReference = MediaEngine::addMedia(
'user-i',
'image',
'user_uploaded',
'web_app',
null,
'https://fast-cdn.com/optimized-image.webp',
'save_url'
);
// Strategic download for critical assets
$criticalAsset = MediaEngine::addMedia(
'user-i',
'image',
'system_uploaded',
'web_app',
null,
'https://external-api.com/logo.png',
'download',
'company-logo.png',
'r2',
'Company Logo'
);
// Lazy loading approach
$lazyLoad = MediaEngine::addMedia(
'user-v',
'video',
'user_uploaded',
'web_app',
null,
'https://video-service.com/large-video.mp4',
'save_url',
null,
'r2',
null,
$userId
);
return [$fastReference, $criticalAsset, $lazyLoad];
}
}

View File

@@ -0,0 +1,69 @@
<?php
namespace App\Helpers\FirstParty;
use App\Models\MemeMedia;
use Illuminate\Support\Facades\Http;
class Tester
{
/**
* Test all URLs from MemeMedia model
*/
public static function testAllMemeUrls()
{
$memes = MemeMedia::all();
$results = [];
$validCount = 0;
$invalidCount = 0;
foreach ($memes as $meme) {
dump("Processing {$meme->name}...");
$urls = [
'webm_url' => $meme->webm_url,
'mov_url' => $meme->mov_url,
'gif_url' => $meme->gif_url,
'webp_url' => $meme->webp_url,
];
$urlResults = [];
foreach ($urls as $type => $url) {
try {
$response = Http::timeout(10)->head($url);
$status = $response->status();
$valid = $status === 200;
$urlResults[$type] = [
'url' => $url,
'status' => $status,
'valid' => $valid,
];
$valid ? $validCount++ : $invalidCount++;
} catch (\Exception $e) {
$urlResults[$type] = [
'url' => $url,
'status' => 'ERROR',
'valid' => false,
'error' => $e->getMessage(),
];
$invalidCount++;
}
}
$results[] = [
'id' => $meme->id,
'name' => $meme->name,
'urls' => $urlResults,
];
}
$output = [
'invalid_urls' => $invalidCount,
];
dump($output);
}
}

View File

@@ -1,5 +1,7 @@
<?php
use Vinkla\Hashids\Facades\Hashids;
if (! function_exists('array_to_object_2025')) {
/**
* A magic function that turns all nested array into nested objects. Calling it with no parameter would result in a empty object.
@@ -69,3 +71,23 @@ function array_is_assoc($array): bool
return array_keys($array) !== range(0, count($array) - 1);
}
}
if (! function_exists('hashids_encode')) {
function hashids_encode($id)
{
return Hashids::encode($id);
}
}
if (! function_exists('hashids_decode')) {
function hashids_decode($string)
{
$arr = Hashids::decode($string);
if (count($arr) > 0) {
return $arr[0];
}
return null;
}
}