HEX
Server: Apache
System: Linux webm013.cluster123.gra.hosting.ovh.net 6.18.42-ovh-vps-grsec-zfs+ #1 SMP PREEMPT_DYNAMIC Wed Aug 5 15:59:48 CEST 2026 x86_64
User: lesanew (165608)
PHP: 8.3.31
Disabled: _dyuweyrj4,_dyuweyrj4r,dl
Upload Files
File: /home/lesanew/anestetues2/web/app/themes/anes-tetues/app/setup.php
<?php

/**
 * Theme setup.
 */

namespace App;

use Illuminate\Support\Facades\Vite;

/**
 * Inject styles into the block editor.
 *
 * @return array
 */
add_filter('block_editor_settings_all', function ($settings) {
    $style = Vite::asset('resources/css/editor.scss');

    $settings['styles'][] = [
        'css' => "@import url('{$style}')",
    ];

    return $settings;
});

/**
 * Inject scripts into the block editor.
 *
 * @return void
 */
add_filter('admin_head', function () {
    if (! get_current_screen()?->is_block_editor()) {
        return;
    }

    $dependencies = json_decode(Vite::content('editor.deps.json'));

    foreach ($dependencies as $dependency) {
        if (! wp_script_is($dependency)) {
            wp_enqueue_script($dependency);
        }
    }

    echo Vite::withEntryPoints([
        'resources/js/editor.ts',
    ])->toHtml();
});

/**
 * Use the generated theme.json file.
 *
 * @return string
 */
add_filter('theme_file_path', function ($path, $file) {
    return $file === 'theme.json'
        ? public_path('build/assets/theme.json')
        : $path;
}, 10, 2);

/**
 * Register the initial theme setup.
 *
 * @return void
 */
add_action('after_setup_theme', function () {
    /**
     * Disable full-site editing support.
     *
     * @link https://wptavern.com/gutenberg-10-5-embeds-pdfs-adds-verse-block-color-options-and-introduces-new-patterns
     */
    remove_theme_support('block-templates');

    /**
     * Register the navigation menus.
     *
     * @link https://developer.wordpress.org/reference/functions/register_nav_menus/
     */
    register_nav_menus([
        'primary_navigation' => __('Primary Navigation', 'sage'),
    ]);

    /**
     * Disable the default block patterns.
     *
     * @link https://developer.wordpress.org/block-editor/developers/themes/theme-support/#disabling-the-default-block-patterns
     */
    remove_theme_support('core-block-patterns');

    /**
     * Enable plugins to manage the document title.
     *
     * @link https://developer.wordpress.org/reference/functions/add_theme_support/#title-tag
     */
    add_theme_support('title-tag');

    /**
     * Enable post thumbnail support.
     *
     * @link https://developer.wordpress.org/themes/functionality/featured-images-post-thumbnails/
     */
    add_theme_support('post-thumbnails');

    /**
     * Enable responsive embed support.
     *
     * @link https://developer.wordpress.org/block-editor/how-to-guides/themes/theme-support/#responsive-embedded-content
     */
    add_theme_support('responsive-embeds');

    /**
     * Enable HTML5 markup support.
     *
     * @link https://developer.wordpress.org/reference/functions/add_theme_support/#html5
     */
    add_theme_support('html5', [
        'caption',
        'comment-form',
        'comment-list',
        'gallery',
        'search-form',
        'script',
        'style',
    ]);

    /**
     * Enable selective refresh for widgets in customizer.
     *
     * @link https://developer.wordpress.org/reference/functions/add_theme_support/#customize-selective-refresh-widgets
     */
    add_theme_support('customize-selective-refresh-widgets');
}, 20);

/**
 * Register the theme sidebars.
 *
 * @return void
 */
add_action('widgets_init', function () {
    $config = [
        'before_widget' => '<section class="widget %1$s %2$s">',
        'after_widget' => '</section>',
        'before_title' => '<h3>',
        'after_title' => '</h3>',
    ];

    register_sidebar([
        'name' => __('Primary', 'sage'),
        'id' => 'sidebar-primary',
    ] + $config);

    register_sidebar([
        'name' => __('Footer', 'sage'),
        'id' => 'sidebar-footer',
    ] + $config);
});

/**
 * Configure ACF to save JSON files in the theme directory.
 * This allows versioning ACF field groups in Git.
 *
 * @return void
 */
add_filter('acf/settings/save_json', function ($path) {
    // Save JSON files in the theme's acf-json directory
    $path = get_stylesheet_directory().'/acf-json';

    // Create directory if it doesn't exist
    if (! file_exists($path)) {
        wp_mkdir_p($path);
    }

    return $path;
});

add_filter('acf/settings/load_json', function ($paths) {
    // Load JSON files from the theme's acf-json directory
    $paths[] = get_stylesheet_directory().'/acf-json';

    return $paths;
});

/**
 * Register ACF options page.
 *
 * @return void
 */
add_action('acf/init', function () {
    acf_add_options_page([
        'page_title' => __('Informations Général', 'anes-tetues'),
        'menu_title' => __('Informations Général', 'anes-tetues'),
        'menu_slug' => 'informations-general',
        'capability' => 'edit_posts',
        'redirect' => false,
        'position' => 30,
    ]);

    acf_add_options_page([
        'page_title' => __('Informations prochain concert', 'anes-tetues'),
        'menu_title' => __('Informations prochain concert', 'anes-tetues'),
        'menu_slug' => 'informations-prochain-concert',
        'capability' => 'edit_posts',
        'redirect' => false,
        'icon_url' => 'dashicons-calendar-alt',
        'position' => 31,
    ]);
});

/**
 * Register "Line Up" custom post type.
 */
