Initial commit
This commit is contained in:
447
inc/single-helpers.php
Normal file
447
inc/single-helpers.php
Normal file
@@ -0,0 +1,447 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Format a Pods datetime string (e.g. "2026-01-17 00:00:00") into natural French/English.
|
||||
* Shows time only if not midnight.
|
||||
*/
|
||||
function thalim_format_date($raw, $lang = 'fr') {
|
||||
if (!$raw || str_starts_with($raw, '0000-00-00')) return '';
|
||||
$ts = strtotime($raw);
|
||||
if ($ts === false || $ts < 0) return '';
|
||||
return date_i18n('j F Y', $ts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve all Pods custom fields for a single post into a display-ready array.
|
||||
*/
|
||||
function thalim_get_single_data($post_id) {
|
||||
$lang = thalim_current_language();
|
||||
|
||||
$data = [
|
||||
// Text fields
|
||||
'sous_titre' => thalim_bilingual( get_post_meta($post_id, 'sous-titre', true) ?: '', $lang ),
|
||||
'reference_bibliographique' => get_post_meta($post_id, 'reference_bibliographique', true) ?: '',
|
||||
'editeur' => get_post_meta($post_id, 'editeur', true) ?: '',
|
||||
'journal' => get_post_meta($post_id, 'journal', true) ?: '',
|
||||
'lieu' => thalim_bilingual( get_post_meta($post_id, 'lieu', true) ?: '', $lang ),
|
||||
'adresse' => get_post_meta($post_id, 'adresse', true) ?: '',
|
||||
'autrepersonnes' => get_post_meta($post_id, 'autrepersonnes', true) ?: '',
|
||||
'autre_autrepersonnes' => get_post_meta($post_id, 'autre_autrepersonnes', true) ?: '',
|
||||
'body_en' => apply_filters( 'the_content', get_post_meta($post_id, 'body_en', true) ?: '' ),
|
||||
|
||||
// Dates (formatted for display)
|
||||
'datetime' => thalim_format_date(get_post_meta($post_id, 'datetime', true), $lang),
|
||||
'date_de_debut' => '',
|
||||
'date_de_fin' => '',
|
||||
'date_debut_ymd' => '',
|
||||
'date_fin_ymd' => '',
|
||||
'heure_de_debut' => substr( get_post_meta($post_id, 'heure_de_debut', true) ?: '', 0, 5 ),
|
||||
'heure_de_fin' => substr( get_post_meta($post_id, 'heure_de_fin', true) ?: '', 0, 5 ),
|
||||
|
||||
// URLs
|
||||
'hal_url' => get_post_meta($post_id, 'hal_url', true) ?: '',
|
||||
'hal_file' => get_post_meta($post_id, 'hal_file', true) ?: '',
|
||||
'canal_u' => array_values( array_filter( array_map( function( $url ) {
|
||||
if ( preg_match( '/(\d+)\/?$/', trim( $url ), $m ) ) {
|
||||
return 'https://www.canal-u.tv/embed/' . $m[1] . '?t=0';
|
||||
}
|
||||
return '';
|
||||
}, get_post_meta( $post_id, 'lien_canal_u', false ) ) ) ),
|
||||
'youtube' => array_values( array_filter( array_map( function( $url ) {
|
||||
$url = trim( $url );
|
||||
// youtu.be/ID or youtube.com/embed/ID or youtube.com/watch?v=ID
|
||||
if ( preg_match( '/(?:youtu\.be\/|youtube\.com\/(?:embed\/|watch\?.*v=|shorts\/))([A-Za-z0-9_-]{11})/', $url, $m ) ) {
|
||||
return 'https://www.youtube-nocookie.com/embed/' . $m[1];
|
||||
}
|
||||
return '';
|
||||
}, get_post_meta( $post_id, 'lien_youtube', false ) ) ) ),
|
||||
|
||||
// Resolved below
|
||||
'liens_externes' => [],
|
||||
'membres' => [],
|
||||
'autre_membres' => [],
|
||||
'autre_fonction_label' => '',
|
||||
'axes' => [],
|
||||
'etiquettes' => [],
|
||||
'programmes' => [],
|
||||
'annonces_liees' => [],
|
||||
'seances_a_venir' => [],
|
||||
'seances_passees' => [],
|
||||
'show_image_titles' => (bool) get_post_meta($post_id, 'afficher_le_titre_des_images_en_legende', true),
|
||||
'images' => [],
|
||||
'documents' => [],
|
||||
'type_label' => '',
|
||||
'fonction_label' => '',
|
||||
'parent_slug' => '',
|
||||
'parent_name' => '',
|
||||
'parent_link' => '',
|
||||
'category_name' => '',
|
||||
'category_link' => '',
|
||||
];
|
||||
|
||||
// --- Dates ---
|
||||
$raw_debut = get_post_meta($post_id, 'date_de_debut', true);
|
||||
$raw_fin = get_post_meta($post_id, 'date_de_fin', true);
|
||||
$ts_debut = ($raw_debut && !str_starts_with($raw_debut, '0000-00-00')) ? strtotime($raw_debut) : 0;
|
||||
$ts_fin = ($raw_fin && !str_starts_with($raw_fin, '0000-00-00')) ? strtotime($raw_fin) : 0;
|
||||
|
||||
$data['date_de_debut'] = thalim_format_date($raw_debut, $lang);
|
||||
$data['date_de_fin'] = thalim_format_date($raw_fin, $lang);
|
||||
if ($ts_debut) $data['date_debut_ymd'] = date('Y-m-d', $ts_debut);
|
||||
if ($ts_fin) $data['date_fin_ymd'] = date('Y-m-d', $ts_fin);
|
||||
|
||||
// --- External links (up to 3) ---
|
||||
for ($i = 1; $i <= 3; $i++) {
|
||||
$url = get_post_meta($post_id, 'lien_externe_' . $i, true);
|
||||
if ($url) {
|
||||
$titre = thalim_bilingual( get_post_meta($post_id, 'titre_du_lien_externe_' . $i, true) ?: '', $lang );
|
||||
if (!$titre) {
|
||||
$host = parse_url($url, PHP_URL_HOST) ?: $url;
|
||||
$parts = explode('.', $host);
|
||||
$titre = count($parts) >= 2 ? implode('.', array_slice($parts, -2)) : $host;
|
||||
}
|
||||
$data['liens_externes'][] = [
|
||||
'url' => $url,
|
||||
'titre' => $titre,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// --- Category hierarchy for breadcrumb and color ---
|
||||
$categories = wp_get_post_categories($post_id, ['fields' => 'all']);
|
||||
$excluded_ids = [12, 31];
|
||||
foreach ($categories as $cat) {
|
||||
if (in_array($cat->term_id, $excluded_ids)) continue;
|
||||
$ancestor_ids = get_ancestors($cat->term_id, 'category');
|
||||
if (!empty($ancestor_ids)) {
|
||||
$root = get_category(end($ancestor_ids));
|
||||
$data['parent_slug'] = $root->slug;
|
||||
$data['parent_name'] = $root->name;
|
||||
$data['parent_link'] = get_category_link($root->term_id);
|
||||
$data['category_name'] = $cat->name;
|
||||
} else {
|
||||
$data['parent_slug'] = $cat->slug;
|
||||
$data['parent_name'] = $cat->name;
|
||||
$data['parent_link'] = get_category_link($cat->term_id);
|
||||
$data['category_name'] = $lang === 'en' ? 'Other' : 'Autre';
|
||||
}
|
||||
// category_link: for direct posts (no ancestors), point to the /autres index
|
||||
$data['category_link'] = empty($ancestor_ids)
|
||||
? trailingslashit(get_category_link($cat->term_id)) . 'autres/'
|
||||
: get_category_link($cat->term_id);
|
||||
break;
|
||||
}
|
||||
|
||||
// --- Documents joints: split images vs files ---
|
||||
$doc_ids = get_post_meta($post_id, 'documents_joints', false);
|
||||
foreach ($doc_ids as $doc_id) {
|
||||
$mime = get_post_mime_type($doc_id);
|
||||
if (!$mime) continue;
|
||||
if (str_starts_with($mime, 'image/')) {
|
||||
$src = wp_get_attachment_image_url($doc_id, 'large');
|
||||
if ($src) {
|
||||
$meta = wp_get_attachment_metadata($doc_id);
|
||||
$w = isset($meta['width']) ? $meta['width'] : 0;
|
||||
$h = isset($meta['height']) ? $meta['height'] : 0;
|
||||
$data['images'][] = [
|
||||
'url' => $src,
|
||||
'alt' => get_post_meta($doc_id, '_wp_attachment_image_alt', true) ?: '',
|
||||
'caption' => thalim_bilingual(wp_get_attachment_caption($doc_id) ?: '', $lang),
|
||||
'title' => thalim_bilingual(get_the_title($doc_id) ?: '', $lang),
|
||||
'portrait' => ($h > $w),
|
||||
];
|
||||
}
|
||||
} else {
|
||||
$data['documents'][] = [
|
||||
'url' => wp_get_attachment_url($doc_id),
|
||||
'title' => thalim_bilingual(get_the_title($doc_id) ?: '', $lang) ?: basename(get_attached_file($doc_id)),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// --- Members (user IDs → name + profile URL) ---
|
||||
foreach (get_post_meta($post_id, 'membres', false) as $uid) {
|
||||
$user = get_userdata($uid);
|
||||
if ($user) {
|
||||
$data['membres'][] = [
|
||||
'name' => $user->display_name,
|
||||
'url' => get_author_posts_url($uid),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// --- Autre membres (user IDs → name + profile URL) ---
|
||||
foreach (get_post_meta($post_id, 'autre_membres', false) as $uid) {
|
||||
$user = get_userdata($uid);
|
||||
if ($user) {
|
||||
$data['autre_membres'][] = [
|
||||
'name' => $user->display_name,
|
||||
'url' => get_author_posts_url($uid),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// --- Axes thématiques (taxonomy term IDs) ---
|
||||
$axe_ids = get_post_meta($post_id, 'axes_thematiques', false);
|
||||
foreach ($axe_ids as $axe_id) {
|
||||
$term = get_term(intval($axe_id), 'axe_thematique');
|
||||
if ($term && !is_wp_error($term)) {
|
||||
$data['axes'][] = [
|
||||
'id' => $term->term_id,
|
||||
'name' => thalim_bilingual($term->name, $lang),
|
||||
'url' => get_term_link($term),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// --- Étiquettes (taxonomy term IDs) ---
|
||||
$tag_ids = get_post_meta($post_id, 'etiquettes', false);
|
||||
foreach ($tag_ids as $tag_id) {
|
||||
$term = get_term(intval($tag_id), 'post_tag');
|
||||
if ($term && !is_wp_error($term)) {
|
||||
$data['etiquettes'][] = [
|
||||
'id' => $term->term_id,
|
||||
'name' => thalim_bilingual($term->name, $lang),
|
||||
'url' => get_term_link($term),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// --- Programmes de recherche (taxonomy term IDs) ---
|
||||
$prog_ids = get_post_meta($post_id, 'programmes_de_recherche', false);
|
||||
foreach ($prog_ids as $prog_id) {
|
||||
$term = get_term(intval($prog_id), 'programme_de_recherche');
|
||||
if ($term && !is_wp_error($term)) {
|
||||
$data['programmes'][] = [
|
||||
'id' => $term->term_id,
|
||||
'name' => thalim_bilingual($term->name, $lang),
|
||||
'url' => get_term_link($term),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// --- Annonces liées (related posts) ---
|
||||
$related_ids = get_post_meta($post_id, 'annonces_liees', false);
|
||||
if (!empty($related_ids)) {
|
||||
$data['annonces_liees'] = Timber::get_posts([
|
||||
'post_type' => 'post',
|
||||
'post__in' => array_map('intval', $related_ids),
|
||||
'posts_per_page' => -1,
|
||||
'lang' => '',
|
||||
]);
|
||||
}
|
||||
|
||||
// --- Séances (session posts) — split into upcoming / past ---
|
||||
$seance_ids = get_post_meta($post_id, 'seances', false);
|
||||
$data['seances_a_venir'] = [];
|
||||
$data['seances_passees'] = [];
|
||||
if (!empty($seance_ids)) {
|
||||
$seance_posts = Timber::get_posts([
|
||||
'post_type' => 'post',
|
||||
'post__in' => array_map('intval', $seance_ids),
|
||||
'posts_per_page' => -1,
|
||||
'orderby' => 'meta_value',
|
||||
'meta_key' => 'date_de_debut',
|
||||
'order' => 'ASC',
|
||||
'lang' => '',
|
||||
'post_status' => ['publish', 'future'],
|
||||
]);
|
||||
$now = time();
|
||||
$current_year = date('Y');
|
||||
$months_fr = ['jan.', 'fév.', 'mars', 'avr.', 'mai', 'juin', 'juil.', 'août', 'sept.', 'oct.', 'nov.', 'déc.'];
|
||||
$months_en = ['Jan.', 'Feb.', 'Mar.', 'Apr.', 'May', 'Jun.', 'Jul.', 'Aug.', 'Sep.', 'Oct.', 'Nov.', 'Dec.'];
|
||||
|
||||
foreach ($seance_posts as $seance) {
|
||||
$raw_date = get_post_meta($seance->ID, 'date_de_debut', true);
|
||||
$ts = $raw_date ? strtotime($raw_date) : strtotime($seance->post_date);
|
||||
|
||||
// Only expose date_fin when it's a different day than date_de_debut
|
||||
$raw_fin = get_post_meta($seance->ID, 'date_de_fin', true);
|
||||
$ts_fin = $raw_fin && !str_starts_with($raw_fin, '0000-00-00') ? strtotime($raw_fin) : false;
|
||||
$date_fin_display = ($ts_fin && date('Y-m-d', $ts_fin) !== date('Y-m-d', $ts))
|
||||
? thalim_format_date($raw_fin, $lang)
|
||||
: '';
|
||||
|
||||
$month_idx = intval(date('n', $ts)) - 1;
|
||||
$seance_data = [
|
||||
'post' => $seance,
|
||||
'day' => date('d', $ts),
|
||||
'month' => ($lang === 'en') ? $months_en[$month_idx] : $months_fr[$month_idx],
|
||||
'year' => (date('Y', $ts) !== $current_year) ? date('Y', $ts) : '',
|
||||
'date_full' => thalim_format_date($raw_date, $lang),
|
||||
'date_fin' => $date_fin_display,
|
||||
'heure_de_debut' => substr( get_post_meta($seance->ID, 'heure_de_debut', true) ?: '', 0, 5 ),
|
||||
'heure_de_fin' => substr( get_post_meta($seance->ID, 'heure_de_fin', true) ?: '', 0, 5 ),
|
||||
'lieu' => thalim_bilingual( get_post_meta($seance->ID, 'lieu', true) ?: '', $lang ),
|
||||
'adresse' => get_post_meta($seance->ID, 'adresse', true) ?: '',
|
||||
'body_en' => apply_filters( 'the_content', get_post_meta($seance->ID, 'body_en', true) ?: '' ),
|
||||
'intervenants' => [],
|
||||
'images' => [],
|
||||
'documents' => [],
|
||||
'liens_externes' => [],
|
||||
'annonces_liees' => [],
|
||||
];
|
||||
|
||||
// Resolve intervenants (membres or autrepersonnes)
|
||||
$m_ids = get_post_meta($seance->ID, 'membres', false);
|
||||
if (empty($m_ids)) {
|
||||
$m_ids = get_post_meta($seance->ID, 'autre_membres', false);
|
||||
}
|
||||
foreach ($m_ids as $uid) {
|
||||
$user = get_userdata($uid);
|
||||
if ($user) {
|
||||
$seance_data['intervenants'][] = [
|
||||
'name' => $user->display_name,
|
||||
'url' => get_author_posts_url($uid),
|
||||
];
|
||||
}
|
||||
}
|
||||
$seance_data['autrepersonnes'] = get_post_meta($seance->ID, 'autrepersonnes', true) ?: '';
|
||||
$seance_data['show_image_titles'] = (bool) get_post_meta($seance->ID, 'afficher_le_titre_des_images_en_legende', true);
|
||||
|
||||
// Documents joints: images and files
|
||||
$s_doc_ids = get_post_meta($seance->ID, 'documents_joints', false);
|
||||
foreach ($s_doc_ids as $doc_id) {
|
||||
$mime = get_post_mime_type($doc_id);
|
||||
if (!$mime) continue;
|
||||
if (str_starts_with($mime, 'image/')) {
|
||||
$src = wp_get_attachment_image_url($doc_id, 'large');
|
||||
if ($src) {
|
||||
$seance_data['images'][] = [
|
||||
'url' => $src,
|
||||
'alt' => get_post_meta($doc_id, '_wp_attachment_image_alt', true) ?: '',
|
||||
'caption' => thalim_bilingual(wp_get_attachment_caption($doc_id) ?: '', $lang),
|
||||
'title' => thalim_bilingual(get_the_title($doc_id) ?: '', $lang),
|
||||
];
|
||||
}
|
||||
} else {
|
||||
$seance_data['documents'][] = [
|
||||
'url' => wp_get_attachment_url($doc_id),
|
||||
'title' => thalim_bilingual(get_the_title($doc_id) ?: '', $lang) ?: basename(get_attached_file($doc_id)),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// External links (up to 3)
|
||||
for ($i = 1; $i <= 3; $i++) {
|
||||
$url = get_post_meta($seance->ID, 'lien_externe_' . $i, true);
|
||||
if ($url) {
|
||||
$titre = thalim_bilingual( get_post_meta($seance->ID, 'titre_du_lien_externe_' . $i, true) ?: '', $lang );
|
||||
if (!$titre) {
|
||||
$host = parse_url($url, PHP_URL_HOST) ?: $url;
|
||||
$parts = explode('.', $host);
|
||||
$titre = count($parts) >= 2 ? implode('.', array_slice($parts, -2)) : $host;
|
||||
}
|
||||
$seance_data['liens_externes'][] = ['url' => $url, 'titre' => $titre];
|
||||
}
|
||||
}
|
||||
|
||||
// Annonces liées
|
||||
$s_related_ids = get_post_meta($seance->ID, 'annonces_liees', false);
|
||||
if (!empty($s_related_ids)) {
|
||||
$seance_data['annonces_liees'] = Timber::get_posts([
|
||||
'post_type' => 'post',
|
||||
'post__in' => array_map('intval', $s_related_ids),
|
||||
'posts_per_page' => -1,
|
||||
'lang' => '',
|
||||
]);
|
||||
}
|
||||
|
||||
if ($ts >= $now) {
|
||||
$data['seances_a_venir'][] = $seance_data;
|
||||
} else {
|
||||
$data['seances_passees'][] = $seance_data;
|
||||
}
|
||||
}
|
||||
// Past séances: most recent first
|
||||
$data['seances_passees'] = array_reverse($data['seances_passees']);
|
||||
}
|
||||
|
||||
// --- Type label (category-conditional type fields) ---
|
||||
$type_fields = [
|
||||
'type_colloque_journee_d_etude',
|
||||
'type_soutenance',
|
||||
'type_evenement_culturel',
|
||||
'type_media',
|
||||
'type_captation',
|
||||
'type_revue_collection',
|
||||
'type_autre',
|
||||
];
|
||||
foreach ($type_fields as $field) {
|
||||
$val = get_post_meta($post_id, $field, true);
|
||||
if ($val) {
|
||||
$data['type_label'] = thalim_bilingual( $val, $lang );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// --- Fonction label (first non-empty fonction_* field) ---
|
||||
$fonction_fields = [
|
||||
'fonction_auteur',
|
||||
'fonction_organisation',
|
||||
'fonction_intervention',
|
||||
'fonction_redaction',
|
||||
'fonction_realisation',
|
||||
'fonction_dirige',
|
||||
'fonction_responsable',
|
||||
'fonction_candidat',
|
||||
];
|
||||
foreach ($fonction_fields as $field) {
|
||||
$val = get_post_meta($post_id, $field, true);
|
||||
if ($val) {
|
||||
$data['fonction_label'] = thalim_bilingual( $val, $lang );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// --- Autre fonction label (first non-empty autre_fonction_* field) ---
|
||||
$autre_fonction_fields = [
|
||||
'autre_fonction_autre',
|
||||
'autre_fonction_concerne',
|
||||
'autre_fonction_directeur',
|
||||
'autre_fonction_direction_d_ouvrage',
|
||||
'autre_fonction_intervenant',
|
||||
'autre_fonction_participants',
|
||||
];
|
||||
foreach ($autre_fonction_fields as $field) {
|
||||
$val = get_post_meta($post_id, $field, true);
|
||||
if ($val) {
|
||||
$data['autre_fonction_label'] = thalim_bilingual( $val, $lang );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// --- Fallback: derive labels from Pods categorie ID for older posts ---
|
||||
if (!$data['fonction_label'] || !$data['autre_fonction_label']) {
|
||||
$pods_cat = get_post_meta($post_id, '_pods_categorie', true);
|
||||
$cat_id = (is_array($pods_cat) && !empty($pods_cat)) ? intval($pods_cat[0]) : 0;
|
||||
|
||||
// Pods categorie ID → fonction label (main membres)
|
||||
$cat_to_fonction = [
|
||||
3 => 'Organisation', 4 => 'Auteur', 6 => 'Responsable',
|
||||
8 => 'Organisation', 9 => 'Responsable', 10 => 'Organisation',
|
||||
11 => 'Organisation', 12 => 'Intervention', 13 => 'Intervention',
|
||||
14 => 'Candidat', 15 => 'Auteur', 16 => 'Auteur',
|
||||
17 => 'Responsable', 18 => 'Organisation', 19 => 'Intervention',
|
||||
21 => 'Rédaction', 22 => 'Réalisation', 23 => 'Intervention',
|
||||
24 => 'Responsable', 25 => 'Responsable', 65 => 'Dirigé par',
|
||||
];
|
||||
|
||||
// Pods categorie ID → autre_fonction label (autre membres)
|
||||
$cat_to_autre_fonction = [
|
||||
3 => 'Participants', 4 => "Direction d'ouvrage",
|
||||
10 => 'Participants', 14 => 'Directeur de thèse',
|
||||
15 => "Direction d'ouvrage", 16 => "Direction d'ouvrage",
|
||||
19 => 'Membre concerné', 22 => 'Intervenant',
|
||||
];
|
||||
|
||||
if (!$data['fonction_label'] && isset($cat_to_fonction[$cat_id])) {
|
||||
$data['fonction_label'] = $cat_to_fonction[$cat_id];
|
||||
}
|
||||
if (!$data['autre_fonction_label'] && isset($cat_to_autre_fonction[$cat_id])) {
|
||||
$data['autre_fonction_label'] = $cat_to_autre_fonction[$cat_id];
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
Reference in New Issue
Block a user