2026-04-03
This commit is contained in:
parent
15371d2469
commit
5f835ca4e6
45 changed files with 819 additions and 626 deletions
|
|
@ -25,7 +25,7 @@ $templates = ['404.twig'];
|
|||
function load_page_resources(): void {
|
||||
Resource::enqueue_style_file(
|
||||
handle: 'haiku-atelier-2024-styles-page-a-propos',
|
||||
path: '/assets/css/pages/page-modele-simple.css'
|
||||
path: '/assets/css/pages/page-modele-simple.css',
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -33,5 +33,5 @@ add_action('wp_enqueue_scripts', load_page_resources(...));
|
|||
|
||||
Timber::render(
|
||||
data: $context,
|
||||
filenames: $templates
|
||||
filenames: $templates,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ $wc_products = wc_get_products(['limit' => 12, 'order' => 'DESC', 'orderby' => '
|
|||
|
||||
$products = array_map(
|
||||
callback: Product::new(...),
|
||||
array: $wc_products
|
||||
array: $wc_products,
|
||||
);
|
||||
$context['products'] = $products;
|
||||
|
||||
|
|
@ -40,15 +40,15 @@ $context['products'] = $products;
|
|||
function load_page_resources(): void {
|
||||
Resource::enqueue_style_file(
|
||||
handle: 'haiku-atelier-2024-styles-page-boutique',
|
||||
path: '/assets/css/pages/page-boutique.css'
|
||||
path: '/assets/css/pages/page-boutique.css',
|
||||
);
|
||||
Resource::enqueue_script_module_file(
|
||||
id: 'haiku-atelier-2024-scripts-page-boutique',
|
||||
path: '/assets/js/scripts-page-boutique.js'
|
||||
path: '/assets/js/scripts-page-boutique.js',
|
||||
);
|
||||
Resource::enqueue_script_module_file(
|
||||
id: 'haiku-atelier-2024-scripts-menu-categories',
|
||||
path: '/assets/js/scripts-menu-categories.js'
|
||||
path: '/assets/js/scripts-menu-categories.js',
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -56,5 +56,5 @@ add_action('wp_enqueue_scripts', load_page_resources(...));
|
|||
|
||||
Timber::render(
|
||||
data: $context,
|
||||
filenames: $templates
|
||||
filenames: $templates,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -22,20 +22,20 @@ $templates = ['accueil.twig'];
|
|||
*
|
||||
* @throws Exception une exception est levée s'il est impossible d'obtenir la date de modification du fichier à charger
|
||||
*/
|
||||
function load_resources(): void {
|
||||
function load_page_resources(): void {
|
||||
Resource::enqueue_style_file(
|
||||
handle: 'haiku-atelier-2024-styles-page-accueil',
|
||||
path: '/assets/css/pages/page-accueil.css'
|
||||
path: '/assets/css/pages/page-accueil.css',
|
||||
);
|
||||
Resource::enqueue_script_module_file(
|
||||
id: 'haiku-atelier-2024-scripts-page-accueil',
|
||||
path: '/assets/js/scripts-page-accueil.js'
|
||||
path: '/assets/js/scripts-page-accueil.js',
|
||||
);
|
||||
}
|
||||
|
||||
add_action('wp_enqueue_scripts', load_resources(...));
|
||||
add_action('wp_enqueue_scripts', load_page_resources(...));
|
||||
|
||||
Timber::render(
|
||||
data: $context,
|
||||
filenames: $templates
|
||||
filenames: $templates,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -33,19 +33,19 @@ function load_scripts(): void {
|
|||
id: 'haiku-atelier-2024-bouton-panier',
|
||||
deps: [],
|
||||
src: get_template_directory_uri() . '/assets/js/scripts-bouton-panier.js',
|
||||
version: filemtime(get_template_directory() . '/assets/js/scripts-bouton-panier.js')
|
||||
version: filemtime(get_template_directory() . '/assets/js/scripts-bouton-panier.js'),
|
||||
);
|
||||
wp_enqueue_script_module(
|
||||
id: 'haiku-atelier-2024-menu-mobile',
|
||||
deps: [],
|
||||
src: get_template_directory_uri() . '/assets/js/scripts-menu-mobile.js',
|
||||
version: filemtime(get_template_directory() . '/assets/js/scripts-menu-mobile.js')
|
||||
version: filemtime(get_template_directory() . '/assets/js/scripts-menu-mobile.js'),
|
||||
);
|
||||
wp_enqueue_script_module(
|
||||
id: 'haiku-atelier-2024-bouton-retour-sommet',
|
||||
deps: [],
|
||||
src: get_template_directory_uri() . '/assets/js/scripts-bouton-retour-sommet.js',
|
||||
version: filemtime(get_template_directory() . '/assets/js/scripts-bouton-retour-sommet.js')
|
||||
version: filemtime(get_template_directory() . '/assets/js/scripts-bouton-retour-sommet.js'),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -58,7 +58,7 @@ function charge_styles_haiku_atelier_2024(): void {
|
|||
src: get_template_directory_uri() . '/assets/css/main.css',
|
||||
deps: [],
|
||||
ver: filemtime(get_template_directory() . '/assets/css/main.css'),
|
||||
media: 'all'
|
||||
media: 'all',
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ function enregistre_personnalisations_theme(mixed $wp_customize): void {
|
|||
// Section « Réseaux sociaux »
|
||||
$wp_customize->add_section('liens_reseaux_sociaux', [
|
||||
'title' => __('Liens des réseaux sociaux'),
|
||||
'description' => __("Liens des réseaux sociaux s'affichant dans le pied de page.")
|
||||
'description' => __("Liens des réseaux sociaux s'affichant dans le pied de page."),
|
||||
]);
|
||||
|
||||
// Instagram
|
||||
|
|
@ -82,7 +82,7 @@ function enregistre_personnalisations_theme(mixed $wp_customize): void {
|
|||
$wp_customize->add_control('lien_instagram', [
|
||||
'type' => 'url',
|
||||
'section' => 'liens_reseaux_sociaux',
|
||||
'label' => __('Profil Instagram')
|
||||
'label' => __('Profil Instagram'),
|
||||
]);
|
||||
|
||||
// Facebook
|
||||
|
|
@ -90,7 +90,7 @@ function enregistre_personnalisations_theme(mixed $wp_customize): void {
|
|||
$wp_customize->add_control('lien_facebook', [
|
||||
'type' => 'url',
|
||||
'section' => 'liens_reseaux_sociaux',
|
||||
'label' => __('Profil Facebook')
|
||||
'label' => __('Profil Facebook'),
|
||||
]);
|
||||
|
||||
// Pinterest
|
||||
|
|
@ -98,13 +98,13 @@ function enregistre_personnalisations_theme(mixed $wp_customize): void {
|
|||
$wp_customize->add_control('lien_pinterest', [
|
||||
'type' => 'url',
|
||||
'section' => 'liens_reseaux_sociaux',
|
||||
'label' => __('Profil Pinterest')
|
||||
'label' => __('Profil Pinterest'),
|
||||
]);
|
||||
|
||||
// Section « Descriptions Produits »
|
||||
$wp_customize->add_section('descriptions_produits', [
|
||||
'title' => __('Textes des descriptions Produits'),
|
||||
'description' => __('Textes des descriptions apparaissant sur les pages Produit.')
|
||||
'description' => __('Textes des descriptions apparaissant sur les pages Produit.'),
|
||||
]);
|
||||
|
||||
$wp_customize->add_setting('texte_conditions_livraison', [
|
||||
|
|
@ -112,7 +112,7 @@ function enregistre_personnalisations_theme(mixed $wp_customize): void {
|
|||
'default' => '',
|
||||
'sanitize_callback' => 'wp_kses_post',
|
||||
'transport' => 'postMessage',
|
||||
'type' => 'theme_mod'
|
||||
'type' => 'theme_mod',
|
||||
]);
|
||||
$wp_customize->add_control(new Controle_Personnalise_TinyMCE($wp_customize, 'texte_conditions_livraison', [
|
||||
'label' => __('Conditions de livraison'),
|
||||
|
|
@ -120,8 +120,8 @@ function enregistre_personnalisations_theme(mixed $wp_customize): void {
|
|||
'section' => 'descriptions_produits',
|
||||
'input_attrs' => [
|
||||
'toolbar1' => 'bold italic bullist numlist alignleft aligncenter alignright link',
|
||||
'mediaButtons' => true
|
||||
]
|
||||
'mediaButtons' => true,
|
||||
],
|
||||
]));
|
||||
|
||||
$wp_customize->add_setting('texte_entretien_produit', [
|
||||
|
|
@ -129,7 +129,7 @@ function enregistre_personnalisations_theme(mixed $wp_customize): void {
|
|||
'default' => '',
|
||||
'sanitize_callback' => 'wp_kses_post',
|
||||
'transport' => 'postMessage',
|
||||
'type' => 'theme_mod'
|
||||
'type' => 'theme_mod',
|
||||
]);
|
||||
$wp_customize->add_control(new Controle_Personnalise_TinyMCE($wp_customize, 'texte_entretien_produit', [
|
||||
'label' => __('Entretien du Produit'),
|
||||
|
|
@ -137,8 +137,8 @@ function enregistre_personnalisations_theme(mixed $wp_customize): void {
|
|||
'section' => 'descriptions_produits',
|
||||
'input_attrs' => [
|
||||
'toolbar1' => 'bold italic bullist numlist alignleft aligncenter alignright link',
|
||||
'mediaButtons' => true
|
||||
]
|
||||
'mediaButtons' => true,
|
||||
],
|
||||
]));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,5 +9,5 @@ $templates = ['base.twig'];
|
|||
|
||||
Timber::render(
|
||||
data: $context,
|
||||
filenames: $templates
|
||||
filenames: $templates,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -34,20 +34,20 @@ $context['image_dimensions'] = $image_dimensions;
|
|||
*
|
||||
* @throws Exception une exception est levée s'il est impossible d'obtenir la date de modification du fichier à charger
|
||||
*/
|
||||
function load_resources(): void {
|
||||
function load_page_resources(): void {
|
||||
Resource::enqueue_style_file(
|
||||
handle: 'haiku-atelier-2024-styles-page-a-propos',
|
||||
path: '/assets/css/pages/page-a-propos.css'
|
||||
path: '/assets/css/pages/page-a-propos.css',
|
||||
);
|
||||
Resource::enqueue_script_module_file(
|
||||
id: 'haiku-atelier-2024-scripts-page-a-propos',
|
||||
path: '/assets/js/scripts-page-a-propos.js'
|
||||
path: '/assets/js/scripts-page-a-propos.js',
|
||||
);
|
||||
}
|
||||
|
||||
add_action('wp_enqueue_scripts', load_resources(...));
|
||||
add_action('wp_enqueue_scripts', load_page_resources(...));
|
||||
|
||||
Timber::render(
|
||||
data: $context,
|
||||
filenames: $templates
|
||||
filenames: $templates,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -9,127 +9,47 @@ declare(strict_types=1);
|
|||
namespace HaikuAtelier;
|
||||
|
||||
use Exception;
|
||||
use HaikuAtelier\Data\Cart;
|
||||
use HaikuAtelier\WP\Resource;
|
||||
use Illuminate\Support\Number;
|
||||
use Timber\Timber;
|
||||
use WC_Shipping_Rate;
|
||||
|
||||
use function add_action;
|
||||
use function collect;
|
||||
use function Crell\fp\pipe;
|
||||
use function filemtime;
|
||||
use function genere_balise_img_multiformats;
|
||||
use function get_template_directory;
|
||||
use function get_template_directory_uri;
|
||||
use function is_bool;
|
||||
use function recupere_et_formate_attributs_produit;
|
||||
use function WC;
|
||||
use function wp_enqueue_script_module;
|
||||
use function wp_enqueue_style;
|
||||
|
||||
// Importe la fonction pour récupérer les informations affichées des Produits dans le Panier
|
||||
require_once __DIR__ . '/src/inc/TraitementInformations.php';
|
||||
|
||||
// Contexte et modèles
|
||||
$contexte = Timber::context();
|
||||
$modeles = ['panier.twig'];
|
||||
|
||||
$allowed_countries = [
|
||||
'AD',
|
||||
'AL',
|
||||
'AM',
|
||||
'AR',
|
||||
'AT',
|
||||
'AU',
|
||||
'BA',
|
||||
'BE',
|
||||
'BG',
|
||||
'BR',
|
||||
'CA',
|
||||
'CH',
|
||||
'CL',
|
||||
'CR',
|
||||
'CU',
|
||||
'CY',
|
||||
'CZ',
|
||||
'DE',
|
||||
'DK',
|
||||
'DZ',
|
||||
'EE',
|
||||
'EG',
|
||||
'ES',
|
||||
'FI',
|
||||
'FR',
|
||||
'GF',
|
||||
'GP',
|
||||
'GR',
|
||||
'HR',
|
||||
'HU',
|
||||
'IE',
|
||||
'IS',
|
||||
'IT',
|
||||
'JP',
|
||||
'KR',
|
||||
'LB',
|
||||
'LI',
|
||||
'LT',
|
||||
'LU',
|
||||
'LV',
|
||||
'MA',
|
||||
'MD',
|
||||
'ME',
|
||||
'MF',
|
||||
'MQ',
|
||||
'MT',
|
||||
'MX',
|
||||
'NC',
|
||||
'NL',
|
||||
'NO',
|
||||
'NZ',
|
||||
'PF',
|
||||
'PL',
|
||||
'PM',
|
||||
'PS',
|
||||
'PT',
|
||||
'RE',
|
||||
'RO',
|
||||
'SE',
|
||||
'SI',
|
||||
'SK',
|
||||
'SM',
|
||||
'TN',
|
||||
'TR',
|
||||
'TW',
|
||||
'US',
|
||||
'YT',
|
||||
'ZA'
|
||||
];
|
||||
$context = Timber::context();
|
||||
$templates = ['panier.twig'];
|
||||
|
||||
// Récupère les informations affichés des Produits du Panier
|
||||
$cart = [];
|
||||
|
||||
/** Le sous-total de la Commande dans le Panier. */
|
||||
$cart_subtotal = WC()->cart->get_subtotal();
|
||||
/** @var array<string,int> */
|
||||
$cart_totals = WC()->cart->get_totals();
|
||||
|
||||
/** @var string|null $promo_code Le code promo appliqué au Panier s'il existe. */
|
||||
$promo_code = collect(WC()->cart->get_applied_coupons())->first();
|
||||
|
||||
/** @var array<string,int> */
|
||||
$cart_totals = WC()->cart->get_totals();
|
||||
/** Le sous-total de la Commande dans le Panier. */
|
||||
$cart_subtotal = Cart::parse_cart_value($cart_totals['subtotal'] ?? 0);
|
||||
|
||||
/** @var string $cart_subtotal_with_discount Le total du montant de la Réduction appliquée au Panier. */
|
||||
$cart_subtotal_with_discount = $cart_totals['discount_total']
|
||||
|> (static fn(int $number) => Number::format($number, maxPrecision: 2))
|
||||
|> (static fn(false|string $number) => is_bool($number) ? '0' : $number);
|
||||
/** @var float $cart_total Le total de la Commande dans le Panier. */
|
||||
$cart_total = $cart_totals['total']
|
||||
|> (static fn(int $number) => Number::format($number, maxPrecision: 2))
|
||||
|> (static fn(false|string $number) => is_bool($number) ? '0' : $number)
|
||||
|> (static fn(string $number) => (float) $number);
|
||||
/** @var string $shipping_subtotal Le sous-total de la livraison. */
|
||||
$shipping_subtotal = $cart_totals['shipping_total']
|
||||
|> (static fn(int $number) => Number::format($number, precision: 0))
|
||||
|> (static fn(false|string $number) => is_bool($number) ? '0' : $number);
|
||||
/** Le total du montant de la Réduction appliquée au Panier. */
|
||||
$cart_subtotal_with_discount = Cart::parse_cart_value($cart_totals['discount_total'] ?? 0);
|
||||
|
||||
/** Le total de la Commande dans le Panier. */
|
||||
$cart_total = Cart::parse_cart_value($cart_totals['total'] ?? 0);
|
||||
|
||||
/** Le sous-total de la livraison. */
|
||||
$shipping_subtotal = Cart::parse_cart_value($cart_totals['shipping_total'] ?? 0);
|
||||
|
||||
// TODO: Nettoyer ça.
|
||||
foreach (WC()->cart->get_cart() as $cle_panier => $article_panier) {
|
||||
$cart[$cle_panier] = [
|
||||
'attributs' => $article_panier['data']?->get_type() === 'variation'
|
||||
|
|
@ -140,12 +60,12 @@ foreach (WC()->cart->get_cart() as $cle_panier => $article_panier) {
|
|||
'id_variation' => $article_panier['variation_id'],
|
||||
'image' => pipe($article_panier['data']?->get_image_id(), static fn($id): string => genere_balise_img_multiformats(
|
||||
id: (string) $id,
|
||||
lazy: true
|
||||
lazy: true,
|
||||
)),
|
||||
'prix' => $article_panier['data']?->get_price(),
|
||||
'quantite' => $article_panier['quantity'],
|
||||
'url' => $article_panier['data']?->get_permalink(),
|
||||
'titre' => $article_panier['data']?->get_title()
|
||||
'titre' => $article_panier['data']?->get_title(),
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -154,49 +74,51 @@ $email = WC()->customer->get_billing_email();
|
|||
$adresse_livraison = WC()->customer->get_shipping();
|
||||
$adresse_facturation = WC()->customer->get_billing();
|
||||
$adresse_renseignee = $adresse_livraison['city'] !== '';
|
||||
$allowed_countries = collect(WC()->countries->get_countries())->only($allowed_countries)->toArray();
|
||||
// TODO: Déplacer ça dans une fonction statique de Cart.
|
||||
$allowed_countries = collect(WC()->countries->get_countries())->only(Cart::get_allowed_countries())->toArray();
|
||||
// TODO: Nettoyer ça.
|
||||
$methodes_livraison = collect(WC()->session->get('shipping_for_package_0')['rates'])
|
||||
->values()
|
||||
->map(static fn(WC_Shipping_Rate $methode): array => [
|
||||
'id' => $methode->get_method_id(),
|
||||
'prix' => Number::format((int) $methode->get_cost(), maxPrecision: 2),
|
||||
'prix' => Number::format((int) $methode->get_cost(), precision: 2),
|
||||
'selectionnee' => collect(WC()->session->get('chosen_shipping_methods'))->first() === $methode->get_id(),
|
||||
'titre' => $methode->get_label()
|
||||
'titre' => $methode->get_label(),
|
||||
]);
|
||||
|
||||
$contexte['email'] = $email;
|
||||
$contexte['adresse_livraison'] = $adresse_livraison;
|
||||
$contexte['adresse_facturation'] = $adresse_facturation;
|
||||
$contexte['adresse_renseignee'] = $adresse_renseignee;
|
||||
$contexte['sous_total_panier'] = $cart_subtotal;
|
||||
$contexte['code_promo'] = $promo_code;
|
||||
$contexte['sous_total_reduction'] = $cart_subtotal_with_discount;
|
||||
$contexte['total_panier'] = $cart_total;
|
||||
$contexte['produits_panier'] = $cart;
|
||||
$contexte['pays_livraison'] = $allowed_countries;
|
||||
$contexte['sous_total_livraison'] = $shipping_subtotal;
|
||||
$contexte['methodes_livraison'] = $methodes_livraison;
|
||||
$context['email'] = $email;
|
||||
$context['adresse_livraison'] = $adresse_livraison;
|
||||
$context['adresse_facturation'] = $adresse_facturation;
|
||||
$context['adresse_renseignee'] = $adresse_renseignee;
|
||||
$context['sous_total_panier'] = $cart_subtotal;
|
||||
$context['code_promo'] = $promo_code;
|
||||
$context['sous_total_reduction'] = $cart_subtotal_with_discount;
|
||||
$context['total_panier'] = $cart_total;
|
||||
$context['produits_panier'] = $cart;
|
||||
$context['pays_livraison'] = $allowed_countries;
|
||||
$context['sous_total_livraison'] = $shipping_subtotal;
|
||||
$context['methodes_livraison'] = $methodes_livraison;
|
||||
|
||||
/**
|
||||
* Charge les scripts et styles de la page.
|
||||
*
|
||||
* @throws Exception une exception est levée s'il est impossible d'obtenir la date de modification du fichier à charger
|
||||
*/
|
||||
function load_resources(): void {
|
||||
function load_page_resources(): void {
|
||||
Resource::enqueue_style_file(
|
||||
handle: 'haiku-atelier-2024-styles-page-panier',
|
||||
path: '/assets/css/pages/page-panier.css'
|
||||
path: '/assets/css/pages/page-panier.css',
|
||||
);
|
||||
Resource::enqueue_script_module_file(
|
||||
id: 'haiku-atelier-2024-scripts-page-panier',
|
||||
path: '/assets/js/scripts-page-panier.js'
|
||||
path: '/assets/js/scripts-page-panier.js',
|
||||
);
|
||||
}
|
||||
|
||||
add_action('wp_enqueue_scripts', load_resources(...));
|
||||
add_action('wp_enqueue_scripts', load_page_resources(...));
|
||||
|
||||
// Rendu
|
||||
Timber::render(
|
||||
filenames: $modeles,
|
||||
data: $contexte
|
||||
filenames: $templates,
|
||||
data: $context,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,17 +1,23 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Route pour la préparation du paiement via Stripe (« Checkout »).
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace HaikuAtelier;
|
||||
|
||||
use Roots\WPConfig\Config;
|
||||
use Stripe\BillingPortal\Session;
|
||||
use Stripe\Checkout\Session;
|
||||
use Stripe\Coupon;
|
||||
use Stripe\Product;
|
||||
use Stripe\Stripe;
|
||||
use Symfony\Component\Uid\Uuid;
|
||||
use WC_Cart;
|
||||
use WC_Coupon;
|
||||
use WC_Order;
|
||||
use WC_Session_Handler;
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
|
|
@ -40,7 +46,7 @@ $session_wc = WC()->session;
|
|||
$urls = [
|
||||
'accueil' => get_page_link(get_page_by_path('home')),
|
||||
'succes_commande' => get_page_link(get_page_by_path('successful-order')),
|
||||
'echec_commande' => get_page_link(get_page_by_path('failed-order'))
|
||||
'echec_commande' => get_page_link(get_page_by_path('failed-order')),
|
||||
];
|
||||
|
||||
// Redirige à la page d'accueil si le Panier est vide
|
||||
|
|
@ -86,7 +92,7 @@ $articles = collect($panier->get_cart())
|
|||
. ' ('
|
||||
. explode(': ', (string) $article_panier['data']?->get_attribute_summary())[1]
|
||||
. ')',
|
||||
false => $article_panier['data']?->get_title()
|
||||
false => $article_panier['data']?->get_title(),
|
||||
};
|
||||
|
||||
return [
|
||||
|
|
@ -94,11 +100,11 @@ $articles = collect($panier->get_cart())
|
|||
'currency' => 'EUR',
|
||||
'product_data' => [
|
||||
'name' => $titre_produit,
|
||||
'images' => [wp_get_attachment_image_url($article_panier['data']?->get_image_id())]
|
||||
'images' => [wp_get_attachment_image_url($article_panier['data']?->get_image_id())],
|
||||
],
|
||||
'unit_amount' => $article_panier['data']?->get_price() * 100
|
||||
'unit_amount' => $article_panier['data']?->get_price() * 100,
|
||||
],
|
||||
'quantity' => $article_panier['quantity']
|
||||
'quantity' => $article_panier['quantity'],
|
||||
];
|
||||
})
|
||||
->values()
|
||||
|
|
@ -126,7 +132,7 @@ $coupons_wc = collect(WC()->cart->get_coupons())
|
|||
'duration' => get_discount_duration($coupon),
|
||||
'fixed_cart' === $coupon->get_discount_type() ? 'amount_off' : 'percent_off' => get_discount_amount($coupon),
|
||||
'id' => $coupon->get_code(),
|
||||
'name' => $coupon->get_code()
|
||||
'name' => $coupon->get_code(),
|
||||
])
|
||||
->each(static function (array $item) use ($coupons_stripe): void {
|
||||
// Si le code promo n'existe pas, le créer
|
||||
|
|
@ -140,7 +146,7 @@ $reductions_stripe = $coupons_wc
|
|||
->toArray();
|
||||
|
||||
/** @var Session $session_checkout_stripe */
|
||||
$session_checkout_stripe = \Stripe\Checkout\Session::create([
|
||||
$session_checkout_stripe = Session::create([
|
||||
'cancel_url' => $urls['echec_commande'],
|
||||
'customer_email' => $email_client,
|
||||
'discounts' => $reductions_stripe,
|
||||
|
|
@ -152,8 +158,8 @@ $session_checkout_stripe = \Stripe\Checkout\Session::create([
|
|||
'display_name' => $methode_livraison['nom'],
|
||||
'fixed_amount' => ['amount' => $methode_livraison['cout'], 'currency' => 'EUR'],
|
||||
'tax_behavior' => 'inclusive',
|
||||
'type' => 'fixed_amount'
|
||||
]]]
|
||||
'type' => 'fixed_amount',
|
||||
]]],
|
||||
], ['idempotency_key' => Uuid::v4()]);
|
||||
// echo json_encode($session_checkout_stripe);
|
||||
header('HTTP/1.1 303 See Other');
|
||||
|
|
|
|||
|
|
@ -3,30 +3,36 @@
|
|||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Modèle de la Page Contact.
|
||||
* Modèle de la Page « Contact ».
|
||||
*/
|
||||
|
||||
namespace HaikuAtelier;
|
||||
|
||||
use Exception;
|
||||
use HaikuAtelier\WP\Resource;
|
||||
use Timber\Timber;
|
||||
|
||||
// Contexte et modèles
|
||||
$contexte = Timber::context();
|
||||
$modeles = ['contact.twig'];
|
||||
use function add_action;
|
||||
|
||||
// Charge les scripts et styles de la page
|
||||
function charge_scripts_styles_page_contact(): void {
|
||||
wp_enqueue_style(
|
||||
$context = Timber::context();
|
||||
$templates = ['contact.twig'];
|
||||
|
||||
/**
|
||||
* Charge les scripts et styles de la page.
|
||||
*
|
||||
* @throws Exception une exception est levée s'il est impossible d'obtenir la date de modification du fichier à charger
|
||||
*/
|
||||
function load_page_resources(): void {
|
||||
Resource::enqueue_style_file(
|
||||
handle: 'haiku-atelier-2024-styles-page-contact',
|
||||
src: get_template_directory_uri() . '/assets/css/pages/page-modele-simple.css',
|
||||
deps: [],
|
||||
ver: filemtime(get_template_directory() . '/assets/css/pages/page-modele-simple.css'),
|
||||
media: 'all'
|
||||
path: '/assets/css/pages/page-contact.css',
|
||||
);
|
||||
}
|
||||
|
||||
add_action('wp_enqueue_scripts', 'charge_scripts_styles_page_contact');
|
||||
add_action('wp_enqueue_scripts', load_page_resources(...));
|
||||
|
||||
// Rendu
|
||||
Timber::render(
|
||||
filenames: $modeles,
|
||||
data: $contexte
|
||||
filenames: $templates,
|
||||
data: $context,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,32 +1,38 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Route pour la préparation du paiement via Stripe (« Checkout »).
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Modèle de la Page affichée à l'utilisateur lors de l'échec d'un paiement « Failed Order ».
|
||||
*/
|
||||
|
||||
namespace HaikuAtelier;
|
||||
|
||||
use Exception;
|
||||
use HaikuAtelier\WP\Resource;
|
||||
use Timber\Timber;
|
||||
|
||||
// Contexte et modèles
|
||||
$contexte = Timber::context();
|
||||
$modeles = ['echec-commande.twig'];
|
||||
use function add_action;
|
||||
|
||||
// Charge les scripts et styles de la page
|
||||
function charge_scripts_styles_page_echec_commande(): void {
|
||||
wp_enqueue_style(
|
||||
handle: 'haiku-atelier-2024-styles-page-a-propos',
|
||||
src: get_template_directory_uri() . '/assets/css/pages/page-modele-simple.css',
|
||||
deps: [],
|
||||
ver: filemtime(get_template_directory() . '/assets/css/pages/page-modele-simple.css'),
|
||||
media: 'all'
|
||||
$context = Timber::context();
|
||||
$templates = ['echec-commande.twig'];
|
||||
|
||||
/**
|
||||
* Charge les scripts et styles de la page.
|
||||
*
|
||||
* @throws Exception une exception est levée s'il est impossible d'obtenir la date de modification du fichier à charger
|
||||
*/
|
||||
function load_page_resources(): void {
|
||||
Resource::enqueue_style_file(
|
||||
handle: 'haiku-atelier-2024-styles-page-modele-simple',
|
||||
path: '/assets/css/pages/page-modele-simple.css',
|
||||
);
|
||||
}
|
||||
|
||||
add_action('wp_enqueue_scripts', 'charge_scripts_styles_page_echec_commande');
|
||||
add_action('wp_enqueue_scripts', load_page_resources(...));
|
||||
|
||||
// Rendu
|
||||
Timber::render(
|
||||
filenames: $modeles,
|
||||
data: $contexte
|
||||
filenames: $templates,
|
||||
data: $context,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,15 +1,20 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Route pour la préparation du paiement via Stripe (« Checkout »).
|
||||
* Modèle de la Page affichée à l'utilisateur lors du succès d'un paiement « Succesful Order ».
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace HaikuAtelier;
|
||||
|
||||
use Roots\WPConfig\Config;
|
||||
use Stripe\Checkout\Session;
|
||||
use Stripe\StripeClient;
|
||||
use Timber\Timber;
|
||||
use WC_Cart;
|
||||
use WC_Order;
|
||||
use WC_Order_Refund;
|
||||
|
||||
use function Crell\fp\pipe;
|
||||
|
||||
|
|
@ -57,9 +62,8 @@ try {
|
|||
$panier->empty_cart();
|
||||
}
|
||||
|
||||
// Contexte et modèles
|
||||
$contexte = Timber::context();
|
||||
$modeles = ['succes-commande.twig'];
|
||||
$context = Timber::context();
|
||||
$templates = ['succes-commande.twig'];
|
||||
|
||||
// Récupère les données des Produits
|
||||
/** @var mixed $produits Les Produits de la Commande sous forme de tableau contenant uniquement les données affichées nécessaires pour le Page. */
|
||||
|
|
@ -85,16 +89,16 @@ try {
|
|||
'id_produit' => $id_produit,
|
||||
'image' => pipe($produit->get_image_id(), static fn($id): string => genere_balise_img_multiformats(
|
||||
id: $id,
|
||||
lazy: true
|
||||
lazy: true,
|
||||
)),
|
||||
'permalien' => $produit->get_permalink(),
|
||||
'prix' => $produit_commande->get_data()['total'],
|
||||
'quantite' => $produit_commande->get_quantity(),
|
||||
'titre' => $produit->get_title()
|
||||
'titre' => $produit->get_title(),
|
||||
];
|
||||
});
|
||||
|
||||
$contexte['produits'] = $produits;
|
||||
$context['produits'] = $produits;
|
||||
|
||||
// Charge les scripts et styles de la page
|
||||
function charge_scripts_styles_page_succes_commande(): void {
|
||||
|
|
@ -103,7 +107,7 @@ try {
|
|||
src: get_template_directory_uri() . '/assets/css/pages/page-succes-commande.css',
|
||||
deps: [],
|
||||
ver: filemtime(get_template_directory() . '/assets/css/pages/page-succes-commande.css'),
|
||||
media: 'all'
|
||||
media: 'all',
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -111,8 +115,8 @@ try {
|
|||
|
||||
// Rendu
|
||||
Timber::render(
|
||||
filenames: $modeles,
|
||||
data: $contexte
|
||||
filenames: $templates,
|
||||
data: $context,
|
||||
);
|
||||
} catch (Error $error) {
|
||||
http_response_code(500);
|
||||
|
|
|
|||
|
|
@ -6,27 +6,31 @@ declare(strict_types=1);
|
|||
* Le modèle de la Page « Terms & Conditions ».
|
||||
*/
|
||||
|
||||
namespace HaikuAtelier;
|
||||
|
||||
use Exception;
|
||||
use HaikuAtelier\WP\Resource;
|
||||
use Timber\Timber;
|
||||
|
||||
// Contexte et modèles
|
||||
$contexte = Timber::context();
|
||||
$modeles = ['cgv.twig'];
|
||||
$context = Timber::context();
|
||||
$templates = ['cgv.twig'];
|
||||
|
||||
// Charge les scripts et styles de la page
|
||||
function charge_scripts_styles_page_cgv(): void {
|
||||
wp_enqueue_style(
|
||||
handle: 'haiku-atelier-2024-styles-page-cgv',
|
||||
src: get_template_directory_uri() . '/assets/css/pages/page-modele-simple.css',
|
||||
deps: [],
|
||||
ver: filemtime(get_template_directory() . '/assets/css/pages/page-modele-simple.css'),
|
||||
media: 'all'
|
||||
/**
|
||||
* Charge les scripts et styles de la page.
|
||||
*
|
||||
* @throws Exception une exception est levée s'il est impossible d'obtenir la date de modification du fichier à charger
|
||||
*/
|
||||
function load_page_resources(): void {
|
||||
Resource::enqueue_style_file(
|
||||
handle: '/assets/css/pages/page-modele-simple.css',
|
||||
path: '/assets/css/pages/page-modele-simple.css',
|
||||
);
|
||||
}
|
||||
|
||||
add_action('wp_enqueue_scripts', 'charge_scripts_styles_page_cgv');
|
||||
add_action('wp_enqueue_scripts', load_page_resources(...));
|
||||
|
||||
// Rendu
|
||||
Timber::render(
|
||||
filenames: $modeles,
|
||||
data: $contexte
|
||||
filenames: $templates,
|
||||
data: $context,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -6,33 +6,50 @@ declare(strict_types=1);
|
|||
* Le modèle de la Page d'un Produit.
|
||||
*/
|
||||
|
||||
use HaikuAtelier\Data\Product;
|
||||
use Timber\Timber;
|
||||
namespace HaikuAtelier;
|
||||
|
||||
use Exception;
|
||||
use HaikuAtelier\Data\Product;
|
||||
use HaikuAtelier\WP\Resource;
|
||||
use Illuminate\Support\Arr;
|
||||
use stdClass;
|
||||
use Timber\Timber;
|
||||
use WC_Product;
|
||||
|
||||
use function add_action;
|
||||
use function assert;
|
||||
use function collect;
|
||||
use function is_array;
|
||||
use function is_bool;
|
||||
use function recupere_produits_meme_collection;
|
||||
use function wc_get_product;
|
||||
use function wp_json_encode;
|
||||
|
||||
require_once __DIR__ . '/src/inc/HTML.php';
|
||||
require_once __DIR__ . '/src/inc/TraitementInformations.php';
|
||||
|
||||
// Contexte et modèles
|
||||
$context = Timber::context();
|
||||
$templates = ['produit.twig'];
|
||||
|
||||
$raw_product = wc_get_product();
|
||||
|
||||
// Le Produit DOIT exister.
|
||||
if ($raw_product === null || is_bool($raw_product)) {
|
||||
if ($raw_product === null || $raw_product === false) {
|
||||
throw new Exception("Le Produit n'existe pas.");
|
||||
}
|
||||
|
||||
// Assemble les données d'intérêt pour la page au sein d'une Classe.
|
||||
$product = Product::new($raw_product);
|
||||
|
||||
/** @var int $prix_maximal Le prix de la Variation la plus chère */
|
||||
/** @var int $maximum_price Le prix de la Variation la plus chère */
|
||||
$maximum_price = collect($product->variations)->max('price');
|
||||
|
||||
$same_collection_products = array_map(
|
||||
array: recupere_produits_meme_collection($product->collection)($product->id),
|
||||
callback: Product::new(...)
|
||||
);
|
||||
/** @var list<Product> Les Produits de la même collection que celui affiché dans la Page. */
|
||||
$same_collection_products = recupere_produits_meme_collection($product->collection)($product->id)
|
||||
|> function (/** @var list<WC_Product>|stdClass */ mixed $products): array {
|
||||
assert(is_array($products), 'Les Produits de la même collection doivent être un tableau.');
|
||||
return $products;
|
||||
}
|
||||
|> (static fn(/** @var list<WC_Product> */ array $products): array => Arr::map($products, Product::new(...)));
|
||||
|
||||
$context['product'] = $product;
|
||||
$context['product_json'] = wp_json_encode($product);
|
||||
|
|
@ -40,27 +57,25 @@ $context['maximum_price'] = $maximum_price;
|
|||
$context['same_collection_products'] = $same_collection_products;
|
||||
|
||||
/**
|
||||
* Charge les Scripts nécessaires pour la page Produit.
|
||||
* Charge les scripts et styles de la page.
|
||||
*
|
||||
* @throws Exception une exception est levée s'il est impossible d'obtenir la date de modification du fichier à charger
|
||||
*/
|
||||
function charge_scripts_page_produit(): void {
|
||||
wp_enqueue_script_module(
|
||||
function load_page_resources(): void {
|
||||
Resource::enqueue_script_module_file(
|
||||
id: 'haiku-atelier-2024-scripts-page-produit',
|
||||
src: get_template_directory_uri() . '/assets/js/scripts-page-produit.js',
|
||||
deps: [],
|
||||
version: filemtime(get_template_directory() . '/assets/js/scripts-page-produit.js')
|
||||
path: '/assets/js/scripts-page-produit.js',
|
||||
);
|
||||
wp_enqueue_script_module(
|
||||
Resource::enqueue_script_module_file(
|
||||
id: 'haiku-atelier-2024-scripts-menu-categories',
|
||||
src: get_template_directory_uri() . '/assets/js/scripts-menu-categories.js',
|
||||
deps: [],
|
||||
version: filemtime(get_template_directory() . '/assets/js/scripts-menu-categories.js')
|
||||
path: '/assets/js/scripts-menu-categories.js',
|
||||
);
|
||||
}
|
||||
|
||||
add_action('wp_enqueue_scripts', 'charge_scripts_page_produit');
|
||||
add_action('wp_enqueue_scripts', load_page_resources(...));
|
||||
|
||||
// Rendu
|
||||
Timber::render(
|
||||
filenames: $templates,
|
||||
data: $context
|
||||
data: $context,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -54,21 +54,21 @@ final class StarterSite extends Site {
|
|||
$liens_reseaux_sociaux = [
|
||||
'facebook' => ['nom' => 'Facebook', 'url' => $personnalisations_theme['lien_facebook'] ?? ''],
|
||||
'instagram' => ['nom' => 'Instagram', 'url' => $personnalisations_theme['lien_instagram'] ?? ''],
|
||||
'pinterest' => ['nom' => 'Pinterest', 'url' => $personnalisations_theme['lien_pinterest'] ?? '']
|
||||
'pinterest' => ['nom' => 'Pinterest', 'url' => $personnalisations_theme['lien_pinterest'] ?? ''],
|
||||
];
|
||||
$context['liens_reseaux_sociaux'] = $liens_reseaux_sociaux;
|
||||
|
||||
// Récupère les textes apparaissant sur les pages Produits
|
||||
$descriptions_produits = [
|
||||
'texte_conditions_livraison' => wpautop($personnalisations_theme['texte_conditions_livraison']) ?? '',
|
||||
'texte_entretien_produit' => wpautop($personnalisations_theme['texte_entretien_produit']) ?? ''
|
||||
'texte_entretien_produit' => wpautop($personnalisations_theme['texte_entretien_produit']) ?? '',
|
||||
];
|
||||
$context['descriptions_produits'] = $descriptions_produits;
|
||||
|
||||
// Logo personnalisée
|
||||
$context['logo'] = pipe(get_theme_mod('custom_logo'), static fn($id) => wp_get_attachment_image_src(
|
||||
attachment_id: $id,
|
||||
size: 'full'
|
||||
size: 'full',
|
||||
));
|
||||
|
||||
// Informations des Pages
|
||||
|
|
@ -88,7 +88,7 @@ final class StarterSite extends Site {
|
|||
'failed_order' => $recupere_informations_page('failed_order'),
|
||||
'home' => $recupere_informations_page('home'),
|
||||
'shop' => $recupere_informations_page('shop'),
|
||||
'successful_order' => $recupere_informations_page('successful_order')
|
||||
'successful_order' => $recupere_informations_page('successful_order'),
|
||||
];
|
||||
|
||||
// Récupère la Page courante
|
||||
|
|
@ -96,19 +96,19 @@ final class StarterSite extends Site {
|
|||
$context['page_courante'] = $url_courante;
|
||||
$context['est_page_tous_produits'] = preg_match(
|
||||
pattern: '/(\bshop\b)/',
|
||||
subject: $url_courante
|
||||
subject: $url_courante,
|
||||
);
|
||||
$context['est_page_boutique'] = preg_match(
|
||||
pattern: '/(\bshop\b)/',
|
||||
subject: $url_courante
|
||||
subject: $url_courante,
|
||||
)
|
||||
|| preg_match(
|
||||
pattern: '/(\bproduct\b)/',
|
||||
subject: $url_courante
|
||||
subject: $url_courante,
|
||||
)
|
||||
|| preg_match(
|
||||
pattern: '/(\bproduct-category\b)/',
|
||||
subject: $url_courante
|
||||
subject: $url_courante,
|
||||
);
|
||||
|
||||
// Politique de confidentialité
|
||||
|
|
@ -125,15 +125,15 @@ final class StarterSite extends Site {
|
|||
// Détermine si l'URL courante est celle de la Page d'Archive d'une Catégorie de Produits
|
||||
'courante' => preg_match(
|
||||
pattern: "/(\\b{$categorie->slug}\\b)/",
|
||||
subject: (string) pipe(URLHelper::get_current_url(), URLHelper::get_rel_url(...))
|
||||
)
|
||||
subject: (string) pipe(URLHelper::get_current_url(), URLHelper::get_rel_url(...)),
|
||||
),
|
||||
];
|
||||
$entrees_menu_categories = pipe(
|
||||
get_categories(['hide_empty' => false, 'orderby' => 'menu_order', 'taxonomy' => 'product_cat']),
|
||||
static fn($categories): array => array_map(
|
||||
callback: $cree_entree_menu,
|
||||
array: $categories
|
||||
)
|
||||
array: $categories,
|
||||
),
|
||||
);
|
||||
|
||||
$context['categories_produits'] = $entrees_menu_categories;
|
||||
|
|
@ -152,7 +152,7 @@ final class StarterSite extends Site {
|
|||
$context['nonce_wc'] = $nonce_wc;
|
||||
// TODO: Utiliser des variables d'environnement
|
||||
$auth_string = base64_encode(
|
||||
Config::get('WOOCOMMERCE_API_CONSUMER_KEY') . ':' . Config::get('WOOCOMMERCE_API_CONSUMER_SECRET')
|
||||
Config::get('WOOCOMMERCE_API_CONSUMER_KEY') . ':' . Config::get('WOOCOMMERCE_API_CONSUMER_SECRET'),
|
||||
);
|
||||
$context['auth_string'] = $auth_string;
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ function cree_champs_personnalises_produit(): void {
|
|||
->set_type(['image'])
|
||||
->set_duplicates_allowed(false),
|
||||
// Texte des détails du Produit
|
||||
Field::make('rich_text', 'haiku_details_produit', __("Product's Details"))
|
||||
Field::make('rich_text', 'haiku_details_produit', __("Product's Details")),
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -31,7 +31,7 @@ function cree_champ_personnalise_commande($order): void {
|
|||
'id' => 'tracking_number',
|
||||
'label' => 'Tracking Number:',
|
||||
'value' => $order->get_meta('tracking_number'),
|
||||
'wrapper_class' => 'form-field-wide'
|
||||
'wrapper_class' => 'form-field-wide',
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ function enregistre_controle_personnalise_tinymce(): void {
|
|||
src: get_template_directory_uri() . '/assets/vendor/controle-personnalise-tinymce.js',
|
||||
deps: ['jquery'],
|
||||
ver: '1.3',
|
||||
args: true
|
||||
args: true,
|
||||
);
|
||||
wp_enqueue_editor();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ final readonly class Attribute {
|
|||
public function __construct(
|
||||
public string $name,
|
||||
public string $slug,
|
||||
public array $options
|
||||
public array $options,
|
||||
) {}
|
||||
|
||||
public static function new(WC_Product_Attribute $attribute): self {
|
||||
|
|
@ -29,7 +29,7 @@ final readonly class Attribute {
|
|||
return new self(
|
||||
name: $name,
|
||||
slug: $slug,
|
||||
options: $options
|
||||
options: $options,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ final readonly class AttributeOption {
|
|||
public function __construct(
|
||||
public int $id,
|
||||
public string $name,
|
||||
public string $slug
|
||||
public string $slug,
|
||||
) {}
|
||||
|
||||
public static function new(WP_Term $term): self {
|
||||
|
|
@ -21,7 +21,7 @@ final readonly class AttributeOption {
|
|||
return new self(
|
||||
id: $id,
|
||||
name: $name,
|
||||
slug: $slug
|
||||
slug: $slug,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
122
web/app/themes/haiku-atelier-2024/src/inc/Data/Cart.php
Normal file
122
web/app/themes/haiku-atelier-2024/src/inc/Data/Cart.php
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace HaikuAtelier\Data;
|
||||
|
||||
use Illuminate\Support\Number;
|
||||
|
||||
use function is_bool;
|
||||
use function is_float;
|
||||
use function is_int;
|
||||
use function is_string;
|
||||
|
||||
final readonly class Cart {
|
||||
public function __construct() {}
|
||||
|
||||
/** La valeur par défaut d'une donnée invalide du Panier. */
|
||||
private const string DEFAULT_VALUE = '0.00';
|
||||
|
||||
/**
|
||||
* Retourne la liste des pays acceptés pour la livraison.
|
||||
*
|
||||
* @return array<int,string>
|
||||
*/
|
||||
public static function get_allowed_countries(): array {
|
||||
return [
|
||||
'AD',
|
||||
'AL',
|
||||
'AM',
|
||||
'AR',
|
||||
'AT',
|
||||
'AU',
|
||||
'BA',
|
||||
'BE',
|
||||
'BG',
|
||||
'BR',
|
||||
'CA',
|
||||
'CH',
|
||||
'CL',
|
||||
'CR',
|
||||
'CU',
|
||||
'CY',
|
||||
'CZ',
|
||||
'DE',
|
||||
'DK',
|
||||
'DZ',
|
||||
'EE',
|
||||
'EG',
|
||||
'ES',
|
||||
'FI',
|
||||
'FR',
|
||||
'GF',
|
||||
'GP',
|
||||
'GR',
|
||||
'HR',
|
||||
'HU',
|
||||
'IE',
|
||||
'IS',
|
||||
'IT',
|
||||
'JP',
|
||||
'KR',
|
||||
'LB',
|
||||
'LI',
|
||||
'LT',
|
||||
'LU',
|
||||
'LV',
|
||||
'MA',
|
||||
'MD',
|
||||
'ME',
|
||||
'MF',
|
||||
'MQ',
|
||||
'MT',
|
||||
'MX',
|
||||
'NC',
|
||||
'NL',
|
||||
'NO',
|
||||
'NZ',
|
||||
'PF',
|
||||
'PL',
|
||||
'PM',
|
||||
'PS',
|
||||
'PT',
|
||||
'RE',
|
||||
'RO',
|
||||
'SE',
|
||||
'SI',
|
||||
'SK',
|
||||
'SM',
|
||||
'TN',
|
||||
'TR',
|
||||
'TW',
|
||||
'US',
|
||||
'YT',
|
||||
'ZA',
|
||||
];
|
||||
}
|
||||
|
||||
public static function parse_cart_value(int|float|string|bool $cart_value): string {
|
||||
if (is_int($cart_value) || is_float($cart_value)) {
|
||||
return self::format_number($cart_value);
|
||||
}
|
||||
|
||||
if (is_string($cart_value)) {
|
||||
$number = Number::parseInt($cart_value);
|
||||
$number = is_bool($number) ? 0 : $number;
|
||||
|
||||
return self::format_number($number);
|
||||
}
|
||||
|
||||
return '0.00';
|
||||
}
|
||||
|
||||
private static function format_number(int|float $number): string {
|
||||
$formatted_number = Number::format(
|
||||
number: $number,
|
||||
// precision et max_precision sont mutuellement exclusifs.
|
||||
precision: 2,
|
||||
locale: 'fr',
|
||||
);
|
||||
return is_bool($formatted_number) ? self::DEFAULT_VALUE : $formatted_number;
|
||||
}
|
||||
}
|
||||
|
|
@ -35,7 +35,7 @@ final readonly class Product {
|
|||
public string $slug,
|
||||
public int $stock,
|
||||
public array $variations,
|
||||
public string $url
|
||||
public string $url,
|
||||
) {}
|
||||
|
||||
/**
|
||||
|
|
@ -94,7 +94,7 @@ final readonly class Product {
|
|||
slug: $slug,
|
||||
stock: $stock,
|
||||
variations: $variations,
|
||||
url: $url
|
||||
url: $url,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ final readonly class ProductVariation {
|
|||
private function __construct(
|
||||
public int $id,
|
||||
public string $price,
|
||||
public array $attributes
|
||||
public array $attributes,
|
||||
) {}
|
||||
|
||||
/**
|
||||
|
|
@ -29,7 +29,7 @@ final readonly class ProductVariation {
|
|||
/** @phpstan-ignore argument.type (Impossible à satisfaire) */
|
||||
static fn(string $key, string $value) => new ProductVariationAttribute($key, $value),
|
||||
array_keys($product->get_attributes()),
|
||||
array_values($product->get_attributes())
|
||||
array_values($product->get_attributes()),
|
||||
);
|
||||
|
||||
return new self($id, $price, $attributes);
|
||||
|
|
|
|||
|
|
@ -11,6 +11,6 @@ final readonly class ProductVariationAttribute {
|
|||
*/
|
||||
public function __construct(
|
||||
public string $attribute,
|
||||
public string $value
|
||||
public string $value,
|
||||
) {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ function retire_merdes_wc(): void {
|
|||
*/
|
||||
function genere_balises_img_dans_produit_dans_reponse_rest(
|
||||
WP_REST_Response $response,
|
||||
mixed $_product
|
||||
mixed $_product,
|
||||
): WP_REST_Response {
|
||||
// Vérifie que la Réponse a des données
|
||||
if (empty($response->data)) {
|
||||
|
|
@ -143,16 +143,16 @@ function genere_balises_img_dans_produit_dans_reponse_rest(
|
|||
$response->data['meta_data'],
|
||||
static fn($metadata): array => array_filter(
|
||||
array: $metadata,
|
||||
callback: static fn($entree): bool => '_photos_colonne_gauche|||0|value' === $entree->key
|
||||
callback: static fn($entree): bool => '_photos_colonne_gauche|||0|value' === $entree->key,
|
||||
),
|
||||
static fn($metadata): array => array_map(
|
||||
array: $metadata,
|
||||
callback: static fn($entree): string => genere_balise_img_multiformats(
|
||||
id: $entree?->value,
|
||||
lazy: true
|
||||
)
|
||||
lazy: true,
|
||||
),
|
||||
),
|
||||
static fn($image) => array_values(array: $image)[0]
|
||||
static fn($image) => array_values(array: $image)[0],
|
||||
);
|
||||
|
||||
// Génère la balise <img> pour l'image au survol
|
||||
|
|
@ -160,16 +160,16 @@ function genere_balises_img_dans_produit_dans_reponse_rest(
|
|||
$response->data['meta_data'],
|
||||
static fn($metadata): array => array_filter(
|
||||
array: $metadata,
|
||||
callback: static fn($entree): bool => '_photos_colonne_droite|||0|value' === $entree->key
|
||||
callback: static fn($entree): bool => '_photos_colonne_droite|||0|value' === $entree->key,
|
||||
),
|
||||
static fn($metadata): array => array_map(
|
||||
array: $metadata,
|
||||
callback: static fn($entree): string => genere_balise_img_multiformats(
|
||||
id: $entree?->value,
|
||||
lazy: true
|
||||
)
|
||||
lazy: true,
|
||||
),
|
||||
),
|
||||
static fn($image) => array_values(array: $image)[0]
|
||||
static fn($image) => array_values(array: $image)[0],
|
||||
);
|
||||
|
||||
return $response;
|
||||
|
|
@ -182,7 +182,7 @@ add_filter('woocommerce_rest_prepare_product_object', 'genere_balises_img_dans_p
|
|||
*/
|
||||
function genere_prix_maximal_produit_variable_dans_reponse_rest(
|
||||
WP_REST_Response $reponse,
|
||||
WC_Data $_produit
|
||||
WC_Data $_produit,
|
||||
): WP_REST_Response {
|
||||
// Vérifie que la Réponse a des données
|
||||
if (empty($reponse->data)) {
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Fonctions pour la génération de HTML.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Génère la balise `<img>` d'un Média attaché à un Produit selon son ID.
|
||||
*/
|
||||
function genere_balise_img(int $id_image): string {
|
||||
return wp_get_attachment_image(
|
||||
attachment_id: $id_image,
|
||||
size: 'full'
|
||||
);
|
||||
}
|
||||
|
|
@ -19,7 +19,7 @@ function enregistre_taxonomie_collection(): void {
|
|||
'new_item_name' => __('New Collection Name'),
|
||||
'search_items' => __('Search Collections'),
|
||||
'singular_name' => __('Collection'),
|
||||
'update_item' => __('Update Collection')
|
||||
'update_item' => __('Update Collection'),
|
||||
];
|
||||
$args = [
|
||||
'description' => __('An ensemble of pieces thematically or chronologically grouped together.'),
|
||||
|
|
@ -31,7 +31,7 @@ function enregistre_taxonomie_collection(): void {
|
|||
'show_admin_column' => true,
|
||||
'show_in_menu' => true,
|
||||
'show_in_quick_edit' => true,
|
||||
'show_ui' => true
|
||||
'show_ui' => true,
|
||||
];
|
||||
|
||||
register_taxonomy('collection', ['product'], $args);
|
||||
|
|
|
|||
|
|
@ -35,14 +35,13 @@ function genere_balise_img_multiformats(string $id, bool $lazy = false): string
|
|||
|
||||
$avif = $chemin ? realpath(pathinfo($chemin)['dirname'] . '/' . pathinfo($chemin)['filename'] . '.avif') : false;
|
||||
$jxl = $chemin ? realpath(pathinfo($chemin)['dirname'] . '/' . pathinfo($chemin)['filename'] . '.jxl') : false;
|
||||
$webp = $chemin ? realpath(pathinfo($chemin)['dirname'] . '/' . pathinfo($chemin)['filename'] . '.webp') : false;
|
||||
|
||||
// Génère un tableau avec les différents formats valides
|
||||
$formats = pipe(
|
||||
[$avif, $jxl, $webp],
|
||||
[$avif, $jxl],
|
||||
static fn($tableau): array => array_filter(
|
||||
array: $tableau,
|
||||
callback: static fn($chemin_format): bool => false !== $chemin_format
|
||||
callback: static fn($chemin_format): bool => false !== $chemin_format,
|
||||
),
|
||||
static fn($tableau): array => array_map(
|
||||
array: $tableau,
|
||||
|
|
@ -54,13 +53,13 @@ function genere_balise_img_multiformats(string $id, bool $lazy = false): string
|
|||
. '/'
|
||||
. pathinfo($url)['filename']
|
||||
. '.'
|
||||
. pathinfo((string) $chemin_format)['extension']
|
||||
]
|
||||
)
|
||||
. pathinfo((string) $chemin_format)['extension'],
|
||||
],
|
||||
),
|
||||
);
|
||||
usort(
|
||||
array: $formats,
|
||||
callback: static fn($a, $b): int => $a['taille'] <=> $b['taille']
|
||||
callback: static fn($a, $b): int => $a['taille'] <=> $b['taille'],
|
||||
);
|
||||
|
||||
// Construis les balises <source> avec les formats valides
|
||||
|
|
@ -109,17 +108,17 @@ function recupere_informations_produit_shop(WC_Product $produit): mixed {
|
|||
// Récupère les informations de chaque Variation
|
||||
static fn($enfants): array => array_map(
|
||||
callback: wc_get_product(...),
|
||||
array: $enfants
|
||||
array: $enfants,
|
||||
),
|
||||
// Trie les Variations par prix descendant
|
||||
static fn($variations): array => array_map(
|
||||
callback: static fn($variation) => $variation->get_price(),
|
||||
array: $variations
|
||||
array: $variations,
|
||||
),
|
||||
// Récupère le Prix de la Variation la plus chère
|
||||
static fn($prix) => collect($prix)->max(),
|
||||
// Récupère le Prix pour la Variation la plus chère OU le prix du Produit simple
|
||||
static fn($prix_variation_maximale) => $prix_variation_maximale ?? $produit->get_price()
|
||||
static fn($prix_variation_maximale) => $prix_variation_maximale ?? $produit->get_price(),
|
||||
);
|
||||
|
||||
// TEMP: Cas de la Carte Cadeau où aucun prix ne doit être affiché. Idéalement utiliser un système d'étiquettes pour ces cas là.
|
||||
|
|
@ -137,15 +136,15 @@ function recupere_informations_produit_shop(WC_Product $produit): mixed {
|
|||
// Photo du Produit affichée par défaut
|
||||
'photo_repos' => genere_balise_img_multiformats(
|
||||
get_post_meta($post_id = $produit->get_id(), $key = '_photos_colonne_gauche|||0|value')[0] ?? -1,
|
||||
false
|
||||
false,
|
||||
),
|
||||
// Photo du Produit affichée au survol de l'image
|
||||
'photo_survol' => genere_balise_img_multiformats(
|
||||
get_post_meta($post_id = $produit->get_id(), $key = '_photos_colonne_droite|||0|value')[0] ?? -1,
|
||||
true
|
||||
true,
|
||||
),
|
||||
// URL du Produit pour les liens vers celui-ci
|
||||
'url' => $produit->get_permalink()
|
||||
'url' => $produit->get_permalink(),
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -175,19 +174,19 @@ function recupere_informations_produit_page_produit(WC_Product $product): mixed
|
|||
'prix' => $product->get_price(),
|
||||
'photos_colonne_gauche' => array_map(
|
||||
callback: genere_balise_img_multiformats(...),
|
||||
array: get_post_meta($post_id = $product->get_id(), $key = '_photos_colonne_gauche|||0|value')
|
||||
array: get_post_meta($post_id = $product->get_id(), $key = '_photos_colonne_gauche|||0|value'),
|
||||
),
|
||||
'photos_colonne_droite' => array_map(
|
||||
callback: genere_balise_img_multiformats(...),
|
||||
array: carbon_get_the_post_meta('photos_colonne_droite')
|
||||
array: carbon_get_the_post_meta('photos_colonne_droite'),
|
||||
),
|
||||
'photo_repos' => genere_balise_img_multiformats(
|
||||
get_post_meta($post_id = $product->get_id(), $key = '_photos_colonne_gauche|||0|value')[0] ?? -1,
|
||||
false
|
||||
false,
|
||||
),
|
||||
'photo_survol' => genere_balise_img_multiformats(
|
||||
get_post_meta($post_id = $product->get_id(), $key = '_photos_colonne_droite|||0|value')[0] ?? -1,
|
||||
true
|
||||
true,
|
||||
),
|
||||
// Slug du Produit
|
||||
'slug' => $product->get_slug(),
|
||||
|
|
@ -196,7 +195,7 @@ function recupere_informations_produit_page_produit(WC_Product $product): mixed
|
|||
// Variations du Produit
|
||||
'variations_ids' => $product->get_children(),
|
||||
// URL du Produit
|
||||
'url' => $product->get_permalink()
|
||||
'url' => $product->get_permalink(),
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -206,15 +205,14 @@ function recupere_informations_produit_page_produit(WC_Product $product): mixed
|
|||
*
|
||||
* Pour faciliter l'usage avec `array_map`, utilise une fonction avec curryfication.
|
||||
*/
|
||||
function recupere_produits_meme_collection(string $slug_collection): mixed {
|
||||
// @param int $id_produit
|
||||
return static fn($id_produit) => wc_get_products([
|
||||
function recupere_produits_meme_collection(string $slug_collection): callable {
|
||||
return static fn(int $id_produit): array|stdClass => wc_get_products([
|
||||
'exclude' => [$id_produit],
|
||||
'limit' => 4,
|
||||
'order' => 'DESC',
|
||||
'orderby' => 'date',
|
||||
'status' => 'publish',
|
||||
'tax_query' => [['taxonomy' => 'collection', 'field' => 'slug', 'terms' => $slug_collection]]
|
||||
'tax_query' => [['taxonomy' => 'collection', 'field' => 'slug', 'terms' => $slug_collection]],
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -224,6 +222,6 @@ function recupere_et_formate_attributs_produit(mixed $attributs_produit): mixed
|
|||
return [
|
||||
'taille' => ['nom' => 'Size', 'valeur' => $attributs_produit['pa_size'] ?? false],
|
||||
'pierre' => ['nom' => 'Stone', 'valeur' => $attributs_produit['pa_stone'] ?? false],
|
||||
'cote' => ['nom' => 'Side', 'valeur' => $attributs_produit['pa_side'] ?? false]
|
||||
'cote' => ['nom' => 'Side', 'valeur' => $attributs_produit['pa_side'] ?? false],
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ final readonly class Resource {
|
|||
id: $id,
|
||||
src: $file_uri,
|
||||
deps: [],
|
||||
version: $version
|
||||
version: $version,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ final readonly class Resource {
|
|||
src: $file_uri,
|
||||
deps: [],
|
||||
ver: $ver,
|
||||
media: 'all'
|
||||
media: 'all',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ export type ParentElement = Document | Element;
|
|||
export const getFirstSelectorFromParent =
|
||||
(parent: ParentElement) =>
|
||||
<E extends Element = Element>(selector: string): Option.Option<NonNullable<E>> =>
|
||||
Option.fromNullable(parent.querySelector<E>(selector));
|
||||
Option.fromNullishOr(parent.querySelector<E>(selector));
|
||||
|
||||
export const getFirstSelectorFromDocument = <E extends Element = Element>(
|
||||
selector: string,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ Description: Hé.
|
|||
Version: 1.0
|
||||
Requires at least: 5.0
|
||||
Tested up to: 5.4
|
||||
Requires PHP: 7.0
|
||||
Requires PHP: 8.5
|
||||
License: Tous droits réservés
|
||||
Text Domain: haiku-atelier-2024
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -6,19 +6,23 @@ declare(strict_types=1);
|
|||
* Le modèle de la Page d'Archive d'une Catégorie de Produits.
|
||||
*/
|
||||
|
||||
namespace HaikuAtelier;
|
||||
|
||||
use Exception;
|
||||
use HaikuAtelier\Data\Product;
|
||||
use HaikuAtelier\WP\Resource;
|
||||
use Illuminate\Support\Arr;
|
||||
use Timber\Timber;
|
||||
use WC_Product;
|
||||
use WP_Term;
|
||||
|
||||
require_once __DIR__ . '/src/inc/TraitementInformations.php';
|
||||
|
||||
// Contexte et modèles
|
||||
$context = Timber::context();
|
||||
$templates = ['boutique.twig'];
|
||||
|
||||
/** @var WP_Term */
|
||||
$current_term = get_queried_object();
|
||||
/** @var string */
|
||||
$category_slug = $current_term->slug;
|
||||
|
||||
/** @var list<WC_Product> $raw_products Les informations brutes des Produits. */
|
||||
|
|
@ -27,14 +31,11 @@ $raw_products = wc_get_products([
|
|||
'limit' => 12,
|
||||
'order' => 'DESC',
|
||||
'orderby' => 'date',
|
||||
'status' => 'publish'
|
||||
'status' => 'publish',
|
||||
]);
|
||||
|
||||
/** @var list<Product> */
|
||||
$products = array_map(
|
||||
callback: Product::new(...),
|
||||
array: $raw_products
|
||||
);
|
||||
$products = Arr::map($raw_products, Product::new(...));
|
||||
$context['products'] = $products;
|
||||
|
||||
/** @var string */
|
||||
|
|
@ -49,22 +50,22 @@ $context['products_category_id'] = $products_category_id;
|
|||
function load_page_resources(): void {
|
||||
Resource::enqueue_style_file(
|
||||
handle: 'haiku-atelier-2024-styles-page-boutique',
|
||||
path: '/assets/css/pages/page-boutique.css'
|
||||
path: '/assets/css/pages/page-boutique.css',
|
||||
);
|
||||
Resource::enqueue_script_module_file(
|
||||
id: 'haiku-atelier-2024-scripts-page-boutique',
|
||||
path: '/assets/js/scripts-page-boutique.js'
|
||||
path: '/assets/js/scripts-page-boutique.js',
|
||||
);
|
||||
Resource::enqueue_script_module_file(
|
||||
id: 'haiku-atelier-2024-scripts-menu-categories',
|
||||
path: '/assets/js/scripts-menu-categories.js'
|
||||
path: '/assets/js/scripts-menu-categories.js',
|
||||
);
|
||||
}
|
||||
|
||||
add_action('wp_enqueue_scripts', 'load_page_resources');
|
||||
add_action('wp_enqueue_scripts', load_page_resources(...));
|
||||
|
||||
// Rendu
|
||||
Timber::render(
|
||||
filenames: $templates,
|
||||
data: $context
|
||||
data: $context,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -8,10 +8,6 @@
|
|||
srcset="{{ rel_url }}.avif"
|
||||
type="image/avif"
|
||||
/>
|
||||
<source
|
||||
srcset="{{ rel_url }}.webp"
|
||||
type="image/webp"
|
||||
/>
|
||||
<source
|
||||
srcset="{{ rel_url }}.png"
|
||||
type="image/png"
|
||||
|
|
|
|||
|
|
@ -19,9 +19,9 @@ if (!defined('ABSPATH')) {
|
|||
Timber::init();
|
||||
// Sélectionne le répertoire contenant les modèles Twig
|
||||
Timber::$dirname = ['views'];
|
||||
// Contexte et modèles
|
||||
$contexte = Timber::context();
|
||||
$modeles = ['email-commande-envoyee.twig'];
|
||||
|
||||
$context = Timber::context();
|
||||
$templates = ['email-commande-envoyee.twig'];
|
||||
|
||||
/** @var Order $commande La Commande issue du contexte contenu dans la variable $order. */
|
||||
$commande = $order;
|
||||
|
|
@ -35,13 +35,13 @@ $email = [
|
|||
'transporteur' => Str::of($commande->get_shipping_method())->replace(' (Free)', ''),
|
||||
'numero_suivi' => blank($commande->get_meta('tracking_number'))
|
||||
? 'UNKNOWN_TRACKING_NUMBER'
|
||||
: $commande->get_meta('tracking_number')
|
||||
]
|
||||
: $commande->get_meta('tracking_number'),
|
||||
],
|
||||
];
|
||||
|
||||
$contexte['commande'] = $email;
|
||||
$context['commande'] = $email;
|
||||
// Rendu
|
||||
Timber::render(
|
||||
filenames: $modeles,
|
||||
data: $contexte
|
||||
filenames: $templates,
|
||||
data: $context,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -20,9 +20,9 @@ if (!defined('ABSPATH')) {
|
|||
Timber::init();
|
||||
// Sélectionne le répertoire contenant les modèles Twig
|
||||
Timber::$dirname = ['views'];
|
||||
// Contexte et modèles
|
||||
$contexte = Timber::context();
|
||||
$modeles = ['email-base.twig'];
|
||||
|
||||
$context = Timber::context();
|
||||
$templates = ['email-base.twig'];
|
||||
|
||||
/** @var Order $commande La Commande issue du contexte contenu dans la variable $order. */
|
||||
$commande = $order;
|
||||
|
|
@ -35,7 +35,7 @@ $email = [
|
|||
'commande' => ['date' => $date->toDateString(), 'id' => $commande->get_id()],
|
||||
'livraison' => [
|
||||
'methode' => $commande->get_shipping_method(),
|
||||
'numero_suivi' => $commande->get_meta('tracking_number')
|
||||
'numero_suivi' => $commande->get_meta('tracking_number'),
|
||||
],
|
||||
'paiement' => ['methode' => ''],
|
||||
'produits' => collect($commande->get_items())->map(static function (WC_Order_Item_Product $article) {
|
||||
|
|
@ -51,14 +51,14 @@ $email = [
|
|||
? collect($produit->get_attributes())
|
||||
->mapWithKeys(static fn($_atr, $cle): array => [
|
||||
'nom' => Str::lower(wc_attribute_label($cle, $produit)),
|
||||
'valeur' => $produit->get_attribute($cle)
|
||||
'valeur' => $produit->get_attribute($cle),
|
||||
])
|
||||
->toArray()
|
||||
: [],
|
||||
'lien' => $produit->get_permalink(),
|
||||
'nom' => $produit->get_title(),
|
||||
'prix_total' => $article->get_total(),
|
||||
'quantite' => $article->get_quantity()
|
||||
'quantite' => $article->get_quantity(),
|
||||
];
|
||||
}),
|
||||
'totaux' => [
|
||||
|
|
@ -67,16 +67,16 @@ $email = [
|
|||
'sous_total_reduction' => '0.00' === $commande->get_discount_total()
|
||||
? '0'
|
||||
: Number::format((float) $commande->get_discount_total(), maxPrecision: 2) . '€',
|
||||
'total' => Number::format((float) $commande->get_total(), maxPrecision: 2) . '€'
|
||||
]
|
||||
'total' => Number::format((float) $commande->get_total(), maxPrecision: 2) . '€',
|
||||
],
|
||||
];
|
||||
// Transforme les codes de pays en noms de pays
|
||||
$email['adresses']['livraison']['country'] = WC()->countries->countries[$commande->get_shipping_country()];
|
||||
$email['adresses']['facturation']['country'] = WC()->countries->countries[$commande->get_billing_country()];
|
||||
|
||||
$contexte['commande'] = $email;
|
||||
$context['commande'] = $email;
|
||||
// Rendu
|
||||
Timber::render(
|
||||
filenames: $modeles,
|
||||
data: $contexte
|
||||
filenames: $templates,
|
||||
data: $context,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -20,9 +20,9 @@ if (!defined('ABSPATH')) {
|
|||
Timber::init();
|
||||
// Sélectionne le répertoire contenant les modèles Twig
|
||||
Timber::$dirname = ['views'];
|
||||
// Contexte et modèles
|
||||
$contexte = Timber::context();
|
||||
$modeles = ['email-commande-recue.twig'];
|
||||
|
||||
$context = Timber::context();
|
||||
$templates = ['email-commande-recue.twig'];
|
||||
|
||||
/** @var Order $commande La Commande issue du contexte contenu dans la variable $order. */
|
||||
$commande = $order;
|
||||
|
|
@ -47,14 +47,14 @@ $email = [
|
|||
? collect($produit->get_attributes())
|
||||
->mapWithKeys(static fn($_atr, $cle): array => [
|
||||
'nom' => Str::lower(wc_attribute_label($cle, $produit)),
|
||||
'valeur' => $produit->get_attribute($cle)
|
||||
'valeur' => $produit->get_attribute($cle),
|
||||
])
|
||||
->toArray()
|
||||
: [],
|
||||
'lien' => $produit->get_permalink(),
|
||||
'nom' => $produit->get_title(),
|
||||
'prix_total' => $article->get_total(),
|
||||
'quantite' => $article->get_quantity()
|
||||
'quantite' => $article->get_quantity(),
|
||||
];
|
||||
}),
|
||||
'totaux' => [
|
||||
|
|
@ -63,17 +63,17 @@ $email = [
|
|||
'sous_total_reduction' => '0.00' === $commande->get_discount_total()
|
||||
? '0'
|
||||
: Number::format((float) $commande->get_discount_total(), maxPrecision: 2) . '€',
|
||||
'total' => Number::format((float) $commande->get_total(), maxPrecision: 2) . '€'
|
||||
]
|
||||
'total' => Number::format((float) $commande->get_total(), maxPrecision: 2) . '€',
|
||||
],
|
||||
];
|
||||
// Transforme les codes de pays en noms de pays
|
||||
$email['adresses']['livraison']['country'] = WC()->countries->countries[$commande->get_shipping_country()];
|
||||
$email['adresses']['facturation']['country'] = WC()->countries->countries[$commande->get_billing_country()];
|
||||
|
||||
$contexte['commande'] = $email;
|
||||
$context['commande'] = $email;
|
||||
|
||||
// Rendu
|
||||
Timber::render(
|
||||
filenames: $modeles,
|
||||
data: $contexte
|
||||
filenames: $templates,
|
||||
data: $context,
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue