149 lines
6.4 KiB
PHP
149 lines
6.4 KiB
PHP
<?php
|
||
/**
|
||
* Tri et filtre par date d'événement (date_de_debut / datetime / post_date)
|
||
* + helpers de listes : groupes d'axes pour les filtres, posts épinglés.
|
||
*
|
||
* Activation sur un WP_Query / Timber::get_posts :
|
||
* 'thalim_event_date_order' => true
|
||
* 'thalim_event_date_filter' => ['from' => 'Y-m-d', 'to' => 'Y-m-d']
|
||
*/
|
||
|
||
// Event date ordering: COALESCE(date_de_debut, datetime, post_date)
|
||
// Activated by adding 'thalim_event_date_order' => true to WP_Query args.
|
||
add_filter('posts_join', function ($join, $query) {
|
||
if (!$query->get('thalim_event_date_order') && !$query->get('thalim_event_date_filter')) return $join;
|
||
global $wpdb;
|
||
$join .= " LEFT JOIN {$wpdb->postmeta} AS thalim_ed"
|
||
. " ON (thalim_ed.post_id = {$wpdb->posts}.ID"
|
||
. " AND thalim_ed.meta_key = 'date_de_debut') ";
|
||
$join .= " LEFT JOIN {$wpdb->postmeta} AS thalim_dt"
|
||
. " ON (thalim_dt.post_id = {$wpdb->posts}.ID"
|
||
. " AND thalim_dt.meta_key = 'datetime') ";
|
||
return $join;
|
||
}, 10, 2);
|
||
|
||
add_filter('posts_orderby', function ($orderby, $query) {
|
||
if (!$query->get('thalim_event_date_order')) return $orderby;
|
||
global $wpdb;
|
||
$valid = "IS NOT NULL AND %s != '' AND %s NOT LIKE '0000-00-00%%'";
|
||
return "CASE"
|
||
. " WHEN thalim_ed.meta_value " . sprintf($valid, 'thalim_ed.meta_value', 'thalim_ed.meta_value') . " THEN thalim_ed.meta_value"
|
||
. " WHEN thalim_dt.meta_value " . sprintf($valid, 'thalim_dt.meta_value', 'thalim_dt.meta_value') . " THEN thalim_dt.meta_value"
|
||
. " ELSE {$wpdb->posts}.post_date"
|
||
. " END DESC, {$wpdb->posts}.ID DESC"; // tiebreaker déterministe: sans lui, les dates ex-æquo paginent de façon instable entre les requêtes séparées (initial vs AJAX)
|
||
}, 10, 2);
|
||
|
||
// Event date range filter: uses same CASE logic as ordering so date_de_debut/datetime take priority over post_date.
|
||
// Activated by adding 'thalim_event_date_filter' => ['from' => $date_from, 'to' => $date_to] to WP_Query args.
|
||
add_filter('posts_where', function ($where, $query) {
|
||
$filter = $query->get('thalim_event_date_filter');
|
||
if (empty($filter) || (!isset($filter['from']) && !isset($filter['to']))) return $where;
|
||
global $wpdb;
|
||
|
||
$effective = "CASE"
|
||
. " WHEN thalim_ed.meta_value IS NOT NULL AND thalim_ed.meta_value != '' AND thalim_ed.meta_value NOT LIKE '0000-00-00%' THEN thalim_ed.meta_value"
|
||
. " WHEN thalim_dt.meta_value IS NOT NULL AND thalim_dt.meta_value != '' AND thalim_dt.meta_value NOT LIKE '0000-00-00%' THEN thalim_dt.meta_value"
|
||
. " ELSE {$wpdb->posts}.post_date"
|
||
. " END";
|
||
|
||
if (!empty($filter['from'])) {
|
||
$from = $wpdb->prepare('%s', $filter['from']);
|
||
$where .= " AND ({$effective}) >= {$from}";
|
||
}
|
||
if (!empty($filter['to'])) {
|
||
$to = $wpdb->prepare('%s', $filter['to'] . ' 23:59:59');
|
||
$where .= " AND ({$effective}) <= {$to}";
|
||
}
|
||
|
||
return $where;
|
||
}, 10, 2);
|
||
|
||
// Return the IDs of posts currently pinned ("épinglé dans la catégorie") in a given category.
|
||
// A pin is active if epingler_dans_la_categorie == 1 AND date_de_fin_depinglage is empty/0000-00-00/future.
|
||
// Shared by category.php (pull them out of the main flow) and the AJAX handler (exclude them from
|
||
// pagination) so both sides stay in sync — a mismatch shifts the page boundary and dupes posts.
|
||
function thalim_get_active_pinned_ids( $category_id ) {
|
||
if ( ! $category_id ) return [];
|
||
$today = date( 'Y-m-d' );
|
||
$pinned_query = new WP_Query([
|
||
'post_type' => 'post',
|
||
'post_status' => 'publish',
|
||
'posts_per_page' => -1,
|
||
'fields' => 'ids',
|
||
'no_found_rows' => true,
|
||
'tax_query' => [[
|
||
'taxonomy' => 'category',
|
||
'field' => 'term_id',
|
||
'terms' => [ $category_id ],
|
||
'include_children' => false,
|
||
]],
|
||
'meta_query' => [[
|
||
'key' => 'epingler_dans_la_categorie',
|
||
'value' => '1',
|
||
]],
|
||
]);
|
||
$pinned_ids = [];
|
||
foreach ( $pinned_query->posts as $pid ) {
|
||
$fin = get_post_meta( $pid, 'date_de_fin_depinglage', true );
|
||
if ( empty( $fin ) || $fin === '0000-00-00' || $fin >= $today ) {
|
||
$pinned_ids[] = $pid;
|
||
}
|
||
}
|
||
return $pinned_ids;
|
||
}
|
||
|
||
// ── Axes thématiques groupés pour les filtres ──────────────────
|
||
// Retourne un tableau de groupes triés par période (plus récent en premier,
|
||
// "passés" toujours en dernier). Chaque terme contient id, name, ordre.
|
||
function thalim_get_axes_filter_groups() {
|
||
$terms = get_terms( [ 'taxonomy' => 'axe_thematique', 'hide_empty' => false ] );
|
||
$axes_map = [];
|
||
|
||
foreach ( $terms as $term ) {
|
||
$debut = trim( get_term_meta( $term->term_id, 'annee_debut', true ) );
|
||
$fin = trim( get_term_meta( $term->term_id, 'annee_fin', true ) );
|
||
|
||
if ( $debut && $fin ) {
|
||
$key = $debut . '-' . $fin;
|
||
$label = $debut . ' – ' . $fin;
|
||
} else {
|
||
$key = 'passes';
|
||
$label = 'Axes antérieurs';
|
||
}
|
||
|
||
if ( ! isset( $axes_map[ $key ] ) ) {
|
||
$axes_map[ $key ] = [ 'label' => $label, 'debut' => intval( $debut ), 'terms' => [] ];
|
||
}
|
||
|
||
$ordre = trim( get_term_meta( $term->term_id, 'ordre_daffichage', true ) );
|
||
$axes_map[ $key ]['terms'][] = [
|
||
'id' => $term->term_id,
|
||
'name' => $term->name,
|
||
'ordre' => $ordre !== '' ? intval( $ordre ) : null,
|
||
'href' => get_term_link( $term ),
|
||
];
|
||
}
|
||
|
||
// Tri des groupes : plus récent en premier, passés toujours en dernier
|
||
uasort( $axes_map, function ( $a, $b ) {
|
||
if ( $a['label'] === 'Axes antérieurs' ) return 1;
|
||
if ( $b['label'] === 'Axes antérieurs' ) return -1;
|
||
return $b['debut'] - $a['debut'];
|
||
} );
|
||
|
||
// Tri des termes dans chaque groupe : ordre_daffichage d'abord, puis alphabétique
|
||
foreach ( $axes_map as &$group ) {
|
||
usort( $group['terms'], function ( $a, $b ) {
|
||
$a_has = $a['ordre'] !== null;
|
||
$b_has = $b['ordre'] !== null;
|
||
if ( $a_has && $b_has ) return $a['ordre'] - $b['ordre'];
|
||
if ( $a_has ) return -1;
|
||
if ( $b_has ) return 1;
|
||
return strcmp( $a['name'], $b['name'] );
|
||
} );
|
||
}
|
||
unset( $group );
|
||
|
||
return array_values( $axes_map );
|
||
}
|