Quando si imposta un post come protetto da password, la protezione si verifica sulla get_the_content()
funzione. Lì WordPress verifica la presenza di un cookie post password e, se non impostato, non valido o scaduto, mostra il modulo password.
Questo modulo di password viene inviato wp-login.php
, lì viene impostato un cookie in base alla password scritta nel modulo, quindi la richiesta viene reindirizzata nuovamente al post.
Il processo può essere descritto in questo modo:
- vai alla pagina dei post
- chiama the_content ()
- controlla il cookie
- se non valido mostra il modulo password
- invia il modulo a wp_login.php
- wp_login.php
- imposta il cookie in base a pwd inviato e reindirizza alla pagina dei post
- ricomincia dal modulo n. 1
Ciò che possiamo fare:
- al punto 4 usa l'hook
'the_password_form'
per modificare l'output del modulo, aggiungendo un campo per l'e-mail e un campo nascosto con l'id post (a questo punto siamo all'interno della get_the_content
funzione quindi abbiamo accesso alla variabile post globale)
- Sfortunatamente al punto 3 non possiamo modificare il risultato del controllo dei cookie (o almeno non possiamo farlo in modo facile e affidabile). Ma al punto 7 WordPress ha un hook di filtro che consente di impostare la scadenza del cookie: se impostiamo quel tempo su un timestamp passato, il cookie non verrà impostato (e se esistex verrà eliminato) e quindi la convalida fallirà . Quindi possiamo usare quell'hook per controllare l'e-mail inviata tramite il modulo e grazie all'ID post nel campo nascosto possiamo confrontarlo con le e-mail nel meta, se l'e-mail non viene fornita o è errata restituiamo un timestamp passato.
Primo passo:
/**
* Customize the form, adding a field for email and a hidden field with the post id
*/
add_filter( 'the_password_form', function( $output ) {
unset( $GLOBALS['the_password_form'] );
global $post;
$submit = '<input type="submit" name="Submit" value="' . esc_attr__('Submit') . '" /></p>';
$hidden = '<input type="hidden" name="email_res_postid" value="' . $post->ID . '">';
$email = '</p><p><label for="email_res">' . __( 'Email:' );
$email .= '<input name="email_res" id="email_res" type="text" size="20" /></label></p><p>';
return str_replace( $submit, $hidden . $email . $submit, $output );
}, 0 );
E il secondo:
/**
* Set the post password cookie expire time based on the email
*/
add_filter( 'post_password_expires', function( $valid ) {
$postid = filter_input( INPUT_POST, 'email_res_postid', FILTER_SANITIZE_NUMBER_INT );
$email = filter_input( INPUT_POST, 'email_res', FILTER_SANITIZE_STRING );
// a timestamp in the past
$expired = time() - 10 * DAY_IN_SECONDS;
if ( empty( $postid ) || ! is_numeric( $postid ) ) {
// empty or bad post id, return past timestamp
return $expired;
}
if ( empty($email) || ! filter_var($email, FILTER_VALIDATE_EMAIL) ) {
// empty or bad email id, return past timestamp
return $expired;
}
// get the allowed emails
$allowed = array_filter( (array)get_post_meta( $postid, 'allow_email' ), function( $e ) {
if ( filter_var( $e, FILTER_VALIDATE_EMAIL) ) return $e;
});
if ( ! empty( $allowed ) ) { // some emails are setted, let's check it
// if the emails posted is good return the original expire time
// otherwise return past timestamp
return in_array( $email, $allowed ) ? $valid : $expired;
}
// no emails are setted, return the original expire time
return $valid;
}, 0 );
Abbiamo chiuso.
Ora crea un post, salva come protetto da password e imposta alcune e-mail consentite nei campi personalizzati utilizzando la chiave 'allow_email'
. Non c'è limite al numero di email che puoi aggiungere ...
Impostazioni:
Risultato (TwentyThirteen senza stile aggiuntivo):