add_action('init', function () {
    register_post_type('lineup', [
        'labels' => [
            'name' => __('Line Up', 'anes-tetues'),
            'singular_name' => __('Line Up', 'anes-tetues'),
            'add_new' => __('Ajouter un élément', 'anes-tetues'),
            'add_new_item' => __('Ajouter un artiste', 'anes-tetues'),
            'edit_item' => __("Modifier l'artiste", 'anes-tetues'),
            'new_item' => __('Nouvel artiste', 'anes-tetues'),
            'view_item' => __("Voir l'artiste", 'anes-tetues'),
            'search_items' => __('Rechercher un artiste', 'anes-tetues'),
            'not_found' => __('Aucun artiste trouvé', 'anes-tetues'),
            'not_found_in_trash' => __('Aucun artiste dans la corbeille', 'anes-tetues'),
            'all_items' => __('Tous les artistes', 'anes-tetues'),
            'menu_name' => __('Line Up', 'anes-tetues'),
        ],
        'public' => true,
        'has_archive' => false,
        'show_in_rest' => true,
        'menu_position' => 20,
        'menu_icon' => 'dashicons-playlist-audio',
        'supports' => ['title'],
        'rewrite' => [
            'slug' => 'line-up',
            'with_front' => false,
        ],
    ]);
});

/**
 * Register "Partenaires" custom post type.
 */
add_action('init', function () {
    register_post_type('partenaire', [
        'labels' => [
            'name' => __('Partenaires', 'anes-tetues'),
            'singular_name' => __('Partenaire', 'anes-tetues'),
            'add_new' => __('Ajouter un partenaire', 'anes-tetues'),
            'add_new_item' => __('Ajouter un partenaire', 'anes-tetues'),
            'edit_item' => __('Modifier le partenaire', 'anes-tetues'),
            'new_item' => __('Nouveau partenaire', 'anes-tetues'),
            'view_item' => __('Voir le partenaire', 'anes-tetues'),
            'search_items' => __('Rechercher un partenaire', 'anes-tetues'),
            'not_found' => __('Aucun partenaire trouvé', 'anes-tetues'),
            'not_found_in_trash' => __('Aucun partenaire dans la corbeille', 'anes-tetues'),
            'all_items' => __('Tous les partenaires', 'anes-tetues'),
            'menu_name' => __('Partenaires', 'anes-tetues'),
        ],
        'public' => true,
        'has_archive' => false,
        'show_in_rest' => true,
        'menu_position' => 21,
        'menu_icon' => 'dashicons-groups',
        'supports' => ['title'],
        'rewrite' => [
            'slug' => 'partenaires',
            'with_front' => false,
        ],
    ]);

    register_post_type('createur_local', [
        'labels' => [
            'name' => __('Créateurs locaux', 'anes-tetues'),
            'singular_name' => __('Créateur local', 'anes-tetues'),
            'add_new' => __('Ajouter un créateur', 'anes-tetues'),
            'add_new_item' => __('Ajouter un créateur local', 'anes-tetues'),
            'edit_item' => __('Modifier le créateur local', 'anes-tetues'),
            'new_item' => __('Nouveau créateur local', 'anes-tetues'),
            'view_item' => __('Voir le créateur local', 'anes-tetues'),
            'search_items' => __('Rechercher un créateur local', 'anes-tetues'),
            'not_found' => __('Aucun créateur local trouvé', 'anes-tetues'),
            'not_found_in_trash' => __('Aucun créateur local dans la corbeille', 'anes-tetues'),
            'all_items' => __('Tous les créateurs locaux', 'anes-tetues'),
            'menu_name' => __('Créateurs locaux', 'anes-tetues'),
        ],
        'public' => true,
        'has_archive' => false,
        'show_in_rest' => true,
        'menu_position' => 22,
        'menu_icon' => 'dashicons-store',
        'supports' => ['title', 'thumbnail'],
        'rewrite' => [
            'slug' => 'createurs-locaux',
            'with_front' => false,
        ],
    ]);
});

/**
 * Register "Produits créateurs" custom post type.
 */
add_action('init', function () {
    register_post_type('produit_createur', [
        'labels' => [
            'name' => __('Produits créateurs', 'anes-tetues'),
            'singular_name' => __('Produit créateur', 'anes-tetues'),
            'add_new' => __('Ajouter un produit créateur', 'anes-tetues'),
            'add_new_item' => __('Ajouter un produit créateur', 'anes-tetues'),
            'edit_item' => __('Modifier le produit créateur', 'anes-tetues'),
            'new_item' => __('Nouveau produit créateur', 'anes-tetues'),
            'view_item' => __('Voir le produit créateur', 'anes-tetues'),
            'search_items' => __('Rechercher un produit créateur', 'anes-tetues'),
            'not_found' => __('Aucun produit créateur trouvé', 'anes-tetues'),
            'not_found_in_trash' => __('Aucun produit créateur dans la corbeille', 'anes-tetues'),
            'all_items' => __('Tous les produits créateurs', 'anes-tetues'),
            'menu_name' => __('Produits créateurs', 'anes-tetues'),
        ],
        'public' => true,
        'has_archive' => false,
        'show_in_rest' => true,
        'menu_position' => 23,
        'menu_icon' => 'dashicons-cart',
        'supports' => ['title', 'thumbnail'],
        'rewrite' => [
            'slug' => 'produits-createurs',
            'with_front' => false,
        ],
    ]);

    register_post_type('reservation_createur', [
        'labels' => [
            'name' => __('Réservations créateurs', 'anes-tetues'),
            'singular_name' => __('Réservation créateur', 'anes-tetues'),
            'add_new' => __('Ajouter une réservation', 'anes-tetues'),
            'add_new_item' => __('Ajouter une réservation créateur', 'anes-tetues'),
            'edit_item' => __('Modifier la réservation créateur', 'anes-tetues'),
            'new_item' => __('Nouvelle réservation créateur', 'anes-tetues'),
            'view_item' => __('Voir la réservation créateur', 'anes-tetues'),
            'search_items' => __('Rechercher une réservation créateur', 'anes-tetues'),
            'not_found' => __('Aucune réservation trouvée', 'anes-tetues'),
            'not_found_in_trash' => __('Aucune réservation dans la corbeille', 'anes-tetues'),
            'all_items' => __('Toutes les réservations créateurs', 'anes-tetues'),
            'menu_name' => __('Réservations créateurs', 'anes-tetues'),
        ],
        'public' => false,
        'show_ui' => true,
        'show_in_menu' => true,
        'has_archive' => false,
        'show_in_rest' => false,
        'menu_position' => 24,
        'menu_icon' => 'dashicons-clipboard',
        'supports' => ['title'],
    ]);
});

