feat: add JSON-LD data

This commit is contained in:
2025-07-22 11:34:02 +04:00
parent 60fe5ea9f7
commit d40bd43d7b
6 changed files with 447 additions and 9 deletions
+319
View File
@@ -0,0 +1,319 @@
<?php
/**
* Fonctions pour générer des données structurées JSON-LD
* pour améliorer le SEO et l'affichage dans les moteurs de recherche
*/
/**
* Génère le JSON-LD pour un objet WebSite
*
* @return string JSON-LD pour le site web
*/
function generateWebSiteJsonLd() {
$baseUrl = getBaseUrl();
$data = [
"@context" => "https://schema.org",
"@type" => "WebSite",
"name" => "kaubuntu.re",
"description" => "Plateforme multimédia indépendante du parti panifricaniste et indépendantiste réunionnais Ka-Ubuntu",
"url" => $baseUrl,
"potentialAction" => [
"@type" => "SearchAction",
"target" => [
"@type" => "EntryPoint",
"urlTemplate" => $baseUrl . "/recherche.php?q={search_term_string}"
],
"query-input" => "required name=search_term_string"
],
"publisher" => [
"@type" => "Organization",
"name" => "Ka-Ubuntu",
"url" => $baseUrl,
"logo" => [
"@type" => "ImageObject",
"url" => $baseUrl . "/img/logo.png"
]
]
];
return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
}
/**
* Génère le JSON-LD pour un objet VideoObject
*
* @param array $videoData Données de la vidéo depuis l'API PeerTube
* @param array $video Données formatées de la vidéo
* @return string JSON-LD pour la vidéo
*/
function generateVideoObjectJsonLd($videoData, $video) {
$baseUrl = getBaseUrl();
$videoUrl = $baseUrl . "/video.php?id=" . $video['id'];
// Construire l'URL de la vignette
$thumbnailUrl = isset($videoData['thumbnailPath'])
? PEERTUBE_URL . $videoData['thumbnailPath']
: $baseUrl . "/img/default-thumbnail.jpg";
// Formater la durée en format ISO 8601 (PT1H30M pour 1h30min)
$duration = formatDurationISO8601($video['duration'] ?? 0);
// Construire les données de base
$data = [
"@context" => "https://schema.org",
"@type" => "VideoObject",
"name" => $video['title'],
"description" => !empty($video['description'])
? truncateText(strip_tags($video['description']), 300)
: "Regardez cette vidéo sur kaubuntu.re",
"url" => $videoUrl,
"thumbnailUrl" => $thumbnailUrl,
"uploadDate" => formatDateISO8601($video['date']),
"duration" => $duration,
"publisher" => [
"@type" => "Organization",
"name" => "kaubuntu.re",
"url" => $baseUrl,
"logo" => [
"@type" => "ImageObject",
"url" => $baseUrl . "/img/logo.png"
]
]
];
// Ajouter les informations de la chaîne/créateur
if (!empty($video['channel'])) {
$data["creator"] = [
"@type" => "Person",
"name" => $video['channel'],
"url" => PEERTUBE_URL . "/c/" . ($videoData['channel']['name'] ?? '')
];
}
// Ajouter les statistiques d'interaction
if (isset($video['views']) && $video['views'] > 0) {
$data["interactionStatistic"] = [
"@type" => "InteractionCounter",
"interactionType" => [
"@type" => "WatchAction"
],
"userInteractionCount" => $video['views']
];
}
// Ajouter les likes si disponibles
if (isset($video['likes']) && $video['likes'] > 0) {
if (!isset($data["interactionStatistic"])) {
$data["interactionStatistic"] = [];
} else {
// Convertir en array si c'était un seul élément
if (isset($data["interactionStatistic"]["@type"])) {
$data["interactionStatistic"] = [$data["interactionStatistic"]];
}
}
$data["interactionStatistic"][] = [
"@type" => "InteractionCounter",
"interactionType" => [
"@type" => "LikeAction"
],
"userInteractionCount" => $video['likes']
];
}
// Ajouter les tags/mots-clés si disponibles
if (!empty($video['tags'])) {
$data["keywords"] = implode(", ", $video['tags']);
}
// Ajouter les informations de licence si disponibles
if (isset($videoData['licence']) && !empty($videoData['licence'])) {
$licenceId = $videoData['licence']['id'];
$licenceMapping = [
1 => "https://creativecommons.org/licenses/by/4.0/",
2 => "https://creativecommons.org/licenses/by-sa/4.0/",
3 => "https://creativecommons.org/licenses/by-nd/4.0/",
4 => "https://creativecommons.org/licenses/by-nc/4.0/",
5 => "https://creativecommons.org/licenses/by-nc-sa/4.0/",
6 => "https://creativecommons.org/licenses/by-nc-nd/4.0/",
7 => "https://creativecommons.org/publicdomain/zero/1.0/"
];
if (isset($licenceMapping[$licenceId])) {
$data["license"] = $licenceMapping[$licenceId];
}
}
// Ajouter la catégorie si disponible
if (isset($videoData['category']) && !empty($videoData['category'])) {
$data["genre"] = $videoData['category']['label'] ?? 'Vidéo';
}
// Ajouter les dimensions si c'est un short (format portrait)
if (isset($video['aspectRatio']) && $video['aspectRatio'] <= 1) {
$data["videoFrameSize"] = "Portrait";
}
return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
}
/**
* Génère le JSON-LD pour les fils d'Ariane (BreadcrumbList)
*
* @param array $breadcrumbs Tableau des fils d'Ariane [['name' => 'Nom', 'url' => 'URL']]
* @return string JSON-LD pour les fils d'Ariane
*/
function generateBreadcrumbJsonLd($breadcrumbs) {
$baseUrl = getBaseUrl();
$listItems = [];
foreach ($breadcrumbs as $index => $crumb) {
$listItems[] = [
"@type" => "ListItem",
"position" => $index + 1,
"name" => $crumb['name'],
"item" => $crumb['url']
];
}
$data = [
"@context" => "https://schema.org",
"@type" => "BreadcrumbList",
"itemListElement" => $listItems
];
return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
}
/**
* Génère le JSON-LD pour une page de collection de vidéos
*
* @param string $name Nom de la collection
* @param string $description Description de la collection
* @param array $videos Tableau des vidéos
* @param string $url URL de la page de collection
* @return string JSON-LD pour la collection
*/
function generateVideoCollectionJsonLd($name, $description, $videos, $url) {
$baseUrl = getBaseUrl();
$videoItems = [];
foreach ($videos as $video) {
$videoItems[] = [
"@type" => "VideoObject",
"name" => $video['title'],
"url" => $baseUrl . "/video.php?id=" . $video['id'],
"thumbnailUrl" => $video['thumbnail'],
"uploadDate" => formatDateISO8601($video['date']),
"duration" => formatDurationISO8601($video['duration'] ?? 0)
];
}
$data = [
"@context" => "https://schema.org",
"@type" => "CollectionPage",
"name" => $name,
"description" => $description,
"url" => $url,
"mainEntity" => [
"@type" => "ItemList",
"itemListElement" => $videoItems,
"numberOfItems" => count($videos)
],
"publisher" => [
"@type" => "Organization",
"name" => "kaubuntu.re",
"url" => $baseUrl
]
];
return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
}
/**
* Formate une durée en secondes au format ISO 8601 (PTnHnMnS)
*
* @param int $seconds Durée en secondes
* @return string Durée au format ISO 8601
*/
function formatDurationISO8601($seconds) {
$hours = floor($seconds / 3600);
$minutes = floor(($seconds % 3600) / 60);
$remainingSeconds = $seconds % 60;
$duration = 'PT';
if ($hours > 0) {
$duration .= $hours . 'H';
}
if ($minutes > 0) {
$duration .= $minutes . 'M';
}
if ($remainingSeconds > 0 || ($hours === 0 && $minutes === 0)) {
$duration .= $remainingSeconds . 'S';
}
return $duration;
}
/**
* Formate une date au format ISO 8601
*
* @param string $dateString Date à formater
* @return string Date au format ISO 8601
*/
function formatDateISO8601($dateString) {
try {
$date = new DateTime($dateString);
return $date->format('c'); // Format ISO 8601
} catch (Exception $e) {
// En cas d'erreur, retourner la date actuelle
return (new DateTime())->format('c');
}
}
/**
* Tronque un texte à une longueur donnée
*
* @param string $text Texte à tronquer
* @param int $length Longueur maximale
* @return string Texte tronqué
*/
function truncateText($text, $length = 200) {
if (strlen($text) <= $length) {
return $text;
}
$truncated = substr($text, 0, $length);
$lastSpace = strrpos($truncated, ' ');
if ($lastSpace !== false) {
$truncated = substr($truncated, 0, $lastSpace);
}
return $truncated . '...';
}
/**
* Obtient l'URL de base du site
*
* @return string URL de base
*/
function getBaseUrl() {
$scheme = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'] ?? 'localhost';
return $scheme . '://' . $host;
}
/**
* Génère et affiche un script JSON-LD
*
* @param string $jsonLd Données JSON-LD
*/
function outputJsonLd($jsonLd) {
echo '<script type="application/ld+json">' . "\n" . $jsonLd . "\n" . '</script>' . "\n";
}
?>