geste de tri. * Catégories alignées sur la signalétique Info-tri (Citeo). Source : docs/regulatory/. * * @package AgecReady */ namespace AgecReady\Compliance; defined( 'ABSPATH' ) || exit; final class InfoTri { /** * Matériaux d'emballage (slug => libellé). * * @return array */ public static function materials(): array { return array( 'carton' => __( 'Carton / papier', 'agec-ready' ), 'bouteille' => __( 'Bouteille / flacon plastique', 'agec-ready' ), 'plastique' => __( 'Autre emballage plastique', 'agec-ready' ), 'metal' => __( 'Métal (acier / aluminium)', 'agec-ready' ), 'verre' => __( 'Verre', 'agec-ready' ), 'brique' => __( 'Brique alimentaire', 'agec-ready' ), ); } /** * Gestes de tri possibles (slug => libellé). * * @return array */ public static function consignes(): array { return array( 'tri' => __( 'Bac de tri', 'agec-ready' ), 'verre' => __( 'Bac à verre', 'agec-ready' ), 'ordures' => __( 'Bac ordures ménagères', 'agec-ready' ), 'collecte' => __( 'Point de collecte / déchèterie', 'agec-ready' ), 'compost' => __( 'Compostage', 'agec-ready' ), ); } /** * Consigne de tri légale par matériau — **gabarit Citeo** « extension des consignes de tri » * (depuis 2023, tous les emballages ménagers se trient → bac de tri ; le verre → bac à verre). * Source : docs/regulatory/emballages.md (Citeo). C'est la SEULE consigne proposée par matériau : * on n'autorise pas de combinaison libre matériau×geste (findings-08 #4). * * @return array */ public static function default_consignes(): array { return array( 'carton' => 'tri', 'bouteille' => 'tri', 'plastique' => 'tri', 'metal' => 'tri', 'verre' => 'verre', 'brique' => 'tri', ); } /** Consigne légale (gabarit Citeo) d'un matériau, ou '' si matériau inconnu. */ public static function default_consigne( string $material ): string { $defaults = self::default_consignes(); return $defaults[ $material ] ?? ''; } /** Vrai si la paire {matériau => geste} est conforme au gabarit Citeo (seule paire légale). */ public static function is_legal_pair( string $material, string $consigne ): bool { return '' !== $consigne && self::default_consigne( $material ) === $consigne; } /** * Options de consigne pour un matériau : « — Non concerné — » + l'UNIQUE geste légal (gabarit Citeo). * Remplace l'ancien consigne_options() qui offrait les 5 gestes pour tous les matériaux (combinaisons * libres → fausses consignes possibles, findings-08 #4). Partagé par le wizard et les champs produit (DRY). * * @param string $material Slug du matériau. * @return array */ public static function consigne_options_for( string $material ): array { $opts = array( '' => __( '— Non concerné —', 'agec-ready' ) ); $default = self::default_consigne( $material ); $labels = self::consignes(); if ( '' !== $default && isset( $labels[ $default ] ) ) { $opts[ $default ] = $labels[ $default ]; } return $opts; } /** * Normalise une saisie {matériau => geste} : ne garde que les paires connues. * * @param mixed $raw Données brutes (issues du formulaire). * @return array */ public static function sanitize_components( $raw ): array { if ( ! is_array( $raw ) ) { return array(); } $materials = self::materials(); $clean = array(); foreach ( $raw as $material => $consigne ) { if ( ! is_string( $material ) || ! is_string( $consigne ) ) { continue; } // Garde-fou #4 : on ne garde que les paires LÉGALES (gabarit Citeo) — pas n'importe quelle // combinaison matériau×geste. Une boutique ne peut pas publier une consigne fausse. if ( isset( $materials[ $material ] ) && self::is_legal_pair( $material, $consigne ) ) { $clean[ $material ] = $consigne; } } return $clean; } }