Initial commit

This commit is contained in:
2026-05-12 23:33:46 +02:00
commit ccf32dcece
104 changed files with 17439 additions and 0 deletions

250
inc/author-helpers.php Normal file
View File

@@ -0,0 +1,250 @@
<?php
/**
* Resolve all profile data for a member/author into a display-ready array.
*/
function thalim_get_author_data($user_id) {
$user = get_userdata($user_id);
if (!$user) return [];
$lang = thalim_current_language();
// --- Avatar (Simple Local Avatar with Gravatar fallback) ---
$avatar_url = thalim_get_user_avatar_url( $user_id );
// --- Role (taxonomy 'role') ---
$role_id = get_user_meta($user_id, 'role_1', true);
$role_label = '';
if ($role_id) {
$role_term = get_term(intval($role_id), 'role');
if ($role_term && !is_wp_error($role_term)) {
$override = thalim_bilingual(get_user_meta($user_id, 'affichage_du_statut_1', true) ?: '', $lang);
$role_label = $override ?: $role_term->name;
}
}
// --- Direction title (read from "Le laboratoire" page) ---
$labo_page = get_page_by_path('le-laboratoire');
$directeur_id = $labo_page ? intval(get_post_meta($labo_page->ID, 'directeur', true)) : 0;
$adjoint_id = $labo_page ? intval(get_post_meta($labo_page->ID, 'directeur_adjoint', true)) : 0;
if ($user_id === $directeur_id) {
$role_label = 'Directeur' . ($role_label ? ', ' . $role_label : '');
} elseif ($user_id === $adjoint_id) {
$role_label = 'Directeur adjoint' . ($role_label ? ', ' . $role_label : '');
}
// --- Domaines de recherches (multiple usermeta rows with post_tag IDs) ---
$domaine_ids = get_user_meta($user_id, 'domaines_de_recherches', false);
$domaines_tags = [];
foreach ($domaine_ids as $tag_id) {
if (!$tag_id) continue;
$term = get_term(intval($tag_id), 'post_tag');
if ($term && !is_wp_error($term)) {
$link = get_term_link($term);
if (!is_wp_error($link)) {
$domaines_tags[] = ['name' => thalim_bilingual($term->name, $lang), 'url' => $link];
}
}
}
// --- Axes thématiques (multiple usermeta rows) ---
$axe_ids = get_user_meta($user_id, 'axes_thematiques', false);
$axes = [];
foreach ($axe_ids as $axe_id) {
$term = get_term(intval($axe_id), 'axe_thematique');
if ($term && !is_wp_error($term)) {
$axes[] = [
'name' => thalim_bilingual($term->name, $lang),
'url' => get_term_link($term),
];
}
}
// --- External links (up to 4) ---
$liens_externes = [];
for ($i = 1; $i <= 4; $i++) {
$url = get_user_meta($user_id, 'lien_externe_' . $i, true);
if ($url) {
$titre = thalim_bilingual(get_user_meta($user_id, 'titre_du_lien_' . $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;
}
$liens_externes[] = ['url' => $url, 'titre' => $titre];
}
}
// --- Documents (multiple usermeta rows with attachment IDs) ---
$doc_ids = get_user_meta($user_id, 'documents', false);
$documents = [];
foreach ($doc_ids as $doc_id) {
$url = wp_get_attachment_url(intval($doc_id));
if ($url) {
$documents[] = [
'url' => $url,
'title' => get_the_title($doc_id) ?: basename(get_attached_file($doc_id)),
];
}
}
// --- Thesis director (THALIM member — stored as user ID) ---
$directeur_id = get_user_meta($user_id, 'directeur_de_these_thalim', true);
$directeur_thalim = null;
if ($directeur_id) {
$dir_user = get_userdata(intval($directeur_id));
if ($dir_user) {
$directeur_thalim = [
'name' => $dir_user->display_name,
'url' => get_author_posts_url(intval($directeur_id)),
];
}
}
// --- Email visibility ---
$is_ancien = isset($role_term) && $role_term && $role_term->slug === 'anciens-membres';
$show_email = !$is_ancien && get_user_meta($user_id, 'afficher_ladresse_mail_sur_le_profil', true);
return [
'display_name' => $user->display_name,
'avatar_url' => $avatar_url,
'role_label' => $role_label,
'role_complement' => thalim_bilingual(get_user_meta($user_id, 'complement_de_role_1', true) ?: '', $lang),
'affiliation' => (function() use ($user_id, $lang) {
$v = get_user_meta($user_id, 'affiliation', true) ?: '';
return strtolower($v) === 'autre'
? thalim_bilingual(get_user_meta($user_id, 'affiliation_autre', true) ?: '', $lang)
: $v;
})(),
'bio' => wpautop( make_clickable( get_user_meta($user_id, 'biographie', true) ?: '' ) ),
'bio_en' => wpautop( make_clickable( get_user_meta($user_id, 'biographie_en', true) ?: '' ) ),
'domaines_tags' => $domaines_tags,
'domaines' => wpautop( make_clickable( get_user_meta($user_id, 'autres_domaines_de_recherches', true) ?: '' ) ),
'domaines_en' => wpautop( make_clickable( get_user_meta($user_id, 'autres_domaines_de_recherches_en', true) ?: '' ) ),
'recherches' => wpautop( get_user_meta($user_id, 'recherches_en_cours', true) ?: '' ),
'recherches_en' => wpautop( get_user_meta($user_id, 'recherches_en_cours_en', true) ?: '' ),
'axes' => $axes,
'titre_these' => thalim_bilingual(get_user_meta($user_id, 'titre_de_these', true) ?: '', $lang),
'date_soutenance' => get_user_meta($user_id, 'date_de_soutenance', true) ?: '',
'directeur_thalim'=> $directeur_thalim,
'autre_directeur' => get_user_meta($user_id, 'autre_directeur_de_these', true) ?: '',
'resume_these' => wpautop( get_user_meta($user_id, 'resume_de_la_these', true) ?: '' ),
'resume_these_en' => wpautop( get_user_meta($user_id, 'resume_de_la_these_en', true) ?: '' ),
'email' => $show_email ? $user->user_email : '',
'liens_externes' => $liens_externes,
'documents' => $documents,
'hal_publications_url' => (function() use ($user_id) {
$hal_id = get_user_meta($user_id, 'identifiant_hal', true) ?: '';
return $hal_id
? 'https://hal.science/search/index/?qa[authIdHal_s][]=' . rawurlencode($hal_id) . '&sort=publicationDate_tdate+desc'
: '';
})(),
'user_since' => date_i18n('d/m/Y', strtotime($user->user_registered)),
];
}
/**
* Query all posts linked to a member and group them by primary category.
* Returns an array sorted by post count (descending).
*/
function thalim_get_author_posts_by_category($user_id) {
$excluded_cats = [12, 31]; // séances de séminaire, etc.
$lang = thalim_current_language();
$posts = Timber::get_posts([
'post_type' => 'post',
'posts_per_page' => -1,
'meta_query' => [
'relation' => 'OR',
[
'key' => 'membres',
'value' => $user_id,
],
[
'key' => 'autre_membres',
'value' => $user_id,
],
],
'thalim_event_date_order' => true,
'lang' => '',
]);
$groups = [];
foreach ($posts as $post) {
$categories = wp_get_post_categories($post->ID, ['fields' => 'all']);
$primary_cat = null;
foreach ($categories as $cat) {
if (in_array($cat->term_id, $excluded_cats)) continue;
$primary_cat = $cat;
break;
}
if (!$primary_cat) continue;
$cat_id = $primary_cat->term_id;
if (!isset($groups[$cat_id])) {
// A top-level category with subcategories → these posts are "Autres"
$is_autres = false;
if ($primary_cat->parent == 0) {
$subcats = get_categories(['parent' => $cat_id, 'hide_empty' => true, 'exclude' => $excluded_cats]);
$is_autres = !empty($subcats);
}
$groups[$cat_id] = [
'cat_id' => $cat_id,
'cat_name' => $is_autres
? ($lang === 'en' ? 'Other ' : 'Autres ') . thalim_cat_name($primary_cat, $lang)
: thalim_cat_name($primary_cat, $lang),
'cat_url' => $is_autres
? trailingslashit(get_category_link($cat_id)) . 'autres/'
: get_category_link($cat_id),
'posts' => [],
];
}
$groups[$cat_id]['posts'][] = $post;
}
// Séances de séminaire — dedicated group. Posts in cat 12 where the member
// is listed in `membres`/`autre_membres`. Cards use the parent séminaire
// permalink with a #seance-{ID} hash (see thalim_get_card_data).
$seances = Timber::get_posts([
'post_type' => 'post',
'posts_per_page' => -1,
'category__in' => [12],
'meta_query' => [
'relation' => 'OR',
[ 'key' => 'membres', 'value' => $user_id ],
[ 'key' => 'autre_membres', 'value' => $user_id ],
],
'thalim_event_date_order' => true,
'lang' => '',
]);
if (count($seances) > 0) {
$seance_cat = get_term(12, 'category');
$groups[12] = [
'cat_id' => 12,
'cat_name' => $seance_cat && !is_wp_error($seance_cat)
? thalim_cat_name($seance_cat, $lang)
: ($lang === 'en' ? 'Seminar sessions' : 'Séances de séminaire'),
'cat_url' => get_category_link(12),
'posts' => $seances,
];
}
// Resolve card data and sort by count descending
foreach ($groups as &$group) {
$group['cards'] = thalim_get_cards_data($group['posts']);
}
unset($group);
uasort($groups, function($a, $b) {
$oa = (int) get_term_meta($a['cat_id'], 'ordre_profil', true) ?: 999;
$ob = (int) get_term_meta($b['cat_id'], 'ordre_profil', true) ?: 999;
return $oa !== $ob
? $oa <=> $ob
: count($b['posts']) <=> count($a['posts']);
});
return array_values($groups);
}