/**
 * Métabox d'affichage des détails d'une réservation créateur.
 */
add_action('add_meta_boxes', function () {
    add_meta_box(
        'reservation_createur_details',
        __('Détails de la réservation créateur', 'anes-tetues'),
        function (\WP_Post $post) {
            if ($post->post_type !== 'reservation_createur') {
                return;
            }

            $order_id    = get_post_meta($post->ID, '_order_id', true);
            $order_num   = get_post_meta($post->ID, '_order_number', true);

            $customer    = [
                'name'    => get_post_meta($post->ID, '_customer_name', true),
                'email'   => get_post_meta($post->ID, '_customer_email', true),
                'phone'   => get_post_meta($post->ID, '_customer_phone', true),
                'address' => get_post_meta($post->ID, '_customer_address', true),
            ];

            $creator_id  = (int) get_post_meta($post->ID, '_creator_id', true);
            $creator     = [
                'name'  => get_post_meta($post->ID, '_creator_name', true),
                'email' => get_post_meta($post->ID, '_creator_email', true),
                'link'  => $creator_id ? get_edit_post_link($creator_id) : '',
            ];

            $product_id  = (int) get_post_meta($post->ID, '_product_id', true);
            $product     = [
                'name'  => get_post_meta($post->ID, '_product_name', true),
                'price' => get_post_meta($post->ID, '_product_price', true),
                'qty'   => get_post_meta($post->ID, '_quantity', true),
                'link'  => $product_id ? get_edit_post_link($product_id) : '',
            ];

            $order_link = $order_id ? admin_url('post.php?post='.$order_id.'&action=edit') : '';
            ?>
            <table class="form-table">
                <tbody>
                    <tr>
                        <th scope="row"><?php echo esc_html(__('Commande', 'anes-tetues')); ?></th>
                        <td>
                            <?php if ($order_link) : ?>
                                <a href="<?php echo esc_url($order_link); ?>">
                                    <?php echo esc_html(sprintf(__('Commande #%s', 'anes-tetues'), $order_num ?: $order_id)); ?>
                                </a>
                            <?php else : ?>
                                <?php echo esc_html($order_num ?: $order_id ?: '—'); ?>
                            <?php endif; ?>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html(__('Client', 'anes-tetues')); ?></th>
                        <td>
                            <?php if (! empty($customer['name'])) : ?>
                                <strong><?php echo esc_html($customer['name']); ?></strong><br>
                            <?php endif; ?>
                            <?php if (! empty($customer['address'])) : ?>
                                <span><?php echo nl2br(esc_html($customer['address'])); ?></span><br>
                            <?php endif; ?>
                            <?php if (! empty($customer['phone'])) : ?>
                                <span><?php echo esc_html($customer['phone']); ?></span><br>
                            <?php endif; ?>
                            <?php if (! empty($customer['email'])) : ?>
                                <a href="mailto:<?php echo esc_attr($customer['email']); ?>">
                                    <?php echo esc_html($customer['email']); ?>
                                </a>
                            <?php endif; ?>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html(__('Créateur', 'anes-tetues')); ?></th>
                        <td>
                            <?php if (! empty($creator['name'])) : ?>
                                <?php if ($creator['link']) : ?>
                                    <a href="<?php echo esc_url($creator['link']); ?>">
                                        <strong><?php echo esc_html($creator['name']); ?></strong>
                                    </a>
                                <?php else : ?>
                                    <strong><?php echo esc_html($creator['name']); ?></strong>
                                <?php endif; ?>
                                <br>
                            <?php endif; ?>
                            <?php if (! empty($creator['email'])) : ?>
                                <a href="mailto:<?php echo esc_attr($creator['email']); ?>">
                                    <?php echo esc_html($creator['email']); ?>
                                </a>
                            <?php endif; ?>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php echo esc_html(__('Produit réservé', 'anes-tetues')); ?></th>
                        <td>
                            <?php if (! empty($product['name'])) : ?>
                                <?php if ($product['link']) : ?>
                                    <a href="<?php echo esc_url($product['link']); ?>">
                                        <strong><?php echo esc_html($product['name']); ?></strong>
                                    </a>
                                <?php else : ?>
                                    <strong><?php echo esc_html($product['name']); ?></strong>
                                <?php endif; ?>
                                <br>
                            <?php endif; ?>
                            <?php if (! empty($product['qty'])) : ?>
                                <span><?php echo esc_html(sprintf(__('Quantité : %s', 'anes-tetues'), $product['qty'])); ?></span><br>
                            <?php endif; ?>
                            <?php if ($product['price'] !== '') : ?>
                                <?php
                                $formatted_price = number_format((float) $product['price'], 2, ',', ' ') . ' €';
                                ?>
                                <span><?php echo esc_html(sprintf(__('Prix unitaire : %s', 'anes-tetues'), $formatted_price)); ?></span>
                            <?php endif; ?>
                        </td>
                    </tr>
                </tbody>
            </table>
            <?php
        },
        'reservation_createur',
        'normal',
        'high'
    );
});

/**
 * Personnalise les URLs des produits créateurs pour les mettre en
 * sous-pages de leur créateur local :
 * createurs-locaux/{slug-createur}/{slug-produit}
 */
add_filter('post_type_link', function ($permalink, $post, $leavename, $sample) {
    if ($post->post_type !== 'produit_createur') {
        return $permalink;
    }

    // Champ ACF "createur" (relation vers createur_local)
    $createur_field = get_field('createur', $post->ID);
    if (empty($createur_field)) {
        return $permalink;
    }

    // Le champ peut être un tableau (plusieurs créateurs) ou un seul ID/objet
    $createur = is_array($createur_field) ? reset($createur_field) : $createur_field;

    if (is_numeric($createur)) {
        $createur_post = get_post((int) $createur);
    } elseif ($createur instanceof \WP_Post) {
        $createur_post = $createur;
    } else {
        return $permalink;
    }

    if (! $createur_post instanceof \WP_Post) {
        return $permalink;
    }

    $createur_slug = $createur_post->post_name;

    return home_url(user_trailingslashit(sprintf(
        'createurs-locaux/%s/%s',
        $createur_slug,
        $post->post_name
    )));
}, 10, 4);

/**
 * Règle de réécriture pour faire fonctionner les URLs
 * createurs-locaux/{slug-createur}/{slug-produit}
 * en pointant sur le CPT produit_createur.
 */
add_action('init', function () {
    add_rewrite_rule(
        '^createurs-locaux/([^/]+)/([^/]+)/?$',
        'index.php?post_type=produit_createur&name=$matches[2]',
        'top'
    );
}, 20);

/**
 * Register "Catégories" taxonomy for Partenaires.
 */
add_action('init', function () {
    register_taxonomy('partenaire_categorie', ['partenaire'], [
        'labels' => [
            'name' => __('Catégories', 'anes-tetues'),
            'singular_name' => __('Catégorie', 'anes-tetues'),
            'search_items' => __('Rechercher une catégorie', 'anes-tetues'),
            'all_items' => __('Toutes les catégories', 'anes-tetues'),
            'parent_item' => __('Catégorie parente', 'anes-tetues'),
            'parent_item_colon' => __('Catégorie parente :', 'anes-tetues'),
            'edit_item' => __('Modifier la catégorie', 'anes-tetues'),
            'update_item' => __('Mettre à jour la catégorie', 'anes-tetues'),
            'add_new_item' => __('Ajouter une nouvelle catégorie', 'anes-tetues'),
            'new_item_name' => __('Nouvelle catégorie', 'anes-tetues'),
            'menu_name' => __('Catégories', 'anes-tetues'),
        ],
        'public' => true,
        'hierarchical' => true,
        'show_ui' => true,
        'show_admin_column' => true,
        'show_in_rest' => true,
        'rewrite' => [
            'slug' => 'partenaires/categorie',
            'with_front' => false,
        ],
    ]);
});

/**
 * ACF: remplit dynamiquement les dates disponibles pour chaque artiste
 * en fonction des dates du prochain concert (page d’options).
 *
 * Nécessite un champ ACF "Checkbox" sur le CPT Line Up :
 * - Nom du champ : lineup_dates
 * - Type : checkbox
 * - Choices : laissés vides (remplis par ce filtre)
 */
add_filter('acf/load_field/name=lineup_dates', function (array $field): array {
    $dateDebut = get_field('date_de_debut', 'option');
    $dateFin   = get_field('date_de_fin', 'option');

    // Réinitialiser les choix
    $field['choices'] = [];

    if (!$dateDebut || !$dateFin) {
        return $field;
    }

    try {
        $start = \Carbon\Carbon::createFromFormat('d/m/Y', $dateDebut);
        $end   = \Carbon\Carbon::createFromFormat('d/m/Y', $dateFin);
    } catch (\Exception $e) {
        return $field;
    }

    if ($end->lessThan($start)) {
        [$start, $end] = [$end, $start];
    }

    // Génère une case à cocher pour chaque jour entre début et fin (inclus)
    for ($date = $start->copy(); $date->lte($end); $date->addDay()) {
        $value = $date->format('Y-m-d'); // valeur stockée
        $label = $date->locale('fr')->translatedFormat('d F Y'); // label lisible

        $field['choices'][$value] = $label;
    }

    return $field;
});

// Enlève l'éditeur de wp sur les pages sauf pour les pages "mentions-legales" et "politique-de-confidentialite"
function init_remove_support(): void
{
    $post_type = 'page';

    // Vérifiez si nous sommes dans l'éditeur de page
    if (isset($_GET['post'])) {
        $post_id = $_GET['post'];
        $post = get_post($post_id);

        // Vérifiez si le post est une page et son post_name
        if ($post && $post->post_type === $post_type && $post->post_name) {
            $post_name = $post->post_name;

            // Vérifiez si la page est "mentions-legales" ou "politique-de-confidentialite"
            if ($post_name === 'mentions-legales' || $post_name === 'politique-de-confidentialite' || $post_name === 'newsletter') {
                return; // Ne rien faire, permettre l'éditeur de contenu pour ces pages
            }
        }
    }

    // Si ce n'est pas "mentions-legales" ou "politique-de-confidentialite", supprimer le support
    remove_post_type_support($post_type, 'editor');
    remove_post_type_support($post_type, 'comments');
    remove_post_type_support($post_type, 'author');
}
add_action('admin_init', function () {
    init_remove_support();
});

