Je voudrais limiter la recherche aux caractères utilisés sur la langue anglaise + les chiffres. La raison en est qu'en regardant les requêtes les plus lentes sur le journal mysql, je trouve que la plupart proviennent de recherches en caractères arabes, russes et chinois, donc je voudrais les ignorer et afficher un message d'erreur à la place.
9
Réponses:
Cette solution filtre les chaînes de recherche en appliquant une expression régulière qui ne correspond qu'aux caractères des scripts Unicode commun et latin.
Faire correspondre les caractères latins aux expressions régulières
Je venais juste d' avoir le souffle coupé à Stack Overflow . Il s'avère que les expressions régulières ont un mécanisme pour faire correspondre des catégories Unicode entières, y compris des valeurs pour spécifier des "scripts" Unicode entiers , chacun correspondant à des groupes de caractères utilisés dans différents systèmes d'écriture.
Cela se fait en utilisant le
\p
méta-caractère suivi d'un identifiant de catégorie Unicode entre accolades -[\p{Common}\p{Latin}]
correspond donc à un seul caractère dans les scripts latin ou commun - cela inclut la ponctuation, les chiffres et les symboles divers.Comme le souligne @Paul 'Sparrow Hawk' Biron , l'
u
indicateur de modificateur de modèle doit être défini à la fin de l'expression régulière afin que les fonctions PCRE de PHP traitent la chaîne en question commeUTF-8
codée Unicode.Tous ensemble alors, le motif
correspondra à une chaîne entière composée d'un ou plusieurs caractères dans les scripts Latin et Common Unicode.
Filtrage de la chaîne de recherche
Un bon endroit pour intercepter une chaîne de recherche est l'
pre_get_posts
action car elle se déclenche immédiatement avant que WordPress n'exécute la requête. Avec plus de soin , cela pourrait également être accompli en utilisant unrequest
filtre .Répondre aux recherches non autorisées
Une fois qu'il a été déterminé qu'une chaîne de recherche contient des caractères non latins, vous pouvez utiliser
WP_Query::set()
afin de modifier la requête en changeant son nom de variable de requête - affectant ainsi la requête SQL que WordPress compose et exécute ensuite.Les variables de requête les plus pertinentes sont probablement les suivantes:
s
est la variable de requête correspondant à une chaîne de recherche. Si vous le définissez surnull
ou une chaîne vide (''
), WordPress ne traitera plus la requête comme une recherche - cela aboutit souvent à un modèle d'archive affichant toutes les publications ou la première page du site, selon les valeurs de l'autre requête vars.' '
Cependant, si vous le définissez sur un seul espace ( ), WordPress le reconnaîtra comme une recherche et tentera donc d'afficher lesearch.php
modèle.page_id
pourrait être utilisé pour diriger l'utilisateur vers une page spécifique de votre choix.post__in
peut restreindre la requête à une sélection spécifique de publications. En le définissant sur un tableau avec un ID de publication impossible, il peut servir de mesure pour garantir que la requête ne renvoie absolument rien .Ce qui précède à l'esprit, vous pouvez faire ce qui suit afin de répondre à une mauvaise recherche en chargeant le
search.php
modèle sans résultat:Affichage d'une erreur
La façon dont vous affichez réellement le message d'erreur dépend fortement de votre application et des capacités de votre thème - il y a plusieurs façons de le faire. Si votre thème appelle
get_search_form()
dans son modèle de recherche, la solution la plus simple consiste probablement à utiliser un crochet d'pre_get_search_form
action pour afficher votre erreur immédiatement au-dessus du formulaire de recherche:Voici d'autres possibilités pour afficher un message d'erreur:
wp_enqueue_script
crochet avec un$priority
plus grand que celui qui met en file d'attente ce JavaScript, et utilisezwp_localize_script()
pour définir cette variable pour inclure votre message d'erreur.wp_redirect()
pour envoyer l'utilisateur à l'URL de votre choix (cette méthode nécessite un chargement de page supplémentaire).s
variable de requête à la''
place de' '
et utilisezpage_id
à la place depost__in
afin de retourner une page de votre choix.loop_start
crochet pour injecter un fauxWP_Post
objet contenant votre erreur dans les résultats de la requête - il s'agit certainement d'un vilain hack et peut ne pas convenir à votre thème particulier, mais il a l'effet secondaire potentiellement souhaitable de supprimer le message "Aucun résultat".template_include
crochet de filtre pour échanger le modèle de recherche avec un modèle personnalisé dans votre thème ou plug-in qui affiche votre erreur.Sans examiner le thème en question, il est difficile de déterminer l'itinéraire à suivre.
la source
Pour ce faire, mettez une fonction de validation en PHP pour tester l'entrée par rapport à une expression régulière comme
^[a-zA-Z0-9,.!?' ]*
Donc, cela ressemblerait à ceci:
Le RexEx j'ai utilisé pour tous les personnages
A-Z
,a-z
,0-9
, ainsi que,
,.
,!
,?
,'
,"
, et(espace).
la source
EDIT: Cette solution n'est pas recommandée
Un moyen d'empêcher les recherches utilisant des alphabets non latins consiste à utiliser la
mb_detect_encoding()
fonction PHP pour voir si la chaîne de recherche est conforme à l'une d'une sélection personnalisée d'encodages de caractères. Un bon endroit pour le faire est l' unepre_get_posts
action , comme il se déclenche juste avant que la requête est exécutée.Ce que vous faites réellement après avoir déterminé qu'une recherche utilise un encodage invalide est vraiment spécifique à l'application. Ici, j'ai défini la requête de recherche sur un seul espace pour garantir que WordPress interprète toujours la requête comme une recherche et charge donc toujours le
search.php
modèle (et ne dirige pas l'utilisateur vers la page d'accueil, comme cela se produit lorsque la chaîne de recherche est une chaîne vide). Je prends également une précaution supplémentaire de définir'post__in'
un tableau avec un ID de publication impossible afin de m'assurer que rien ne soit retourné .Vous pouvez également envisager de définir la chaîne de recherche sur
null
et de définirpage_id
afin de diriger l'utilisateur vers une page avec votre message d'erreur personnalisé.Choix des encodages
J'ai écrit un test de couverture comparant certaines chaînes factices dans différents alphabets à tous les encodages par défaut pris en charge par PHP . Ce n'est parfait par aucun tronçon (je n'ai aucune idée du réalisme de mes chaînes factices, et cela semble étouffer la détection japonaise), mais c'est quelque peu utile pour déterminer les candidats. Vous pouvez le voir en action ici .
Après avoir recherché des encodages de caractères potentiels signalés par ce test, il semble que ce
Windows-1252
soit le choix parfait pour vos besoins, couvrant l'alphabet latin ainsi que les accents des langues latines courantes.Une sélection des
ISO-8859
jeux de caractères devrait être un autre choix viable, mais pour des raisons que je ne peux pas comprendre, lesmb_
fonctions ne semblent pas faire la différence entreISO-8859
les différents jeux de caractères de, bien qu'ils les répertorient comme des encodages séparés.Pour autoriser d'autres caractères communs, vous pouvez également envisager d'ajouter
HTML-ENTITIES
.la source
ISO-8859
encodages .Comme j'ai essayé de l'expliquer à @MichaelRogers lorsqu'il a posté une question similaire il y a plusieurs jours, connaître le jeu de caractères (ou script) utilisé dans une chaîne n'est PAS suffisant pour détecter la langue de cette chaîne.
Ainsi, alors que la méthode détaillée par @bosco va supprimer russe, etc cordes (avec les 2 corrections ci - dessous), il pas limiter vos recherches à l' anglais.
Pour voir cela, essayez:
[ note: les 2 corrections mentionnées ci-dessus à ce que @bosco a fournies sont:
/u
modificateur (requis pour traiter le motif et le sujet comme encodés en UTF-8, voir PHP: Modificateurs de motifs regex ]qui produira:
[ note: je parle anglais, français et un peu d'allemand (et un peu de Lorem ipsum :-), mais je me suis appuyé sur Google Translate pour l'arabe, le russe et le chinois]
Comme vous pouvez le voir, s'appuyer sur la vérification du script latin NE garantira PAS que vous avez l'anglais.
Il existe un certain nombre de threads sur StackOverflow (par exemple, Détecter le langage de la chaîne en PHP ) qui fournissent plus d'informations sur le sujet.
la source