Social profiles are maintained once under settings (one HTTPS address per network, SocialProfiles::NETWORKS) and shown by the new `social` block (document schema v23) wherever it stands: size, shape, layout, labels, new tab and an optional subset of networks on the block; colour, hover, spacing and alignment through the free block styles. The addresses also feed sameAs in the structured data. Icons are own outline drawings in the style of the existing icon set. ADR 093. Elektro Bernhard is rebuilt with a dark hero over the team photo, a transparent header that turns white on scroll, Lato, cards with shadows and hover lift, a review slider with six real Google reviews, a dark solar band, page headers on every subpage and staggered entrance effects. Social profiles sit in the top bar and the footer. The site is a second local reference installation next to the Kant-IT pilot (var/elektro-bernhard.db, launch config on port 8088); the seed script rebuilds it from scratch. Checked: PHP suite 492 tests (only the documented old failure remains), 33 JS tests, Twig lint, PHP style, full editor browser check with axe. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
80 lines
3.0 KiB
PHP
80 lines
3.0 KiB
PHP
<?php
|
||
|
||
namespace App\Content;
|
||
|
||
use App\Domain\InvalidPage;
|
||
|
||
/**
|
||
* Die sozialen Profile einer Website.
|
||
*
|
||
* Gepflegt werden sie einmal, in den Einstellungen: je Netzwerk eine Adresse. Der Baustein
|
||
* `social` zeigt sie dann an beliebig vielen Stellen – im Kopf, im Fuß, in einer Kontaktsektion –
|
||
* und bestimmt dort nur noch Größe, Form und Beschriftung. Eine Adresse, die sich ändert, ändert
|
||
* sich damit überall auf einmal; das ist der Unterschied zu von Hand gesetzten Symbol-Links.
|
||
*
|
||
* Die Liste der Netzwerke ist fest, weil jedes ein gezeichnetes Symbol braucht (siehe
|
||
* templates/blocks/social-icon.html.twig). Ein Netzwerk, das hier fehlt, hat kein Symbol – ein
|
||
* freies Feld würde also nur eine leere Fläche erzeugen.
|
||
*/
|
||
final class SocialProfiles
|
||
{
|
||
/** Schlüssel → Name, in der Reihenfolge, in der die Symbole erscheinen. */
|
||
public const NETWORKS = [
|
||
'facebook' => 'Facebook',
|
||
'instagram' => 'Instagram',
|
||
'linkedin' => 'LinkedIn',
|
||
'youtube' => 'YouTube',
|
||
'tiktok' => 'TikTok',
|
||
'x' => 'X',
|
||
'threads' => 'Threads',
|
||
'pinterest' => 'Pinterest',
|
||
'xing' => 'Xing',
|
||
'whatsapp' => 'WhatsApp',
|
||
'google' => 'Google-Unternehmensprofil',
|
||
];
|
||
|
||
/** Beispieladressen für die Eingabefelder. */
|
||
public const PLACEHOLDERS = [
|
||
'facebook' => 'https://www.facebook.com/…',
|
||
'instagram' => 'https://www.instagram.com/…',
|
||
'linkedin' => 'https://www.linkedin.com/company/…',
|
||
'youtube' => 'https://www.youtube.com/@…',
|
||
'tiktok' => 'https://www.tiktok.com/@…',
|
||
'x' => 'https://x.com/…',
|
||
'threads' => 'https://www.threads.net/@…',
|
||
'pinterest' => 'https://www.pinterest.de/…',
|
||
'xing' => 'https://www.xing.com/pages/…',
|
||
'whatsapp' => 'https://wa.me/49…',
|
||
'google' => 'https://g.page/…',
|
||
];
|
||
|
||
public const SHAPES = ['plain' => 'Nur Symbol', 'circle' => 'Runde Fläche', 'square' => 'Eckige Fläche'];
|
||
public const LAYOUTS = ['horizontal' => 'Nebeneinander', 'vertical' => 'Untereinander'];
|
||
|
||
/**
|
||
* Prüft die Eingabe der Einstellungen und gibt nur gefüllte, gültige Adressen zurück.
|
||
*
|
||
* @param mixed $input das Feld `social` des Formulars: Netzwerk → Adresse
|
||
*
|
||
* @return array<string, string>
|
||
*
|
||
* @throws InvalidPage
|
||
*/
|
||
public static function clean(mixed $input): array
|
||
{
|
||
$profiles = [];
|
||
foreach (self::NETWORKS as $key => $label) {
|
||
$url = trim((string) (is_array($input) ? ($input[$key] ?? '') : ''));
|
||
if ('' === $url) {
|
||
continue;
|
||
}
|
||
if (strlen($url) > 400 || !str_starts_with($url, 'https://') || false === filter_var($url, FILTER_VALIDATE_URL) || 1 === preg_match('/[\s"<>\\\\]/', $url)) {
|
||
throw new InvalidPage(sprintf('Die Adresse für %s muss mit https:// beginnen und eine gültige Adresse sein.', $label));
|
||
}
|
||
$profiles[$key] = $url;
|
||
}
|
||
|
||
return $profiles;
|
||
}
|
||
}
|