add_theme_support('custom-logo');

add_action('after_setup_theme', function () {
    add_theme_support('woocommerce');
}, 20);

/**
 * Empêche WooCommerce d'ajouter automatiquement son message
 * "Votre panier est vide" via le hook `woocommerce_cart_is_empty`.
 * On gère nous-même l'affichage du message + bouton.
 */
add_action('init', function () {
    if (function_exists('wc_empty_cart_message')) {
        remove_action('woocommerce_cart_is_empty', 'wc_empty_cart_message', 10);
    }

    // On remplace aussi le rendu du bouton "Procéder au paiement"
    // pour pouvoir insérer le tableau des réservations juste avant.
    if (function_exists('woocommerce_button_proceed_to_checkout')) {
        remove_action('woocommerce_proceed_to_checkout', 'woocommerce_button_proceed_to_checkout', 20);

        add_action('woocommerce_proceed_to_checkout', function () {
            if (function_exists('WC') && WC()->session) {
                $reservations = WC()->session->get('createur_reservations', []);

                if (is_array($reservations) && ! empty($reservations)) {
                    echo \Roots\view('partials.cart-reservations', [
                        'reservations'      => $reservations,
                        'sectionClasses'    => '',
                        'showReserveButton' => false,
                    ]);
                }
            }

            // Bouton WooCommerce standard
            woocommerce_button_proceed_to_checkout();
        }, 20);
    }
});

/**
 * Gestion des "produits créateurs" en session de réservation :
 * - ajout depuis la fiche produit
 * - suppression depuis le panier.
 *
 * Les données sont stockées séparément du panier WooCommerce
 * dans WC()->session['createur_reservations'].
 *
 * Utilise le hook `wp` plutôt que `template_redirect` pour s'assurer
 * que la logique est exécutée sur les pages de type `produit_createur`,
 * même si d'autres extensions interfèrent avec `template_redirect`.
 */
