Giải pháp này lọc các chuỗi tìm kiếm bằng cách áp dụng một biểu thức chính quy chỉ khớp với các ký tự từ các tập lệnh Unicode thông dụng và Latin.
Kết hợp các ký tự Latin với các biểu thức chính quy
Tôi vừa mới suy nghĩ về Stack Overflow . Hóa ra, các biểu thức chính quy có một cơ chế khớp với toàn bộ các loại Unicode, bao gồm các giá trị để chỉ định toàn bộ "tập lệnh" Unicode , mỗi tập lệnh tương ứng với các nhóm ký tự được sử dụng trong các hệ thống chữ viết khác nhau.
Điều này được thực hiện bằng cách sử dụng \pký tự meta theo sau là mã định danh Unicode trong các dấu ngoặc nhọn - do đó [\p{Common}\p{Latin}]khớp với một ký tự trong các tập lệnh Latin hoặc Common - bao gồm dấu chấm câu, chữ số và ký hiệu linh tinh.
Như @Paul 'Sparrow Hawk' Biron chỉ ra , u cờ công cụ sửa đổi mẫu nên được đặt ở cuối biểu thức chính quy để các hàm PCRE của PHP xử lý chuỗi chủ đề như UTF-8được mã hóa Unicode.
Tất cả cùng nhau sau đó, mô hình
/^[\p{Latin}\p{Common}]+$/u
sẽ khớp với toàn bộ một chuỗi gồm một hoặc nhiều ký tự trong các tập lệnh Unicode và Latin phổ biến.
Lọc chuỗi tìm kiếm
Một nơi tốt để đánh chặn một chuỗi tìm kiếm là những pre_get_postshành động như nó cháy ngay trước WordPress thực hiện truy vấn. Với dịch vụ chăm sóc nhiều hơn , điều này cũng có thể được thực hiện sử dụng một requestbộ lọc .
function wpse261038_validate_search_characters( $query ) {
// Leave admin, non-main query, and non-search queries alone
if( is_admin() || !$query->is_main_query() || !$query->is_seach() )
return;
// Check if the search string contains only Latin/Common Unicode characters
$match_result = preg_match( '/^[\p{Latin}\p{Common}]+$/u', $query->get( 's' ) );
// If the search string only contains Latin/Common characters, let it continue
if( 1 === $match_result )
return;
// If execution reaches this point, the search string contains non-Latin characters
//TODO: Handle non-Latin search strings
//TODO: Set up logic to display error message
}
add_action( 'pre_get_posts', 'wpse261038_validate_search_characters' );
Đáp ứng các tìm kiếm không được phép
Khi đã xác định rằng chuỗi tìm kiếm có chứa các ký tự không phải là tiếng Latinh, bạn có thể sử dụng WP_Query::set()để sửa đổi truy vấn bằng cách thay đổi các vars truy vấn có tên - do đó ảnh hưởng đến truy vấn SQL sau đó WordPress sẽ thực hiện và thực thi.
Các biến truy vấn phù hợp nhất có lẽ là như sau:
slà biến truy vấn tương ứng với chuỗi tìm kiếm. Đặt nó thành nullhoặc một chuỗi trống ( '') sẽ dẫn đến việc WordPress không còn coi truy vấn là tìm kiếm - thường sẽ dẫn đến kết quả này trong một mẫu lưu trữ hiển thị tất cả các bài đăng hoặc trang nhất của trang web, tùy thuộc vào các giá trị của cái khác vars truy vấn. ' 'Tuy nhiên, đặt nó thành một không gian ( ), sẽ dẫn đến việc WordPress nhận ra nó là một tìm kiếm và do đó cố gắng hiển thị search.phpmẫu.
page_id có thể được sử dụng để hướng người dùng đến một trang cụ thể mà bạn chọn.
post__incó thể hạn chế truy vấn đến một lựa chọn cụ thể của bài viết. Bằng cách đặt nó thành một mảng với ID bài đăng không thể, nó có thể dùng làm thước đo để đảm bảo rằng truy vấn hoàn toàn không có gì .
Ở trên, bạn có thể thực hiện các thao tác sau để phản hồi tìm kiếm xấu bằng cách tải search.phpmẫu không có kết quả:
function wpse261038_validate_search_characters( $query ) {
// Leave admin, non-main query, and non-search queries alone
if( is_admin() || !$query->is_main_query() || !$query->is_seach() )
return;
// Check if the search string contains only Latin/Common Unicode characters
$match_result = preg_match( '/^[\p{Latin}\p{Common}]+$/u', $query->get( 's' ) );
// If the search string only contains Latin/Common characters, let it continue
if( 1 === $match_result )
return;
$query->set( 's', ' ' ); // Replace the non-latin search with an empty one
$query->set( 'post__in', array(0) ); // Make sure no post is ever returned
//TODO: Set up logic to display error message
}
add_action( 'pre_get_posts', 'wpse261038_validate_search_characters' );
Hiển thị một lỗi
Cách bạn thực sự hiển thị thông báo lỗi phụ thuộc rất nhiều vào ứng dụng của bạn và khả năng của chủ đề của bạn - có nhiều cách có thể được thực hiện. Nếu chủ đề của bạn gọi get_search_form()trong mẫu tìm kiếm, giải pháp đơn giản nhất có lẽ là sử dụng móc pre_get_search_formhành động để đưa ra lỗi của bạn ngay trên biểu mẫu tìm kiếm:
function wpse261038_validate_search_characters( $query ) {
// Leave admin, non-main query, and non-search queries alone
if( is_admin() || !$query->is_main_query() || !$query->is_seach() )
return;
// Check if the search string contains only Latin/Common Unicode characters
$match_result = preg_match( '/^[\p{Latin}\p{Common}]+$/u', $query->get( 's' ) );
// If the search string only contains Latin/Common characters, let it continue
if( 1 === $match_result )
return;
$query->set( 's', ' ' ); // Replace the non-latin search with an empty one
$query->set( 'post__in', array(0) ); // Make sure no post is ever returned
add_action( 'pre_get_search_form', 'wpse261038_display_search_error' );
}
add_action( 'pre_get_posts', 'wpse261038_validate_search_characters' );
function wpse261038_display_search_error() {
echo '<div class="notice notice-error"><p>Your search could not be completed as it contains characters from non-Latin alphabets.<p></div>';
}
Một số khả năng khác để hiển thị thông báo lỗi bao gồm:
- Nếu trang web của bạn sử dụng JavaScript có thể hiển thị thông báo "flash" hoặc "phương thức" (hoặc bạn tự thêm các khả năng đó), hãy thêm vào logic để hiển thị thông báo khi tải trang khi đặt một biến cụ thể, sau đó thêm
wp_enqueue_scriptmóc với giá trị $prioritylớn hơn mã JavaScript đó và sử dụng wp_localize_script()để đặt biến đó để bao gồm thông báo lỗi của bạn.
- Sử dụng
wp_redirect()để gửi người dùng đến URL bạn chọn (phương pháp này yêu cầu tải trang bổ sung).
- Đặt một biến PHP hoặc gọi một phương thức sẽ thông báo cho chủ đề / plugin của bạn về lỗi để nó có thể hiển thị nó khi thích hợp.
- Đặt
sbiến truy vấn thành ''thay vì ' 'và sử dụng page_idthay post__incho để trả về một trang bạn chọn.
- Sử dụng một
loop_startcái móc để tiêm một WP_Postđối tượng giả mạo có chứa lỗi của bạn vào kết quả truy vấn - đây chắc chắn là một vụ hack xấu xí và có thể không phù hợp với chủ đề cụ thể của bạn, nhưng nó có tác dụng phụ đáng mong muốn là loại bỏ thông báo "Không có kết quả".
- Sử dụng
template_includemóc lọc để trao đổi mẫu tìm kiếm với mẫu tùy chỉnh trong chủ đề hoặc plugin hiển thị lỗi của bạn.
Nếu không kiểm tra chủ đề được đề cập, thật khó để xác định tuyến đường nào bạn nên đi.