Khi bạn đặt một bài đăng là mật khẩu được bảo vệ, get_the_content()
chức năng bảo vệ sẽ xảy ra trên chức năng. Có WordPress kiểm tra cookie mật khẩu bài đăng và nếu không được đặt, không hợp lệ hoặc hết hạn thì hiển thị biểu mẫu mật khẩu.
Biểu mẫu mật khẩu này được gửi tới wp-login.php
, có một cookie được giải quyết theo mật khẩu được ghi trong biểu mẫu, sau đó yêu cầu được chuyển hướng đến bài đăng một lần nữa.
Quá trình có thể được mô tả như vậy:
- đi đến trang bài
- gọi the_content ()
- kiểm tra cookie
- nếu không hợp lệ hiển thị mẫu mật khẩu
- gửi biểu mẫu đến wp_login.php
- wp_login.php
- đặt cookie dựa trên pwd đã gửi và chuyển hướng đến trang đăng
- bắt đầu lại mẫu số 1
Những gì chúng ta có thể làm:
- tại điểm # 4 sử dụng hook
'the_password_form'
để chỉnh sửa đầu ra của biểu mẫu, thêm trường cho email và trường ẩn với id bài đăng (tại thời điểm này chúng tôi đang ở trong get_the_content
chức năng để chúng tôi có quyền truy cập vào biến bài đăng toàn cầu)
- Thật không may ở điểm số 3 , chúng tôi không thể thay đổi kết quả kiểm tra cookie (hoặc ít nhất là chúng tôi không thể theo cách dễ dàng và đáng tin cậy). Nhưng tại điểm số 7, WordPress có một móc lọc cho phép đặt hết hạn cookie: nếu chúng ta đặt thời gian đó thành dấu thời gian trong quá khứ, thì cookie sẽ không được đặt (và nếu tồn tại thì nó sẽ bị xóa) và vì vậy việc xác thực sẽ thất bại . Vì vậy, chúng tôi có thể sử dụng móc đó để kiểm tra email được gửi qua biểu mẫu và nhờ id bài đăng trong trường ẩn, chúng tôi có thể so sánh nó với các email trong meta, nếu email không được đưa ra hoặc sai, chúng tôi sẽ trả lại dấu thời gian trong quá khứ.
Bước đầu tiên:
/**
* 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 );
Va thu hai:
/**
* 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 );
Chúng ta xong rồi.
Bây giờ hãy tạo một bài đăng, lưu dưới dạng mật khẩu được bảo vệ và đặt một số email được phép trong các trường tùy chỉnh bằng khóa 'allow_email'
. Không có giới hạn về số lượng email bạn có thể thêm ...
Cài đặt:
Kết quả (TwentyThirteen không có kiểu dáng bổ sung):