Display CMS: Footer-Verlauf, Format-Hinweise und Switch-Fixes.
Blendet den B2IN-Text-Verlauf ohne Footer aus, zeigt 9:16-Format-Badges in der Mediathek, normalisiert Modul-Booleans und korrigiert Flux-Switches im Dark Mode. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
6c2da9bdac
commit
7491d20d39
14 changed files with 366 additions and 10 deletions
|
|
@ -12,6 +12,10 @@ class DisplayMedia extends Model
|
|||
/** @use HasFactory<\Database\Factories\DisplayMediaFactory> */
|
||||
use HasFactory;
|
||||
|
||||
private const DISPLAY_TARGET_RATIO = 9 / 16;
|
||||
|
||||
private const DISPLAY_RATIO_TOLERANCE = 0.03;
|
||||
|
||||
protected $table = 'display_media';
|
||||
|
||||
protected $fillable = [
|
||||
|
|
@ -50,13 +54,13 @@ class DisplayMedia extends Model
|
|||
return $this->external_url;
|
||||
}
|
||||
|
||||
return Storage::disk($this->disk)->url($this->path);
|
||||
return Storage::url($this->path);
|
||||
}
|
||||
|
||||
public function getThumbnailUrl(): ?string
|
||||
{
|
||||
if ($this->thumbnail_path) {
|
||||
return Storage::disk($this->disk)->url($this->thumbnail_path);
|
||||
return Storage::url($this->thumbnail_path);
|
||||
}
|
||||
|
||||
if ($this->isUpload() && $this->isImage()) {
|
||||
|
|
@ -66,6 +70,57 @@ class DisplayMedia extends Model
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{status: 'match'|'mismatch'|'unknown', label: string, color: string, description: string}
|
||||
*/
|
||||
public function getDisplayFormatStatus(): array
|
||||
{
|
||||
$dimensions = $this->getDimensions();
|
||||
|
||||
if ($dimensions === null) {
|
||||
return [
|
||||
'status' => 'unknown',
|
||||
'label' => 'Format unbekannt',
|
||||
'color' => 'zinc',
|
||||
'description' => 'Keine Abmessungen gespeichert. Ziel ist 9:16 im Hochformat.',
|
||||
];
|
||||
}
|
||||
|
||||
$ratio = $dimensions['width'] / $dimensions['height'];
|
||||
$matchesTarget = abs($ratio - self::DISPLAY_TARGET_RATIO) <= self::DISPLAY_TARGET_RATIO * self::DISPLAY_RATIO_TOLERANCE;
|
||||
$description = sprintf(
|
||||
'%dx%d px, erkanntes Verhältnis %s. Ziel ist 9:16 im Hochformat.',
|
||||
$dimensions['width'],
|
||||
$dimensions['height'],
|
||||
$this->formatRatio($dimensions['width'], $dimensions['height']),
|
||||
);
|
||||
|
||||
return [
|
||||
'status' => $matchesTarget ? 'match' : 'mismatch',
|
||||
'label' => $matchesTarget ? 'Format passt' : 'Format passt nicht',
|
||||
'color' => $matchesTarget ? 'green' : 'amber',
|
||||
'description' => $description,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{width: int, height: int}|null
|
||||
*/
|
||||
public function getDimensions(): ?array
|
||||
{
|
||||
$width = $this->metadata['width'] ?? null;
|
||||
$height = $this->metadata['height'] ?? null;
|
||||
|
||||
if (! is_numeric($width) || ! is_numeric($height) || (int) $width <= 0 || (int) $height <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
'width' => (int) $width,
|
||||
'height' => (int) $height,
|
||||
];
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// TYPE CHECKS
|
||||
// ========================================
|
||||
|
|
@ -117,6 +172,24 @@ class DisplayMedia extends Model
|
|||
return $this->title ?: $this->filename;
|
||||
}
|
||||
|
||||
private function formatRatio(int $width, int $height): string
|
||||
{
|
||||
$divisor = $this->greatestCommonDivisor($width, $height);
|
||||
|
||||
return ($width / $divisor).':'.($height / $divisor);
|
||||
}
|
||||
|
||||
private function greatestCommonDivisor(int $first, int $second): int
|
||||
{
|
||||
while ($second !== 0) {
|
||||
$remainder = $first % $second;
|
||||
$first = $second;
|
||||
$second = $remainder;
|
||||
}
|
||||
|
||||
return max($first, 1);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// SCOPES
|
||||
// ========================================
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue