293 lines
12 KiB
PHP
293 lines
12 KiB
PHP
<?php
|
||
if ( ! defined( 'ABSPATH' ) ) {
|
||
exit; // Empêche l'accès direct.
|
||
}
|
||
|
||
/**
|
||
* Classe Elementor_Category_Grid_Widget.
|
||
*
|
||
* Widget Elementor personnalisé qui affiche une grille de catégories d'articles.
|
||
* Chaque catégorie est affichée sous forme de carte avec son nom, son image et un lien vers son archive.
|
||
*/
|
||
class Elementor_Category_Grid_Widget extends \Elementor\Widget_Base {
|
||
|
||
/**
|
||
* Identifiant unique du widget.
|
||
*
|
||
* @return string Slug du widget.
|
||
*/
|
||
public function get_name(): string {
|
||
return 'category-grid';
|
||
}
|
||
|
||
/**
|
||
* Titre du widget affiché dans l'interface Elementor.
|
||
*
|
||
* @return string Titre du widget.
|
||
*/
|
||
public function get_title(): string {
|
||
return esc_html__( 'Grille de Catégories', 'category-grid-widget' );
|
||
}
|
||
|
||
/**
|
||
* Icône du widget (bibliothèque d'icônes Elementor).
|
||
*
|
||
* @return string Classe de l'icône du widget.
|
||
*/
|
||
public function get_icon(): string {
|
||
return 'eicon-posts-grid';
|
||
}
|
||
|
||
/**
|
||
* Catégories Elementor dans lesquelles le widget apparaîtra.
|
||
*
|
||
* @return array Catégories du panneau Elementor.
|
||
*/
|
||
public function get_categories(): array {
|
||
return [ 'general' ];
|
||
}
|
||
|
||
/**
|
||
* Mots-clés facilitant la recherche du widget.
|
||
*
|
||
* @return array Mots-clés du widget.
|
||
*/
|
||
public function get_keywords(): array {
|
||
return [ 'category', 'catégorie', 'grid', 'grille' ];
|
||
}
|
||
|
||
/**
|
||
* Enregistrer les contrôles du widget (champs configurables dans Elementor).
|
||
*/
|
||
protected function register_controls(): void {
|
||
/* Section "Contenu" pour le choix des catégories et options de requête */
|
||
$this->start_controls_section(
|
||
'section_content',
|
||
[
|
||
'label' => esc_html__( 'Catégories', 'category-grid-widget' ),
|
||
'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
|
||
]
|
||
);
|
||
|
||
// Contrôle : Sélection des catégories à afficher (multisélection).
|
||
$options = [];
|
||
$categories = get_categories( [ 'hide_empty' => false ] );
|
||
foreach ( $categories as $cat ) {
|
||
$options[ $cat->term_id ] = $cat->name;
|
||
}
|
||
$this->add_control(
|
||
'categories',
|
||
[
|
||
'label' => esc_html__( 'Catégories à afficher', 'category-grid-widget' ),
|
||
'type' => \Elementor\Controls_Manager::SELECT2,
|
||
'multiple' => true,
|
||
'label_block' => true,
|
||
'options' => $options,
|
||
'description' => esc_html__( 'Sélectionnez les catégories d’articles à afficher.', 'category-grid-widget' ),
|
||
]
|
||
);
|
||
|
||
// Contrôle : Inclure les sous-catégories.
|
||
$this->add_control(
|
||
'show_subcategories',
|
||
[
|
||
'label' => esc_html__( 'Afficher les sous-catégories', 'category-grid-widget' ),
|
||
'type' => \Elementor\Controls_Manager::SWITCHER,
|
||
'label_on' => esc_html__( 'Oui', 'category-grid-widget' ),
|
||
'label_off' => esc_html__( 'Non', 'category-grid-widget' ),
|
||
'return_value' => 'yes',
|
||
'default' => 'yes',
|
||
'description' => esc_html__( 'Inclure aussi les sous-catégories des catégories sélectionnées.', 'category-grid-widget' ),
|
||
]
|
||
);
|
||
|
||
// ----------------------------------------------------------------------
|
||
// Contrôle : Ne montrer que les catégories avec image
|
||
$this->add_control(
|
||
'hide_without_image',
|
||
[
|
||
'label' => esc_html__( 'Afficher uniquement catégories avec image', 'category-grid-widget' ),
|
||
'type' => \Elementor\Controls_Manager::SWITCHER,
|
||
'label_on' => esc_html__( 'Oui', 'category-grid-widget' ),
|
||
'label_off' => esc_html__( 'Non', 'category-grid-widget' ),
|
||
'return_value' => 'yes',
|
||
'default' => 'no',
|
||
'description' => esc_html__( 'Si activé, les catégories sans image seront masquées.', 'category-grid-widget' ),
|
||
]
|
||
);
|
||
|
||
// Contrôle : Trier par (critère de tri des catégories).
|
||
$this->add_control(
|
||
'order_by',
|
||
[
|
||
'label' => esc_html__( 'Trier par', 'category-grid-widget' ),
|
||
'type' => \Elementor\Controls_Manager::SELECT,
|
||
'options' => [
|
||
'name' => esc_html__( 'Nom (alphabétique)', 'category-grid-widget' ),
|
||
'count' => esc_html__( 'Nombre d’articles', 'category-grid-widget' ),
|
||
'id' => esc_html__( 'ID (date de création)', 'category-grid-widget' ),
|
||
],
|
||
'default' => 'name',
|
||
]
|
||
);
|
||
|
||
// Contrôle : Ordre croissant/décroissant.
|
||
$this->add_control(
|
||
'order',
|
||
[
|
||
'label' => esc_html__( 'Ordre', 'category-grid-widget' ),
|
||
'type' => \Elementor\Controls_Manager::SELECT,
|
||
'options' => [
|
||
'ASC' => esc_html__( 'Croissant (A-Z / 0-9)', 'category-grid-widget' ),
|
||
'DESC' => esc_html__( 'Décroissant (Z-A / 9-0)', 'category-grid-widget' ),
|
||
],
|
||
'default' => 'ASC',
|
||
]
|
||
);
|
||
|
||
$this->end_controls_section();
|
||
|
||
/* Section "Mise en page" pour les options d'affichage (colonnes, taille d'image) */
|
||
$this->start_controls_section(
|
||
'section_layout',
|
||
[
|
||
'label' => esc_html__( 'Mise en page', 'category-grid-widget' ),
|
||
'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
|
||
]
|
||
);
|
||
|
||
// Contrôle : Nombre de colonnes de la grille.
|
||
$this->add_control(
|
||
'columns',
|
||
[
|
||
'label' => esc_html__( 'Nombre de colonnes', 'category-grid-widget' ),
|
||
'type' => \Elementor\Controls_Manager::SELECT,
|
||
'options' => [
|
||
1 => '1',
|
||
2 => '2',
|
||
3 => '3',
|
||
4 => '4',
|
||
5 => '5',
|
||
6 => '6',
|
||
],
|
||
'default' => 3,
|
||
]
|
||
);
|
||
|
||
// Contrôle : Taille des images affichées.
|
||
$this->add_control(
|
||
'image_size',
|
||
[
|
||
'label' => esc_html__( 'Taille des images', 'category-grid-widget' ),
|
||
'type' => \Elementor\Controls_Manager::SELECT,
|
||
'options' => [
|
||
'thumbnail' => esc_html__( 'Miniature (thumbnail)', 'category-grid-widget' ),
|
||
'medium' => esc_html__( 'Moyen (medium)', 'category-grid-widget' ),
|
||
'large' => esc_html__( 'Grand (large)', 'category-grid-widget' ),
|
||
'full' => esc_html__( 'Plein (full)', 'category-grid-widget' ),
|
||
],
|
||
'default' => 'medium',
|
||
]
|
||
);
|
||
|
||
$this->end_controls_section();
|
||
}
|
||
|
||
/**
|
||
* Générer l'affichage du widget côté front-end.
|
||
*/
|
||
protected function render(): void {
|
||
$settings = $this->get_settings_for_display();
|
||
|
||
// Récupérer les ID des catégories sélectionnées.
|
||
$selected_ids = [];
|
||
if ( ! empty( $settings['categories'] ) ) {
|
||
// S'assurer d'avoir un tableau d'ID (entiers).
|
||
$selected_ids = is_array( $settings['categories'] ) ? $settings['categories'] : [ $settings['categories'] ];
|
||
$selected_ids = array_map( 'intval', $selected_ids );
|
||
}
|
||
if ( empty( $selected_ids ) ) {
|
||
// Aucune catégorie sélectionnée : ne rien afficher.
|
||
return;
|
||
}
|
||
|
||
// Déterminer les catégories à afficher (inclure les sous-catégories si demandé).
|
||
$category_ids_to_show = $selected_ids;
|
||
if ( ! empty( $settings['show_subcategories'] ) && $settings['show_subcategories'] === 'yes' ) {
|
||
// Ajouter les sous-catégories de chaque catégorie sélectionnée.
|
||
foreach ( $selected_ids as $cat_id ) {
|
||
$child_ids = get_term_children( $cat_id, 'category' );
|
||
if ( is_array( $child_ids ) && ! empty( $child_ids ) ) {
|
||
$category_ids_to_show = array_merge( $category_ids_to_show, $child_ids );
|
||
}
|
||
}
|
||
// Éliminer les doublons d'ID au cas où.
|
||
$category_ids_to_show = array_unique( $category_ids_to_show );
|
||
}
|
||
|
||
// Préparer les arguments de requête pour récupérer les termes.
|
||
$term_args = [
|
||
'taxonomy' => 'category',
|
||
'include' => $category_ids_to_show,
|
||
'hide_empty' => false,
|
||
];
|
||
// Appliquer les options de tri.
|
||
if ( ! empty( $settings['order_by'] ) ) {
|
||
$term_args['orderby'] = $settings['order_by'];
|
||
}
|
||
if ( ! empty( $settings['order'] ) ) {
|
||
$term_args['order'] = $settings['order'];
|
||
}
|
||
|
||
// Obtenir les termes de catégories à afficher.
|
||
$categories = get_terms( $term_args );
|
||
if ( is_wp_error( $categories ) || empty( $categories ) ) {
|
||
return;
|
||
}
|
||
|
||
// Calculer la classe CSS pour le nombre de colonnes (pour usage dans le CSS).
|
||
$columns = ! empty( $settings['columns'] ) ? (int) $settings['columns'] : 3;
|
||
$grid_class = 'columns-' . $columns;
|
||
|
||
// Début du markup HTML de la grille.
|
||
echo '<div class="elementor-category-grid ' . esc_attr( $grid_class ) . '">';
|
||
foreach ( $categories as $term ) {
|
||
$term_name = $term->name;
|
||
$term_link = get_term_link( $term );
|
||
if ( is_wp_error( $term_link ) ) {
|
||
continue; // Ignorer si le lien d'archive pose un problème.
|
||
}
|
||
// Récupérer l'image de la catégorie via sa méta 'thumbnail_id' (image mise en avant de la catégorie).
|
||
$image_url = '';
|
||
$thumbnail_id = get_term_meta( $term->term_id, 'thumbnail_id', true );
|
||
if ( $thumbnail_id ) {
|
||
$size = ! empty( $settings['image_size'] ) ? $settings['image_size'] : 'medium';
|
||
$image_url = wp_get_attachment_image_url( $thumbnail_id, $size );
|
||
}
|
||
|
||
// *** Nouveau filtre ***
|
||
if ( 'yes' === $settings['hide_without_image'] && empty( $image_url ) ) {
|
||
continue;
|
||
}
|
||
|
||
echo '<div class="category-card">';
|
||
// Rendre la carte cliquable vers l'archive de la catégorie.
|
||
echo '<a href="' . esc_url( $term_link ) . '">';
|
||
// Image de la catégorie (si disponible).
|
||
if ( $image_url ) {
|
||
echo '<div class="category-card-image">';
|
||
echo '<img src="' . esc_url( $image_url ) . '" alt="' . esc_attr( $term_name ) . '" />';
|
||
echo '</div>';
|
||
}
|
||
// Nom de la catégorie.
|
||
echo '<div class="category-card-name">' . esc_html( $term_name ) . '</div>';
|
||
echo '</a>';
|
||
echo '</div>'; // .category-card
|
||
}
|
||
echo '</div>'; // .elementor-category-grid
|
||
|
||
// Astuce : ajouter du CSS (feuille de style ou balise <style>) pour styliser la grille.
|
||
// Par exemple, .elementor-category-grid.columns-3 .category-card { width: 33.33%; float: left; } pour disposer 3 colonnes.
|
||
}
|
||
}
|