Wenn Sie einen Beitrag als passwortgeschützt festlegen, erfolgt der Schutz für die get_the_content()
Funktion. Dort prüft WordPress auf ein Post-Passwort-Cookie und zeigt das Passwort-Formular an, wenn es nicht gesetzt, ungültig oder abgelaufen ist.
Dieses Passwortformular wird an gesendet wp-login.php
, dort wird ein Cookie gemäß dem im Formular angegebenen Passwort gesetzt und die Anfrage erneut an den Beitrag weitergeleitet.
Der Prozess kann folgendermaßen beschrieben werden:
- Gehe zur Post-Seite
- rufe the_content () auf
- Überprüfen Sie den Cookie
- Wenn nicht gültig, zeigen Sie das Passwortformular an
- Senden Sie das Formular an wp_login.php
- wp_login.php
- Setzen Sie das Cookie basierend auf dem eingereichten pwd und leiten Sie es zur Post-Seite weiter
- Starten Sie erneut von Formular 1
Was wir tun können:
- Verwenden Sie an Punkt 4 den Hook
'the_password_form'
, um die Ausgabe des Formulars zu bearbeiten, und fügen Sie ein Feld für die E-Mail und ein verstecktes Feld mit der Post-ID hinzu (an diesem Punkt befinden wir uns innerhalb der get_the_content
Funktion, sodass wir Zugriff auf die globale Post-Variable haben).
- Leider können wir bei Punkt 3 das Ergebnis der Cookie-Prüfung nicht ändern (oder zumindest nicht auf einfache und zuverlässige Weise). Aber an Punkt 7 hat WordPress einen Filter-Hook, mit dem der Cookie-Ablauf festgelegt werden kann: Wenn wir diese Zeit auf einen vergangenen Zeitstempel setzen, wird das Cookie nicht gesetzt (und wenn es existiert, wird es gelöscht) und die Validierung schlägt fehl . Mit diesem Hook können wir die über das Formular gesendete E-Mail überprüfen und dank der Post-ID im ausgeblendeten Feld mit den E-Mails im Meta vergleichen. Wenn die E-Mail nicht angegeben oder falsch ist, geben wir einen vergangenen Zeitstempel zurück.
Erster Schritt:
/**
* 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 );
Und der zweite:
/**
* 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 );
Wir sind fertig.
Erstellen Sie nun einen Beitrag, speichern Sie ihn als kennwortgeschützt und legen Sie mit dem Schlüssel einige zulässige E-Mails in benutzerdefinierten Feldern fest 'allow_email'
. Die Anzahl der E-Mails, die Sie hinzufügen können, ist unbegrenzt.
Die Einstellungen:
Ergebnis (TwentyThirteen ohne zusätzliches Styling):