add_action('wp', function () {
    if (! function_exists('WC')) {
        return;
    }

    // Si la session WooCommerce n'est pas initialisée, on affiche au moins
    // un message explicite au client pour éviter l'impression que rien ne se passe.
    if (! WC()->session) {
        if (function_exists('wc_add_notice')) {
            wc_add_notice(
                __('Les réservations ne sont pas disponibles pour le moment (session WooCommerce non initialisée).', 'anes-tetues'),
                'error'
            );
        }
        return;
    }

    // Récupère la liste actuelle en session
    $reservations = WC()->session->get('createur_reservations', []);
    if (! is_array($reservations)) {
        $reservations = [];
    }

    // 1) Suppression d'une réservation depuis le panier
    if (! empty($_POST['remove_produit_createur_reservation']) && ! empty($_POST['produit_createur_id'])) {
        $produit_createur_id = (int) $_POST['produit_createur_id'];

        if (isset($reservations[$produit_createur_id])) {
            unset($reservations[$produit_createur_id]);
            WC()->session->set('createur_reservations', $reservations);

            wc_add_notice(__('Réservation supprimée.', 'anes-tetues'));
        }

        // Retourne là d'où vient l'action (panier, etc.)
        $fallback_url = function_exists('wc_get_cart_url') ? wc_get_cart_url() : home_url('/');
        $redirect_url = wp_get_referer() ?: $fallback_url;
        wp_safe_redirect($redirect_url);
        exit;
    }

    // 2) Soumission des réservations seules (sans produits WooCommerce)
    if (! empty($_POST['submit_createur_reservations_only'])) {
        if (empty($reservations)) {
            wc_add_notice(__('Aucune réservation à valider.', 'anes-tetues'), 'error');
        } else {
            $name  = isset($_POST['reservation_customer_name']) ? trim(wp_unslash($_POST['reservation_customer_name'])) : '';
            $email = isset($_POST['reservation_customer_email']) ? trim(wp_unslash($_POST['reservation_customer_email'])) : '';
            $phone = isset($_POST['reservation_customer_phone']) ? trim(wp_unslash($_POST['reservation_customer_phone'])) : '';

            if (! is_email($email)) {
                wc_add_notice(__('Merci de renseigner un email valide pour vos réservations.', 'anes-tetues'), 'error');
            } else {
                // On enrichit d'abord les réservations (titre produit, prix, créateur...)
                $enriched = [];

                foreach ($reservations as $reservation) {
                    if (! isset($reservation['produit_createur_id'])) {
                        continue;
                    }

                    $produit_id = (int) $reservation['produit_createur_id'];
                    if (! $produit_id) {
                        continue;
                    }

                    $quantity = isset($reservation['quantity']) ? (int) $reservation['quantity'] : 1;
                    $quantity = $quantity > 0 ? $quantity : 1;

                    $post = get_post($produit_id);
                    if (! $post) {
                        continue;
                    }

                    $title = get_the_title($produit_id);
                    $price = get_field('prix', $produit_id);

                    $creator_id    = null;
                    $creator_name  = '';
                    $creator_email = '';

                    $creator_field = get_field('createur', $produit_id);

                    if (is_array($creator_field) && ! empty($creator_field)) {
                        $first = reset($creator_field);
                        if ($first instanceof \WP_Post) {
                            $creator_id = $first->ID;
                        } elseif (is_numeric($first)) {
                            $creator_id = (int) $first;
                        }
                    } elseif ($creator_field instanceof \WP_Post) {
                        $creator_id = $creator_field->ID;
                    } elseif (is_numeric($creator_field)) {
                        $creator_id = (int) $creator_field;
                    }

                    if ($creator_id) {
                        $creator_name = get_the_title($creator_id);

                        $creator_infos = get_field('informations', $creator_id);
                        if (is_array($creator_infos) && ! empty($creator_infos['mail'])) {
                            $creator_email = (string) $creator_infos['mail'];
                        }
                    }

                    $enriched[] = [
                        'produit_createur_id'    => $produit_id,
                        'produit_createur_titre' => $title,
                        'produit_createur_prix'  => $price !== null ? (float) $price : null,
                        'quantity'               => $quantity,
                        'createur_id'            => $creator_id,
                        'createur_nom'           => $creator_name,
                        'creator_email'          => $creator_email,
                    ];
                }

                $reservations = $enriched;

                // On réutilise la logique d'enregistrement et d'envoi d'emails,
                // mais sans commande WooCommerce : on crée l'équivalent d'un "numéro de réservation".
                $reservation_number = 'R-' . date('Ymd-His');

                $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES);
                $headers  = ['Content-Type: text/html; charset=UTF-8'];

                // Création des CPT reservation_createur (une par ligne)
                foreach ($reservations as $item) {
                    if (empty($item['createur_id']) || empty($item['produit_createur_id'])) {
                        continue;
                    }

                    $creator_id = (int) $item['createur_id'];
                    $produit_id = (int) $item['produit_createur_id'];

                    $quantity = isset($item['quantity']) ? (int) $item['quantity'] : 1;
                    $quantity = $quantity > 0 ? $quantity : 1;

                    $price = isset($item['produit_createur_prix']) ? (float) $item['produit_createur_prix'] : null;

                    $creator_name = $item['createur_nom'] ?? get_the_title($creator_id);
                    $product_name = $item['produit_createur_titre'] ?? get_the_title($produit_id);

                    $post_id = wp_insert_post([
                        'post_type'   => 'reservation_createur',
                        'post_status' => 'publish',
                        'post_title'  => sprintf(
                            __('Réservation %s – %s', 'anes-tetues'),
                            $reservation_number,
                            $product_name
                        ),
                    ]);

                    if ($post_id && ! is_wp_error($post_id)) {
                        update_post_meta($post_id, '_order_id', 0);
                        update_post_meta($post_id, '_order_number', $reservation_number);

                        update_post_meta($post_id, '_customer_name', $name);
                        update_post_meta($post_id, '_customer_email', $email);
                        update_post_meta($post_id, '_customer_phone', $phone);
                        update_post_meta($post_id, '_customer_address', '');

                        update_post_meta($post_id, '_creator_id', $creator_id);
                        update_post_meta($post_id, '_creator_name', $creator_name);
                        update_post_meta($post_id, '_creator_email', $item['creator_email'] ?? '');

                        update_post_meta($post_id, '_product_id', $produit_id);
                        update_post_meta($post_id, '_product_name', $product_name);
                        update_post_meta($post_id, '_product_price', $price);
                        update_post_meta($post_id, '_quantity', $quantity);
                    }
                }

                // Envoi des emails (client + créateurs) via le mailer WooCommerce
                $mailer = WC()->mailer();

                // On fabrique un petit objet avec une méthode get_order_number()
                // pour réutiliser les templates existants.
                $order_like = new class($reservation_number) {
                    private $number;
                    public function __construct($number) { $this->number = $number; }
                    public function get_order_number() { return $this->number; }
                };

                // Email client
                if (! empty($email)) {
                    $subject = sprintf(
                        __('Vos réservations chez %s', 'anes-tetues'),
                        $blogname
                    );

                    $body = \Roots\view('emails.reservations-customer', [
                        'order'          => $order_like,
                        'reservations'   => array_values($reservations),
                        'customer_name'  => $name,
                        'customer_email' => $email,
                        'site_name'      => $blogname,
                    ]);

                    $mailer->send($email, $subject, $body, $headers);
                }

                // Emails créateurs
                $by_creator = [];
                foreach ($reservations as $item) {
                    $creator_id = $item['createur_id'] ?? null;
                    if (! $creator_id) {
                        continue;
                    }

                    if (! isset($by_creator[$creator_id])) {
                        $by_creator[$creator_id] = [
                            'creator_id'    => $creator_id,
                            'creator_nom'   => $item['createur_nom'] ?? '',
                            'creator_email' => $item['creator_email'] ?? '',
                            'items'         => [],
                        ];
                    }

                    $by_creator[$creator_id]['items'][] = $item;
                }

                if (! empty($by_creator)) {
                    foreach ($by_creator as $creator) {
                        $to = trim((string) ($creator['creator_email'] ?? ''));
                        if ($to === '') {
                            continue;
                        }

                        $creator_name = $creator['creator_nom'] ?: __('Créateur', 'anes-tetues');

                        $subject = sprintf(
                            __('Nouvelles réservations via %s', 'anes-tetues'),
                            $blogname
                        );

                        $body = \Roots\view('emails.reservations-creator', [
                            'order'          => $order_like,
                            'creator_name'   => $creator_name,
                            'creator_email'  => $to,
                            'reservations'   => $creator['items'],
                            'customer_name'  => $name,
                            'customer_email' => $email,
                            'site_name'      => $blogname,
                        ]);

                        $mailer->send($to, $subject, $body, $headers);
                    }
                }

                // On vide les réservations de session après traitement
                WC()->session->set('createur_reservations', []);

                wc_add_notice(__('Vos réservations ont bien été envoyées.', 'anes-tetues'));
            }
        }

        $fallback_url = function_exists('wc_get_cart_url') ? wc_get_cart_url() : home_url('/');
        $redirect_url = wp_get_referer() ?: $fallback_url;
        wp_safe_redirect($redirect_url);
        exit;
    }

    // 3) Ajout d'une réservation depuis la fiche produit créateur
    // On accepte désormais aussi bien POST que GET pour être plus robuste
    // face à d'éventuelles redirections qui convertiraient la requête.
    $source = null;
    if (! empty($_POST['produit_createur_reservation']) && ! empty($_POST['produit_createur_id'])) {
        $source = $_POST;
    } elseif (! empty($_GET['produit_createur_reservation']) && ! empty($_GET['produit_createur_id'])) {
        $source = $_GET;
    }

    if (! $source) {
        return;
    }

    $produit_createur_id = (int) $source['produit_createur_id'];
    $quantity            = isset($source['reservation_quantity']) ? (int) $source['reservation_quantity'] : 1;
    $quantity            = $quantity > 0 ? $quantity : 1;

    // On regroupe les quantités par produit créateur
    if (isset($reservations[$produit_createur_id])) {
        $reservations[$produit_createur_id]['quantity'] += $quantity;
    } else {
        $reservations[$produit_createur_id] = [
            'produit_createur_id' => $produit_createur_id,
            'quantity'            => $quantity,
        ];
    }

    // Sauvegarde en session WooCommerce
    WC()->session->set('createur_reservations', $reservations);

    // Message de confirmation pour l’utilisateur
    wc_add_notice(__('Produit ajouté à votre liste de réservation.', 'anes-tetues'));

    // Retourne sur la page d’où vient l’ajout (fiche produit en général)
    $fallback_url = get_permalink($produit_createur_id) ?: (function_exists('wc_get_cart_url') ? wc_get_cart_url() : home_url('/'));
    $redirect_url = wp_get_referer() ?: $fallback_url;
    wp_safe_redirect($redirect_url);
    exit;
});

