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; }