- 134-tool registry with programmatic SEO (unique titles/H1/descriptions, JSON-LD graphs, sitemap index, canonical 301 enforcement via required filter) - DB-backed job queue (SKIP LOCKED) with drivers: Ffmpeg, Images (GD), Pdf (qpdf/gs/poppler), Youtube (thumbnails), Qr (server-side PNG) - Security: SSRF guard, MIME validation, rate limits, API-key auth, bcrypt admin login, security headers - Admin panel: dashboard, tools/categories/guides CRUD, SEO audit, analytics, job inspector with retry, system health, feature flags - Docker deployment (nginx + web/api FPM pools + scalable workers), PHPUnit suite (19 tests / 1139 assertions), PWA manifest + service worker
68 lines
4.8 KiB
PHP
68 lines
4.8 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace App\Libraries;
|
||
|
||
/**
|
||
* Canonical media-format knowledge base.
|
||
*
|
||
* Every converter landing page inherits its copy from here, so
|
||
* /jpg-to-png and /png-to-webp each get accurate, specific prose about
|
||
* their real input/output formats — not interchangeable filler.
|
||
*/
|
||
final class FormatCatalog
|
||
{
|
||
/** @var array<string, array{name:string,family:string,mime:string,blurb:string}> */
|
||
public const FORMATS = [
|
||
// --- video containers -------------------------------------------------
|
||
'mp4' => ['name' => 'MP4', 'family' => 'video', 'mime' => 'video/mp4', 'blurb' => 'the universal video container supported by virtually every device, browser and social platform'],
|
||
'webm' => ['name' => 'WebM', 'family' => 'video', 'mime' => 'video/webm', 'blurb' => 'an open, lightweight format designed for the web and HTML5 video'],
|
||
'mov' => ['name' => 'MOV', 'family' => 'video', 'mime' => 'video/quicktime', 'blurb' => 'Apple\'s QuickTime container, common on iPhones and Mac editing workflows'],
|
||
'mkv' => ['name' => 'MKV', 'family' => 'video', 'mime' => 'video/x-matroska', 'blurb' => 'a flexible open container that holds multiple audio and subtitle tracks'],
|
||
'avi' => ['name' => 'AVI', 'family' => 'video', 'mime' => 'video/x-msvideo', 'blurb' => 'a legacy Windows container still used by older cameras and recorders'],
|
||
'gif' => ['name' => 'GIF', 'family' => 'image', 'mime' => 'image/gif', 'blurb' => 'a looping animation format made of indexed-color frames'],
|
||
|
||
// --- audio -------------------------------------------------------------
|
||
'mp3' => ['name' => 'MP3', 'family' => 'audio', 'mime' => 'audio/mpeg', 'blurb' => 'the most widely compatible lossy audio format — plays literally everywhere'],
|
||
'wav' => ['name' => 'WAV', 'family' => 'audio', 'mime' => 'audio/wav', 'blurb' => 'uncompressed PCM audio prized for editing and maximum fidelity'],
|
||
'm4a' => ['name' => 'M4A', 'family' => 'audio', 'mime' => 'audio/mp4', 'blurb' => 'Apple\'s AAC-based audio format — smaller than MP3 at the same quality'],
|
||
'aac' => ['name' => 'AAC', 'family' => 'audio', 'mime' => 'audio/aac', 'blurb' => 'the successor to MP3 used by YouTube, iOS and streaming services'],
|
||
'flac' => ['name' => 'FLAC', 'family' => 'audio', 'mime' => 'audio/flac', 'blurb' => 'lossless compression that keeps every bit of the original recording'],
|
||
'ogg' => ['name' => 'OGG', 'family' => 'audio', 'mime' => 'audio/ogg', 'blurb' => 'an open-source Vorbis audio container popular with game and web developers'],
|
||
'opus' => ['name' => 'Opus', 'family' => 'audio', 'mime' => 'audio/opus', 'blurb' => 'the modern low-latency codec behind WebRTC and Discord'],
|
||
'wma' => ['name' => 'WMA', 'family' => 'audio', 'mime' => 'audio/x-ms-wma', 'blurb' => 'Microsoft\'s legacy Windows Media Audio format'],
|
||
|
||
// --- images ------------------------------------------------------------
|
||
'jpg' => ['name' => 'JPG', 'family' => 'image', 'mime' => 'image/jpeg', 'blurb' => 'the standard photo format — small files, universally viewable, no transparency'],
|
||
'jpeg' => ['name' => 'JPEG', 'family' => 'image', 'mime' => 'image/jpeg', 'blurb' => 'identical to JPG — the extension spelling differs only'],
|
||
'png' => ['name' => 'PNG', 'family' => 'image', 'mime' => 'image/png', 'blurb' => 'lossless images with crisp edges and full transparency support'],
|
||
'webp' => ['name' => 'WebP', 'family' => 'image', 'mime' => 'image/webp', 'blurb' => 'Google\'s modern image format — typically 25–35% smaller than JPG at similar quality'],
|
||
'avif' => ['name' => 'AVIF', 'family' => 'image', 'mime' => 'image/avif', 'blurb' => 'next-generation AV1-based images offering excellent compression and HDR support'],
|
||
'bmp' => ['name' => 'BMP', 'family' => 'image', 'mime' => 'image/bmp', 'blurb' => 'uncompressed bitmap graphics, mostly seen in legacy Windows software'],
|
||
|
||
// --- documents ----------------------------------------------------------
|
||
'pdf' => ['name' => 'PDF', 'family' => 'document', 'mime' => 'application/pdf', 'blurb' => 'the portable document format that preserves layout everywhere'],
|
||
];
|
||
|
||
public static function name(string $ext): string
|
||
{
|
||
return self::FORMATS[strtolower($ext)]['name'] ?? strtoupper($ext);
|
||
}
|
||
|
||
public static function blurb(string $ext): string
|
||
{
|
||
return self::FORMATS[strtolower($ext)]['blurb'] ?? strtoupper($ext) . ' files';
|
||
}
|
||
|
||
public static function family(string $ext): string
|
||
{
|
||
return self::FORMATS[strtolower($ext)]['family'] ?? 'file';
|
||
}
|
||
|
||
public static function mime(string $ext): string
|
||
{
|
||
return self::FORMATS[strtolower($ext)]['mime'] ?? 'application/octet-stream';
|
||
}
|
||
}
|