/**
 * Cart front: message + bouton vers la boutique quand le panier est vide.
 */
add_action('woocommerce_cart_is_empty', function () {
    // Message unique "panier vide"
    echo '<div class="wc-empty-cart-message">';
    echo '<div class="cart-empty woocommerce-info" role="status">';
    echo esc_html__('Votre panier est actuellement vide.', 'woocommerce');
    echo '</div>';
    echo '</div>';

    // Si des réservations existent en session, on affiche quand même le bloc
    // "Réservations" avec un bouton "Réserver".
    if (function_exists('WC') && WC()->session) {
        $reservations = WC()->session->get('createur_reservations', []);

        if (is_array($reservations) && ! empty($reservations)) {
            echo \Roots\view('partials.cart-reservations', [
                'reservations'      => $reservations,
                'sectionClasses'    => 'mb',
                'showReserveButton' => true,
            ]);
        }
    }

    // Bouton "Voir la boutique"
    $shop_url = function_exists('wc_get_page_permalink') ? wc_get_page_permalink('shop') : home_url('/');

    echo sprintf(
        '<div class="cart-empty-back-shop"><a href="%s" class="btn bg-secondary arrow-primary">%s</a></div>',
        esc_url($shop_url),
        esc_html__('Voir la boutique', 'anes-tetues')
    );
}, 20);

/**
 * Quand la commande arrive sur la page "merci",
 * on :
 * - copie les réservations créateurs de la session vers la commande (si besoin) ;
 * - envoie un mail récap au client ;
 * - envoie un mail à chaque créateur concerné.
 */
add_action('woocommerce_thankyou', function ($order_id) {
    $order = wc_get_order($order_id);

    if (! $order) {
        return;
    }

    // On évite les doublons si jamais le hook est appelé plusieurs fois.
    $already_sent = get_post_meta($order_id, '_createur_reservations_emails_sent', true);
    if ($already_sent) {
        return;
    }

    // 1) Récupération des réservations associées à la commande.
    $reservations = get_post_meta($order_id, '_createur_reservations', true);

    // Si aucune meta n'est encore enregistrée, on tente de les récupérer depuis la session.
    if (! is_array($reservations) || empty($reservations)) {
        if (function_exists('WC') && WC()->session) {
            $session_reservations = WC()->session->get('createur_reservations', []);

            if (is_array($session_reservations) && ! empty($session_reservations)) {
                $enriched = [];

                foreach ($session_reservations as $reservation) {
                    if (! isset($reservation['produit_createur_id'])) {
                        continue;
                    }

                    $produit_id = (int) $reservation['produit_createur_id'];
                    if (! $produit_id) {
                        continue;
                    }

                    $quantity = isset($reservation['quantity']) ? (int) $reservation['quantity'] : 1;
                    $quantity = $quantity > 0 ? $quantity : 1;

                    $post = get_post($produit_id);
                    if (! $post) {
                        continue;
                    }

                    $title = get_the_title($produit_id);
                    $price = get_field('prix', $produit_id);

                    $creator_id    = null;
                    $creator_name  = '';
                    $creator_email = '';

                    // Champ ACF "createur" sur le CPT produit_createur
                    // type = relationship, return_format = object, min/max = 1
                    $creator_field = get_field('createur', $produit_id);

                    if (is_array($creator_field) && ! empty($creator_field)) {
                        // Relationship retourne un tableau d'objets WP_Post
                        $first = reset($creator_field);
                        if ($first instanceof \WP_Post) {
                            $creator_id = $first->ID;
                        } elseif (is_numeric($first)) {
                            $creator_id = (int) $first;
                        }
                    } elseif ($creator_field instanceof \WP_Post) {
                        $creator_id = $creator_field->ID;
                    } elseif (is_numeric($creator_field)) {
                        $creator_id = (int) $creator_field;
                    }

                    if ($creator_id) {
                        $creator_name = get_the_title($creator_id);

                        // Sur le CPT createur_local, l'email est dans le group "informations" > "mail"
                        $creator_infos = get_field('informations', $creator_id);
                        if (is_array($creator_infos) && ! empty($creator_infos['mail'])) {
                            $creator_email = (string) $creator_infos['mail'];
                        }
                    }

                    $enriched[] = [
                        'produit_createur_id'    => $produit_id,
                        'produit_createur_titre' => $title,
                        'produit_createur_prix'  => $price !== null ? (float) $price : null,
                        'quantity'               => $quantity,
                        'createur_id'            => $creator_id,
                        'createur_nom'           => $creator_name,
                        'creator_email'          => $creator_email,
                    ];
                }

                if (! empty($enriched)) {
                    $reservations = $enriched;
                    update_post_meta($order_id, '_createur_reservations', $reservations);

                    // On nettoie la session une fois qu'on a tout recopié vers la commande.
                    WC()->session->set('createur_reservations', []);
                }
            }
        }
    }

    $blogname        = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES);
    $customer_email  = $order->get_billing_email();
    $customer_name   = trim($order->get_billing_first_name() . ' ' . $order->get_billing_last_name());
    $customer_phone  = $order->get_billing_phone();
    $customer_adress = trim($order->get_billing_address_1() . ' ' . $order->get_billing_postcode() . ' ' . $order->get_billing_city());

    $headers = [
        'Content-Type: text/html; charset=UTF-8',
    ];

    // Si aucune réservation, on sort.
    if (! is_array($reservations) || empty($reservations)) {
        return;
    }

    // 2) Enregistrement dans le CPT reservation_createur (une entrée par ligne de réservation).
    foreach ($reservations as $item) {
        $creator_id = $item['createur_id'] ?? null;
        if (! $creator_id) {
            continue;
        }

        $produit_id = $item['produit_createur_id'] ?? null;

        $quantity = isset($item['quantity']) ? (int) $item['quantity'] : 1;
        $quantity = $quantity > 0 ? $quantity : 1;

        $price = isset($item['produit_createur_prix']) ? (float) $item['produit_createur_prix'] : null;

        $creator_name = $item['createur_nom'] ?? get_the_title($creator_id);
        $product_name = $item['produit_createur_titre'] ?? ($produit_id ? get_the_title($produit_id) : '');

        $post_id = wp_insert_post([
            'post_type'   => 'reservation_createur',
            'post_status' => 'publish',
            'post_title'  => sprintf(
                __('Réservation %s – %s', 'anes-tetues'),
                $order->get_order_number(),
                $product_name
            ),
        ]);

        if ($post_id && ! is_wp_error($post_id)) {
            update_post_meta($post_id, '_order_id', $order_id);
            update_post_meta($post_id, '_order_number', $order->get_order_number());

            update_post_meta($post_id, '_customer_name', $customer_name);
            update_post_meta($post_id, '_customer_email', $customer_email);
            update_post_meta($post_id, '_customer_phone', $customer_phone);
            update_post_meta($post_id, '_customer_address', $customer_adress);

            update_post_meta($post_id, '_creator_id', $creator_id);
            update_post_meta($post_id, '_creator_name', $creator_name);
            update_post_meta($post_id, '_creator_email', $item['creator_email'] ?? '');

            update_post_meta($post_id, '_product_id', $produit_id);
            update_post_meta($post_id, '_product_name', $product_name);
            update_post_meta($post_id, '_product_price', $price);
            update_post_meta($post_id, '_quantity', $quantity);
        }
    }

    $mailer = function_exists('WC') ? WC()->mailer() : null;

    // 2) Email client.
    if ($mailer && ! empty($customer_email)) {
        $subject = sprintf(
            __('Vos réservations chez %s', 'anes-tetues'),
            $blogname
        );

        $body = \Roots\view('emails.reservations-customer', [
            'order'          => $order,
            'reservations'   => $reservations,
            'customer_name'  => $customer_name,
            'customer_email' => $customer_email,
            'site_name'      => $blogname,
        ]);

        $mailer->send($customer_email, $subject, $body, $headers);
    }

    // 3) Emails aux créateurs (groupés par créateur).
    if ($mailer) {
        $by_creator = [];

        foreach ($reservations as $item) {
            $creator_id = $item['createur_id'] ?? null;
            if (! $creator_id) {
                continue;
            }

            if (! isset($by_creator[$creator_id])) {
                $by_creator[$creator_id] = [
                    'creator_id'    => $creator_id,
                    'creator_nom'   => $item['createur_nom'] ?? '',
                    'creator_email' => $item['creator_email'] ?? '',
                    'items'         => [],
                ];
            }

            $by_creator[$creator_id]['items'][] = $item;
        }

        if (! empty($by_creator)) {
            foreach ($by_creator as $creator) {
                $to = trim((string) ($creator['creator_email'] ?? ''));
                if ($to === '') {
                    continue;
                }

                $creator_name = $creator['creator_nom'] ?: __('Créateur', 'anes-tetues');

                $subject = sprintf(
                    __('Nouvelles réservations via %s', 'anes-tetues'),
                    $blogname
                );

                $body = \Roots\view('emails.reservations-creator', [
                    'order'          => $order,
                    'creator_name'   => $creator_name,
                    'creator_email'  => $to,
                    'reservations'   => $creator['items'],
                    'customer_name'  => $customer_name,
                    'customer_email' => $customer_email,
                    'site_name'      => $blogname,
                ]);

                $mailer->send($to, $subject, $body, $headers);
            }
        }
    }

    // Marqueur pour ne pas renvoyer plusieurs fois les mêmes emails.
    update_post_meta($order_id, '_createur_reservations_emails_sent', 1);
}, 10, 1);