'Traducteurs', 'labels' => [ 'name' => 'Traducteurs', 'singular_name' => 'Traducteur', 'add_new' => 'Ajouter un traducteur', 'add_new_item' => 'Ajouter un nouveau traducteur', 'edit_item' => 'Modifier le traducteur', 'new_item' => 'Nouveau traducteur', 'view_item' => 'Voir le traducteur', 'search_items' => 'Rechercher un traducteur', 'not_found' => 'Aucun traducteur trouvé', 'not_found_in_trash' => 'Aucun traducteur dans la corbeille', ], 'public' => true, 'show_in_menu' => true, 'menu_position' => 24, 'menu_icon' => 'dashicons-translation', 'supports' => ['title'], 'has_archive' => false, 'show_in_rest' => true, ]); // Déclaration de la taxonomie 'langue' (si pas déjà déclarée) self::register_taxonomy(); // Association de la taxonomie 'langue' au CPT 'traducteur' \register_taxonomy_for_object_type('langue', 'traducteur'); \register_taxonomy_for_object_type('organisme', 'traducteur'); } public static function register_taxonomy() { \register_taxonomy('langue', ['traducteur'], [ 'label' => 'Langues', 'labels' => [ 'name' => 'Langues', 'singular_name' => 'Langue', 'search_items' => 'Rechercher des langues', 'all_items' => 'Toutes les langues', 'edit_item' => 'Modifier la langue', 'update_item' => 'Mettre à jour la langue', 'add_new_item' => 'Ajouter une nouvelle langue', 'new_item_name' => 'Nom de la nouvelle langue', 'menu_name' => 'Langues', ], 'public' => true, 'show_ui' => true, 'show_in_menu' => true, 'show_in_nav_menus' => true, 'show_tagcloud' => false, 'show_in_quick_edit' => true, 'show_admin_column' => true, 'hierarchical' => false, // comme une étiquette 'show_in_rest' => true, 'rewrite' => [ 'slug' => 'langue' ], ]); \register_taxonomy('organisme', ['traducteur'], [ 'label' => 'Organismes', 'labels' => [ 'name' => 'Organismes', 'singular_name' => 'Organisme', ], 'public' => true, 'show_ui' => true, 'show_in_menu' => true, 'show_in_nav_menus' => true, 'show_tagcloud' => false, 'show_in_quick_edit' => true, 'show_admin_column' => true, 'hierarchical' => false, // comme une étiquette 'show_in_rest' => true, 'rewrite' => [ 'slug' => 'organisme' ], ]); } public static function get_traducteur_by_langue($langue) { $langue_obj = \get_term_by('slug', $langue, 'langue'); if (!$langue_obj) { return null; } $traducteurs = \get_posts([ 'post_type' => 'traducteur', 'tax_query' => [ [ 'taxonomy' => 'langue', 'field' => 'slug', 'terms' => $langue, // ou un tableau de slugs ], ], ]); return $traducteurs; } /** * Retourne les traducteurs disponibles à une date donnée et pour une langue donnée. * @param string $date au format Y-m-d * @param string $langue_slug (slug de la langue) * @return array Liste des traducteurs disponibles (CRVI_Traducteur_Model) */ public static function filtrer_disponibles($date, $langue_slug) { return CRVI_Traducteur_Model::filtrer_disponibles($date, $langue_slug); } public static function register_routes() { \register_rest_route('crvi/v1', '/traducteurs', [ [ 'methods' => 'GET', 'callback' => [self::class, 'get_items'], 'permission_callback' => '__return_true', ], [ 'methods' => 'POST', 'callback' => [self::class, 'create_item'], 'permission_callback' => [self::class, 'can_edit'], ], ]); \register_rest_route('crvi/v1', '/traducteurs/(?P\\d+)', [ [ 'methods' => 'GET', 'callback' => [self::class, 'get_item'], 'permission_callback' => '__return_true', ], [ 'methods' => 'PUT,PATCH', 'callback' => [self::class, 'update_item'], 'permission_callback' => [self::class, 'can_edit'], ], [ 'methods' => 'DELETE', 'callback' => [self::class, 'delete_item'], 'permission_callback' => [self::class, 'can_edit'], ], ]); } public static function get_item($request) { $id = (int) $request['id']; $traducteur = CRVI_Traducteur_Model::load($id); if (!$traducteur) { return [ 'success' => false, 'code' => 404, 'message' => 'Traducteur introuvable', 'data' => null ]; } return [ 'success' => true, 'data' => $traducteur ]; } public static function create_item($request) { $data = $request->get_json_params(); $validation = self::validate_traducteur_data($data); if (is_wp_error($validation)) { return Api_Helper::json_error($validation->get_error_message(), 400); } $result = CRVI_Traducteur_Model::create($data, true); if (!is_numeric($result)) { return $result; } return Api_Helper::json_success([ 'id' => $result, 'nom' => $data['nom'], 'message' => 'Traducteur créé avec succès' ]); } public static function update_item($request) { $id = (int) $request['id']; $data = $request->get_json_params(); $traducteur = new CRVI_Traducteur_Model(); $result = $traducteur->update($id, $data); if ($result !== true) { return $result; } return [ 'success' => true, 'data' => [ 'id' => $id, 'message' => 'Traducteur modifié avec succès' ] ]; } public static function delete_item($request) { $id = (int) $request['id']; $traducteur = new CRVI_Traducteur_Model(); $result = $traducteur->delete($id); if ($result !== true) { return $result; } return [ 'success' => true, 'data' => [ 'id' => $id, 'message' => 'Traducteur supprimé avec succès' ] ]; } public static function can_edit($request = null) { return current_user_can('edit_posts'); } // Handler pour l'import CSV via formulaire admin public static function import_csv_admin() { if (!current_user_can('edit_posts')) { wp_die('Non autorisé'); } check_admin_referer('crvi_import_traducteur'); if (empty($_FILES['import_csv']['tmp_name'])) { wp_redirect(admin_url('admin.php?page=crvi_agenda&import=error&msg=Fichier manquant')); exit; } $file = $_FILES['import_csv']['tmp_name']; $handle = fopen($file, 'r'); if (!$handle) { wp_redirect(admin_url('admin.php?page=crvi_agenda&import=error&msg=Impossible d\'ouvrir le fichier')); exit; } $header = fgetcsv($handle, 0, ','); $created = $updated = $errors = 0; while (($row = fgetcsv($handle, 0, ',')) !== false) { $data = array_combine($header, $row); $data = array_combine( array_map(function($k) { return sanitize_title($k); }, array_keys($data)), array_map('trim', array_values($data)) ); $result = CRVI_Traducteur_Model::create($data, true); if (is_numeric($result)) $created++; else $errors++; } fclose($handle); $msg = "Créés: $created, Modifiés: $updated, Erreurs: $errors"; wp_redirect(admin_url('admin.php?page=crvi_agenda&import=success&msg=' . urlencode($msg))); exit; } /** * Validation des données de traducteur */ public static function validate_traducteur_data($data) { if (empty($data['nom'])) { return new \WP_Error('missing_nom', 'Le nom est obligatoire'); } if (!empty($data['email']) && !is_email($data['email'])) { return new \WP_Error('invalid_email', 'L\'email n\'est pas valide'); } return true; } }