"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 '' . "\n"; } ?>