Dans un projet WordPress, nous avions besoin d’utiliser deux types de contenu personnalisé (CPT) qui doivent être liés entre eux. L’objectif est d’établir une relation bidirectionnelle entre ces deux CPT. Cela signifie que lorsqu’un utilisateur associe un élément du premier CPT à un autre élément dans le second CPT via un champ de relation, cette association doit être répercutée dans l’autre sens.
Exemple :
- Si tu as deux CPT : « Professeurs » et « Cours ».
- Si tu associes un professeur à un cours, il faut que le cours soit aussi automatiquement lié au professeur.
Explication des parties importantes du code :
- Détection de l’enregistrement automatique : La première condition empêche l’exécution de la fonction lors d’une sauvegarde automatique pour éviter les mises à jour inutiles ou non souhaitées.
- Récupération du type de post :
get_post_type($post_id)etget_the_terms($post_id, 'format')sont utilisés pour identifier le type de post et le format associé (si applicable). - Premier bloc de synchronisation :
- Si le post appartient au type
custom_post_type_1(nom générique), il récupère les relations stockées dansrelated_field_1(premier champ relationnel). - Pour chaque relation, il vérifie si le post lié a bien l’ID du post actuel dans son propre champ relationnel (
related_field_2). - Si ce n’est pas le cas, il ajoute cette relation et met à jour le champ avec
update_field().
- Si le post appartient au type
- Deuxième bloc de synchronisation :
- Ce bloc fait exactement la même chose, mais dans l’autre sens : s’il s’agit d’un post de type
custom_post_type_2, il synchronise les relations du champrelated_field_2avecrelated_field_1dans le post lié.
- Ce bloc fait exactement la même chose, mais dans l’autre sens : s’il s’agit d’un post de type
- Attachement au hook
acf/save_post: La fonction est exécutée à chaque fois qu’un post est sauvegardé via ACF, en utilisant le hook avec une priorité de20pour s’assurer que cela se passe après les autres opérations.
Noms génériques :
custom_post_type_1etcustom_post_type_2représentent les deux types de contenu personnalisé (CPT).related_field_1etrelated_field_2représentent les champs de relation entre ces deux types de CPT.
function sync_acf_relationship_fields($post_id) {
// Empêcher l'exécution du code pendant une sauvegarde automatique
if (is_admin() && defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
// Récupérer le type de contenu personnalisé (CPT) du post actuel
$post_type = get_post_type($post_id);
// Récupérer les termes associés à la taxonomie 'format' du post actuel
$post_format = get_the_terms($post_id, 'format');
// Vérifier si le post appartient au premier type de CPT ('cpt_slug')
// et que le format correspond (si applicable)
if ($post_type == 'custom_post_type_1' && $post_format[0]->slug == 'format_slug') {
// Récupérer les relations à synchroniser pour le premier champ personnalisé
$related_posts_1 = get_field('related_field_1', $post_id);
if ($related_posts_1) {
// Parcourir chaque relation pour les synchroniser dans l'autre sens
foreach ($related_posts_1 as $related_post_id) {
// Récupérer les relations existantes dans le second champ du post lié
$existing_related_posts = get_field('related_field_2', $related_post_id);
if (!$existing_related_posts) {
$existing_related_posts = array(); // Initialiser si vide
}
// Si le post actuel n'est pas déjà dans les relations, l'ajouter
if (!in_array($post_id, $existing_related_posts)) {
$existing_related_posts[] = $post_id;
// Mettre à jour le champ relationnel dans le post lié
update_field('related_field_2', $existing_related_posts, $related_post_id);
}
}
}
}
// Vérifier si le post appartient au second type de CPT ('cpt_slug_2')
if ($post_type == 'custom_post_type_2') {
// Récupérer les relations à synchroniser pour le second champ personnalisé
$related_posts_2 = get_field('related_field_2', $post_id);
if ($related_posts_2) {
// Parcourir chaque relation pour les synchroniser dans l'autre sens
foreach ($related_posts_2 as $related_post_id) {
// Récupérer les relations existantes dans le premier champ du post lié
$existing_related_posts = get_field('related_field_1', $related_post_id);
if (!$existing_related_posts) {
$existing_related_posts = array(); // Initialiser si vide
}
// Si le post actuel n'est pas déjà dans les relations, l'ajouter
if (!in_array($post_id, $existing_related_posts)) {
$existing_related_posts[] = $post_id;
// Mettre à jour le champ relationnel dans le post lié
update_field('related_field_1', $existing_related_posts, $related_post_id);
}
}
}
}
}
// Attacher la fonction à l'action 'acf/save_post' pour synchroniser après la sauvegarde d'un post
add_action('acf/save_post', 'sync_acf_relationship_fields', 20);