320 lines
9.7 KiB
PHP
320 lines
9.7 KiB
PHP
<?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";
|
|
}
|
|
|
|
?>
|