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 \p
ký 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_posts
hà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 request
bộ 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:
s
là biến truy vấn tương ứng với chuỗi tìm kiếm. Đặt nó thành null
hoặ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.php
mẫ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__in
có 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.php
mẫ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_form
hà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_script
móc với giá trị $priority
lớ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
s
biến truy vấn thành ''
thay vì ' '
và sử dụng page_id
thay post__in
cho để trả về một trang bạn chọn.
- Sử dụng một
loop_start
cá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_include
mó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.