Tout savoir sur WordPress
Tutoriel WordPress

Un seul mot de passe pour toute une hiérarchie de pages

Par défaut, il n’est pas possible d’attribuer un mot de passe de page privée à toute une hiérarchie. Découvrez comment définir un seul et unique mot de passe pour toute une hiérarchie de page (parent, enfant, etc..).

Derrière ce titre un peu ambigu se cache une astuce très pratique. Il s’agit de faire en sorte qu’une hiérarchie de pages n’ait qu’un seul et unique mot de passe; ceci dans le but qu’un seul mot de passe soit envoyé pour lire toutes ces pages. De plus, lors de la modification du mot de passe d’une de ces pages, que ce soit via la page parent ou l’une des pages enfant, le mot de passe doit se mettre à jour partout.

Copier le code ci-dessous dans le fichier functions.php présent à la racine de votre thème :

[pastacode lang=”php” message=”” highlight=”” provider=”manual”]


if( is_admin() ) :
function bawmpp_update_password( $post_id ) {
	
    // Si c'est une sauvegarde auto, on ne fait rien
    if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ):
	return $post_id;
	
    // si on a bien un ID et un pass envoyé
    elseif( isset( $_POST['post_ID'], $_POST['post_password'] ) ):
	
        // si la requete vient d'ajax, on vérifie nous aussi son token 
	if( defined( 'DOING_AJAX' ) && DOING_AJAX && !wp_verify_nonce( $_POST['_inline_edit'], 'inlineeditnonce' ) )
		check_admin_referer( 'inlineeditnonce', '_inline_edit' );
	
        global $wpdb;
	
        // Si le champ "hidden_post_password" n'est pas envoyé 
        // (quick edit n'envoie pas) on le set à vide
	$_POST['hidden_post_password'] = isset( $_POST['hidden_post_password'] ) ? $_POST['hidden_post_password']  : '';
	
        // Si le pass envoyé est bien une mise à jour (ou création) 
        // on mets à jour tous les posts enfants et enfants d'enfants etc
	if( ( defined( 'DOING_AJAX' ) && DOING_AJAX ) || $_POST['post_password']!=$_POST['hidden_post_password'] ):
            
            // Je crée une chaine avec des IDs corrects
	    $ids = implode( ',', array_filter( array_map( 'intval', get_all_children( $_POST['post_ID'] ) ) ) );
	    $wpdb->query( $wpdb->prepare( 'UPDATE ' . $wpdb->posts . ' SET post_password = %s WHERE ID in ( ' . $ids . ' )', $_POST['post_password'] ) );

	endif;

    endif;
}
add_action('save_post', 'bawmpp_update_password' );
endif;

[/pastacode]

  • On commence par vérifier qu’on a bien envoyé un ID et un mot de passe.
  • Si on le fait via AJAX (quick edit), on vérifie le referer et le token de sécurité.
  • Puis on met à jour le mot de passe.
  • Sinon, via la page d’édition on peut vérifier que le mot de passe a été modifié avant de lancer les requêtes.

A propos de ces requêtes, il peut y en avoir beaucoup, mais comme nous sommes du côté admin et que cela n’intervient que lors de la modification du mot de passe, cela n’est pas gênant.

Dans ce code, j’utilise get_all_children() qui est ma fonction :
[pastacode lang=”php” message=”” highlight=”” provider=”manual”]

function get_all_children( $post_id ) {

    // Récupération du parent le plus haut
    $post_id = get_top_most_parent( $post_id );

    // Création du tableau d'IDs, j'y ajoute de suite mon parent
    $ids = array( $post_id );
	
    // Pour chaque enfants trouvés, je les ajoute dans mon tableau
    foreach( get_child_ids( $post_id ) as $id ):
	$ids[] = $id;
	$ids = array_merge( get_child_ids( $id, $post_types ), $ids );
    endforeach;

    // je retourne le tableau
    return $ids;
}

[/pastacode]

Une nouvelle fois j’utilise une fonction perso get_child_ids() et aussi get_top_most_parent(), les voici :

[pastacode lang=”php” message=”” highlight=”” provider=”manual”]

function get_child_ids( $post_id ) {

    // J'ai besoin de la classe WPDB
    global $wpdb;

    // je récupère les noms des types de posts dans une chaine à virgules
    $post_types = implode( '","', get_post_types( array( 'public'=>true, 'show_ui'=>true ), 'names' ) );

    // Et je récupère tous ses enfants
    $children = $wpdb->get_col( 'SELECT ID FROM ' . $wpdb->posts . ' WHERE post_status = "publish" AND post_type IN ("' . $post_types . '") AND post_parent = ' . (int)$post_id );

    // Et je les renvoie
    return $children;
}

[/pastacode]

et

[pastacode lang=”php” message=”” highlight=”” provider=”manual”]

function get_top_most_parent( $post_id ) {

    // Récupération de l'ID du parent du post ID passé en paramètre
    $parent_id = get_post( $post_id )->post_parent;
    
    // Je retourne cet ID si il vaut 0 sinon je tourne en boucle jusqu'a 0, 
    // qui sera donc le parent le plus haut
    return $parent_id==0 ? $post_id : get_top_most_parent( $parent_id );

}

[/pastacode]

Cet article a été mis à jour il y a 4537 jours - Il n'est peut être plus à jour !

Article écrit par Julio P.

Fondateur de SecuPress, l’extension de sécurité WordPress, Julio Potier est un Expert WordPress, un Formateur Expérimenté et un Consultant en Sécurité Web.

Il aime partager ses compétences et ses réflexions sur WordPress, donnant des conférences partout dans le monde.

6 Commentaires

  1. Bonjour et merci pour ces scripts très pratiques.
    /!\ Attention, dans la dernière fonction, “->” a été converti en “->”.

  2. Bonjour et merci pour ces scripts très pratiques.
    /! Attention, dans la dernière fonction, “->” a été converti en “-&gt ;”.

  3. Merci à toi.
    Oui il est vrai que les caractères > et > posent problème, mais cela va disparaitre avec la v3 du site #teaser !