MDTF
Ricerca a faccette per i post di WordPress e i post type personalizzati, per campi meta e tassonomie allo stesso tempo.
- Prima versione
- Installazioni attive
- 1000+
- Valutazione
- Leggi le recensioni
Chi sono
MDTF filtra qualsiasi post type per campi meta e tassonomie insieme. È stato creato per cataloghi che non sono negozi: immobili, concessionari di auto, directory. Il proprietario del sito definisce i campi del filtro in un costruttore integrato (checkbox, menu a discesa, slider di intervallo, menu a discesa di intervallo, calendario, campo di testo, etichetta), li compila per ogni post e inserisce i moduli di ricerca come widget o shortcode.
La parte difficile è che WordPress salva i meta come stringhe senza tipo in wp_postmeta. Ogni condizione di intervallo, data e testo deve essere trasformata in una meta_query che confronti correttamente, ogni opzione visibile ha bisogno di un conteggio in tempo reale sotto la ricerca corrente, e AND/OR tra i gruppi non deve mai indebolire le condizioni che nascondono i post.
Il plugin è mantenuto dal 2014, attraverso PHP 7.x e 8.x, i cambiamenti di archiviazione di WooCommerce 3.0, l'editor a blocchi dei widget e una lunga serie di segnalazioni di sicurezza gestite tramite Patchstack e Wordfence. I rami premium e gratuito condividono la stessa base di codice.
MDTF · filtro dei meta dati
cosa è stato risolto
Stato della ricerca e link
shipped · 2014Cosa offreI link dei risultati di ricerca restano brevi e possono essere salvati nei preferiti o condivisi. Ripetere la stessa ricerca riutilizza un solo link invece di accumulare copie salvate.
- Problema
- Una ricerca su molti campi meta e tassonomie è una grande struttura annidata. Trasportata nei parametri GET produce link molto lunghi ed espone la forma della query, e ogni query della pagina (risultati, contatori, paginazione, ordinamento, conteggio ajax) deve leggere lo stesso stato.
- Soluzione
Lo stato del modulo è codificato come JSON, salvato sul server in un transient o in una sessione PHP, e il link porta solo una breve chiave. Un unico accessor lo decodifica e lo valida per tutte le query della richiesta.
- Stack
Lo stato della ricerca è troppo grande per viaggiare nell'URLSalvare JSON in base64 sul server, mettere nel link solo una breve chiave page_mdf
encode_search_get_params() riceve il modulo serializzato via ajax, lo analizza e lo sanifica, rimuove i valori '~' (qualsiasi) e salva il resto come JSON in base64 con set_page_mdf_session(). A seconda dell'impostazione keep_search_data_in i dati vanno in un transient per un giorno o in $_SESSION. La risposta è mdf_cat=...&page_mdf=<key>, che il front end trasforma nel link dei risultati.
La stessa ricerca creava ogni volta una nuova copia salvataLa chiave è l'md5 del JSON normalizzato: chiavi associative ordinate, scalari ripuliti dagli spazi, liste in ordine
get_search_data_key() calcola l'hash dell'output di normalize_search_data(), che percorre l'array ricorsivamente, ordina le chiavi associative e mantiene l'ordine delle liste. L'ordine dei campi dal browser non conta più, quindi una ricerca corrisponde a un transient e a un link. I link con chiavi più vecchie continuano a funzionare finché vive il loro transient.
Un endpoint pubblico salva ogni ricerca per un giornoRifiutare input non stringa o sovradimensionato (filtrabile, 65536 byte) prima di salvare qualsiasi cosa
mdf_encode_search_get_params è registrato per i visitatori non autenticati, e ogni ricerca distinta scrive un transient che vive un giorno. Il gestore verifica che vars sia una stringa entro mdf_search_data_max_length e altrimenti risponde mdf_cat=-1 senza salvare. Una chiave fornita viene accettata solo se corrisponde a /^[0-9a-f]{32}$/, altrimenti la chiave è ricavata dai dati.
Lo stato salvato non è attendibile quando viene rilettoDecodificare in un array o in niente; forzare a numeri gli estremi from/to degli intervalli
get_page_mdf_data() tratta come nessuna ricerca tutto ciò che non si decodifica in un array. Unisce le opzioni predefinite del widget e, per ogni campo medafi_, converte 'from' e 'to' in numeri, così i valori di intervallo e calendario raggiungono meta_query come numeri qualunque cosa abbia inviato il visitatore. Il risultato decodificato è mantenuto in una variabile statica per il resto della richiesta.
Le ricerche fisse hanno bisogno di link permanenti che non scadano maiUna chiave numerica si risolve nel post meta page_mdf_string invece che in un transient
I link costanti sono un post type nascosto separato. Il suo save_post() salva la ricerca codificata in page_mdf_string. get_page_mdf_session() controlla la chiave: numerica significa un ID di post e legge il meta salvato, qualsiasi altra cosa va all'archivio dei transient o delle sessioni. Risultati, contatori e template non hanno bisogno di sapere quale tipo di link sia stato usato.
Costruzione della meta query
shipped · 2014Cosa offreI visitatori possono cercare per prezzo, anno, chilometraggio, date o parole, inclusi intervalli aperti come 'e oltre', e i filtri possono riutilizzare dati già inseriti nei post.
- Problema
- I valori meta sono stringhe in wp_postmeta. Prezzi, anni, chilometraggio, intervalli di date e testo libero devono diventare clausole meta_query che confrontano come numeri o date, supportano intervalli aperti e permettono comunque a MySQL di eseguirle.
- Soluzione
Ogni tipo di elemento del filtro ha la propria traduzione in meta_query o in un frammento posts_where, con confronti DECIMAL per slider e menu a discesa di intervallo, limiti superiori aperti e modelli di intervallo a due chiavi salvati per post.
- Stack
Lo slider al massimo deve significare 'e oltre', non 'fino al massimo'Sostituire l'estremo superiore con 2147483647 quando il cursore è al massimo configurato
In get_meta_query_array() il caso dello slider confronta il 'to' selezionato con il massimo dello slider stesso; se sono uguali, il limite superiore diventa MetaDataFilterCore::$max_int, così i post con valori oltre la scala configurata corrispondono ancora. I menu a discesa di intervallo usano la stessa idea con un suffisso 'i' (infinito) come '1001-i'. Gli slider singoli e i menu a discesa di intervallo usano BETWEEN con tipo DECIMAL.
L'elemento ha un intervallo di valori, il visitatore cerca un solo numeroSlider a doppio valore: key <= v AND key_to >= v su due campi meta
Per gli slider con slider_range_value = 1 un post salva due valori, la chiave del campo e key_to (per esempio un intervallo di prezzo o di dimensione). Il visitatore sceglie un valore, e la query richiede che cada dentro l'intervallo proprio del post, con entrambi i lati di tipo DECIMAL.
Intervalli di date in cui uno dei due estremi del calendario può essere vuotoQuattro rami sulle chiavi _from/_to: inizio aperto, fine aperta, giorno singolo, BETWEEN
L'elemento calendario salva <key>_from e <key>_to. Solo 'to' impostato dà _to <= to; solo 'from' dà _from >= from; valori uguali corrispondono agli elementi il cui intervallo copre quel giorno; un intervallo vero e proprio diventa BETWEEN su _from. Un commento nel codice data l'ultimo ramo al 08-10-2014.
Campo di testo che cerca in titolo o contenuto parola per parolaposts_where aggiunge LIKE per parola tramite $wpdb->prepare ed esc_like, uniti da un filtro
Un elemento di testo può puntare al proprio valore meta o a post_title, post_content, o a entrambi con OR o AND. Per le colonne del post la condizione viene passata ai filtri MDTF_HELPER su posts_where, che dividono la frase in parole (commutabile con mdf_txtsearch_some_words_behavior) e le uniscono con mdf_txtsearch_some_words_condition, AND per impostazione predefinita. Gli spazi ripetuti vengono prima ridotti a uno.
I campi del filtro devono riutilizzare meta già esistenti sul sitoGli elementi riflessi associano una chiave del filtro a una chiave meta esistente al momento della query
Un campo marcato is_reflected porta reflected_key. Il costruttore delle query, lo splitter OR e la API pubblica get_field() usano tutti la chiave riflessa, così un filtro può lavorare su meta scritti dal tema o da un altro plugin senza copiare i valori nelle chiavi medafi_.
Logica AND/OR tra i gruppi di filtri
nel prodottoCosa offreI visitatori possono scegliere se i risultati devono corrispondere a una qualsiasi o a tutte le opzioni selezionate. Gli elementi nascosti, esauriti o non pertinenti restano comunque fuori dai risultati.
- Problema
- I visitatori possono volere un OR tra le opzioni selezionate, ma un semplice OR al livello superiore di meta_query mette in OR anche le condizioni di servizio: categoria del filtro, post nascosti, visibilità e disponibilità di WooCommerce. I post nascosti e estranei finiscono allora nei risultati. La modalità scelta deve inoltre raggiungere ogni query di una ricerca.
- Soluzione
Le condizioni sono divise in condizioni del visitatore che possono essere messe in OR e condizioni obbligatorie. La query finale è AND al livello superiore con un solo gruppo OR annidato, per meta e per tassonomie. La modalità viaggia dentro lo stato di ricerca salvato.
- Stack
Un semplice OR metterebbe in OR anche le condizioni che nascondono i postwrap_meta_query(): AND in cima, gruppo OR del visitatore annidato, condizioni di servizio obbligatorie
wrap_meta_query() costruisce una relazione AND e annida le condizioni ORabili come un solo gruppo con relazione OR, solo quando sono due o più. mdf_hide_post NOT EXISTS, meta_data_filter_cat, _visibility e _stock_status vanno al livello superiore e si applicano sempre. Lo stesso wrapper è usato dalla query dei risultati e dai contatori.
Sotto OR hanno senso solo le condizioni checkbox e etichettasplit_meta_query_array() tipizza ogni clausola in base al suo elemento di filtro; gli slider restano obbligatori
Lo splitter associa ogni chiave di ricerca (propria o riflessa) al tipo del suo elemento dalle sezioni del filtro nella ricerca. Le clausole degli elementi checkbox e etichetta diventano ORabili; slider, menu a discesa, campi di testo, calendari e menu a discesa di intervallo restano obbligatori. In modalità AND l'array viene restituito invariato, così le ricerche AND esistenti producono lo stesso SQL di prima.
L'OR sulle tassonomie non deve eliminare la visibilità e le tassonomie aggiuntivesplit_tax_query_array() separa i termini del visitatore da quelli aggiunti dal filtro per identità
Dopo che i filtri di terze parti (mdf_filter_taxonomies, tassonomie aggiuntive, product_visibility) hanno modificato la tax_query, lo splitter confronta ogni clausola con l'elenco costruito dal modulo usando array_search rigoroso. Le corrispondenze sono condizioni del visitatore, il resto è obbligatorio. Le clausole del visitatore ripetute che il filtro ha raccolto per richiesta vengono scartate. wrap_tax_query() annida poi sotto OR solo la parte del visitatore.
La modalità AND/OR deve raggiungere conteggio, paginazione e ordinamentoSalvare la modalità nelle opzioni del widget page_mdf, usare la richiesta solo come ripiego
encode_search_get_params() scrive meta_data_filter_bool e mdf_tax_bool in mdf_widget_options della ricerca salvata, prendendo la scelta del visitatore quando il widget le consente entrambe. get_meta_data_filter_bool() e get_mdf_tax_bool() leggono prima il valore salvato e normalizzano ad 'AND' tutto ciò che non è 'OR'. Risultati, contatori, conteggio ajax, paginazione e ordinamento leggono lo stesso stato.
Abilitare l'OR sulle tassonomie non deve cambiare i risultati dei widget già presenti nei siti in produzioneApplicare l'OR sulle tassonomie solo ai widget salvati con un flag di versione; i più vecchi restano AND
I widget salvati dalle versioni precedenti hanno sempre cercato nelle tassonomie con AND, qualunque cosa dicesse la loro opzione OR. Applicare l'opzione a loro cambierebbe i risultati nei siti in produzione senza alcuna azione del proprietario. get_widget_tax_bool() rispetta l'opzione solo quando taxonomies_options_behaviour_ver è impostato, il che avviene quando il widget viene salvato dalla nuova versione.
Un genitore selezionato e il suo figlio selezionato: il genitore corrisponderebbe a tutto ciò che sta sotto di luiScartare un termine selezionato quando è selezionato anche uno dei suoi figli
tax_query include i figli per impostazione predefinita, perciò un genitore selezionato corrisponderebbe a ogni post sotto di lui e renderebbe priva di senso la selezione del figlio. get_tax_query_array() rimuove un termine selezionato se get_term_children() di quel termine ha intersezione con l'insieme dei selezionati, poi reindicizza l'elenco.
Contatori dinamici e cache
shipped · 2014Cosa offreOgni opzione mostra quanti elementi restituirebbe, così i visitatori evitano risultati vuoti. I conteggi sono in cache, quindi il sito resta veloce.
- Problema
- Ogni checkbox, opzione di menu a discesa e termine mostra quanti post restituirebbe con la ricerca corrente. Significa una query per ogni elemento visibile, con join su wp_postmeta, a ogni visualizzazione di pagina e a ogni conteggio ajax.
- Soluzione
Le query di conteggio recuperano solo gli ID e saltano found-rows e il precaricamento della cache. I conteggi possono essere messi in cache in una tabella chiave/valore con chiave l'hash della query, e gli alberi dei termini nei transient con una durata definita.
- Stack
Un conteggio deve mostrare la ricerca più questa singola opzionePer elemento: aggiungere la sua clausola, sostituire il valore dello stesso select tra le opzioni sorelle, rieseguire
get_item_posts_count() parte dalla ricerca corrente. Un checkbox aggiunge key = 1 se non è già presente. Un'opzione di menu a discesa rimuove prima la clausola della stessa chiave, perché le opzioni sorelle si escludono a vicenda, poi aggiunge sé stessa (come BETWEEN per le opzioni di intervallo). Per i termini, get_tax_count() inietta il termine in una copia dello stato delle tassonomie con la cache delle tassonomie per richiesta disattivata e la ripristina dopo.
Le query di conteggio pagavano per dati che non usavano maifields=ids, nopaging, nessun precaricamento della cache di meta/termini, set_found_posts() sovrascritto
Le query dei contatori chiedono solo gli ID con update_post_meta_cache, update_post_term_cache e cache_results disattivati. WP_QueryMDFCounterIn estende WP_Query e sovrascrive set_found_posts() perché non faccia nulla, così WordPress non esegue il passaggio extra di found-rows; post_count è la risposta.
Gli stessi conteggi ricalcolati a ogni visualizzazione di paginaMettere in cache i conteggi in {prefix}mdf_query_cache con chiave md5 degli argomenti della query
WP_QueryMDFCounter calcola l'hash dell'intero array di argomenti e lo cerca in una tabella a due colonne con un indice su mkey; in caso di mancato riscontro esegue la query e inserisce il conteggio. La pagina delle impostazioni crea la tabella e disattiva l'opzione mostrando l'istruzione CREATE se l'utente del database non ha il privilegio. Un amministratore svuota la cache dalla pagina delle impostazioni, che esegue un TRUNCATE dietro manage_options e un nonce.
Gli elenchi gerarchici di termini costano una query per livelloUna sola chiamata get_categories() per tassonomia, albero costruito in PHP, in cache come transient
get_terms() carica una volta tutti i termini della tassonomia e assemble_terms_childs() costruisce gli elenchi dei figli da quell'array. Con cache_terms_data attivo, il risultato è salvato sotto mdf_terms_cache_<md5 degli argomenti> come transient la cui durata proviene dall'impostazione del periodo della cache dei termini (da un'ora a 7 giorni; nessuna scadenza se non è impostato alcun periodo).
Il filtro non dovrebbe caricarsi nelle pagine che non hanno una ricercaAllow-list di URL opzionale: saltare l'inizializzazione del front end quando il percorso non è elencato
is_should_init() viene eseguita prima che il plugin registri i suoi post type e hook. Se init_on_pages_only è impostato, normalizza l'URL corrente (query string e /page/N rimossi) e termina subito quando l'URL non è nell'elenco. Le richieste di amministrazione si inizializzano sempre.
Modello dei dati e integrazione con WordPress
shipped · 2014Cosa offreI risultati compaiono nel design esistente del sito, e il personale può rinominare o riorganizzare i campi del filtro senza perdere i dati già salvati nei post.
- Problema
- I campi del filtro sono definiti dal proprietario del sito, i loro valori stanno nei post meta di post type arbitrari, e i risultati devono comparire nei template propri del tema senza modificare il tema.
- Soluzione
Le definizioni dei campi stanno in un post type nascosto. I valori dei post sono salvati due volte, come un unico array per la modifica e come chiavi meta separate per l'interrogazione. La query principale viene sostituita da pre_get_posts con una protezione contro la rientranza.
- Stack
I valori meta devono essere modificabili come insieme e interrogabili uno per unoSalvare l'insieme come un unico array e ogni campo medafi_ come una propria chiave meta
save_post() scrive page_meta_data_filter come un unico array, che la schermata di modifica rilegge, e poi scrive ogni campo medafi_ con update_post_meta(), utilizzabile da meta_query. Le sezioni del filtro e i loro elementi sono salvati come meta html_items del post type nascosto meta_data_filter.
Cambiare la categoria del filtro di un post non deve lasciare valori obsoletiAl cambio di categoria eliminare tutti i meta medafi_ del post prima di salvare quelli nuovi
I campi della vecchia categoria del filtro resterebbero altrimenti in wp_postmeta e corrisponderebbero alle ricerche di quella categoria. save_post() confronta la categoria inviata con quella salvata e rimuove tutte le righe medafi_% del post quando è cambiata.
Rinominare la chiave di un campo non deve lasciare dati orfani nei postVerificare l'unicità in tutte le sezioni del filtro, poi rinominare in postmeta con un solo UPDATE
change_meta_key() richiede il prefisso medafi_, rifiuta una chiave già usata in questa o in qualsiasi altra sezione del filtro e indica la sezione in conflitto. Poi rinomina la chiave dentro html_items, riscrive gli array page_meta_data_filter dei post interessati ed esegue UPDATE postmeta SET meta_key. Richiede un nonce, edit_post e edit_others_posts perché tocca tutti i post.
I risultati devono essere renderizzati nel template di ricerca proprio del temapre_get_posts esegue la query dei risultati e sostituisce il $wp_query globale, con una protezione contro i cicli
parse_query() marca la query principale come ricerca del post type richiesto. pre_get_posts() renderizza [meta_data_filter_results] senza un template; quella vista dichiara global $wp_query e assegna un nuovo WP_Query costruito dalla ricerca. Un flag di richiesta impedisce la rientranza, perché la nuova query fa scattare di nuovo pre_get_posts. Il filtro mdtf_prohibited_post_types tiene fuori le query interne di ACF e Contact Form 7.
WooCommerce 3.0 ha spostato i prodotti nascosti da meta a una tassonomiaSelettore di versione: product_visibility NOT IN per la 3.0+, _visibility meta prima
Risultati, contatori degli elementi e contatori dei termini si ramificano tutti su WOOCOMMERCE_VERSION: dalla 3.0 aggiungono una tax_query che esclude exclude-from-catalog, le versioni precedenti ricevono una clausola meta _visibility IN (catalog, visible). Una clausola opzionale _stock_status nasconde i prodotti esauriti. Con WPML attivo, ogni query riceve anche la lingua corrente.
Le opzioni dei menu a discesa più vecchie non hanno chiave, mentre i post salvano i loro titoli come valorifill_select_keys() usa in lettura il titolo dell'opzione come chiave, in corrispondenza ai valori salvati nei post
Le opzioni dei menu a discesa salvate dalle versioni precedenti del costruttore hanno una chiave vuota, mentre il meta box del post salva il titolo dell'opzione come valore. Invece di una migrazione, fill_select_keys() gira dentro get_html_items() e al salvataggio, riempiendo le chiavi vuote con il titolo senza spazi ai margini e lasciando intatte le chiavi esplicite, inclusa '0'. I valori esistenti dei post corrispondono senza dover salvare di nuovo i post.
Hardening di sicurezza
nel prodottoCosa offreLa ricerca pubblica non può essere usata per scrivere dati indesiderati né per raggiungere azioni di amministrazione, il che protegge il sito e i suoi contenuti.
- Problema
- Il plugin espone endpoint ajax pubblici, renderizza template per nome dalle opzioni e scrive post meta da moduli.
- Soluzione
Firme lato server per i dati rimandati indietro dal browser, whitelist per i percorsi dei template e le chiavi meta, e controlli di capability e nonce sulle azioni di amministrazione.
- Stack
Un widget dentro un blocco deve essere ridisegnato dal conteggio ajax a partire da opzioni portate dalla paginaFirmare classe e opzioni del widget con wp_hash; accettare solo due classi di widget note
Un Legacy Widget dentro un blocco non ha una sidebar in cui il conteggio possa trovarlo per ID, perciò il suo modulo porta la classe del widget e le opzioni. get_widget_redraw_data() le firma con wp_hash(); get_widget_from_redraw_data() verifica con hash_equals() e accetta solo MetaDataFilter_Search e MetaDataFilter_TaxSearch prima di chiamare the_widget().
Il percorso del template dei risultati proviene dalle opzioni di shortcode e widgetRidurre ogni segmento del percorso a [A-Za-z0-9_-]; sottocartelle consentite, '..' impossibile
sanitize_template_path() normalizza gli slash, filtra ogni segmento a un set di caratteri sicuro e scarta quelli vuoti, così un valore non può uscire dalla cartella dei template mentre sottocartelle come any/my_posts continuano a funzionare.
Il modulo di modifica del post non deve scrivere chiavi meta diverse dai campi del filtroAccettare solo chiavi medafi_ e richiedere edit_post prima di salvare i valori
save_post() rimuove dall'array inviato ogni chiave senza il prefisso medafi_ prima di salvarlo e ricontrolla il prefisso prima di ogni chiamata a update_post_meta(), così il modulo non può impostare _edit_lock, _price o chiavi simili. Salvare i valori richiede current_user_can('edit_post').
Le azioni ajax di amministrazione non devono essere richiamabili da qualsiasi visitatoreCapability più nonce su svuotamento della cache, rinomina delle chiavi e modifica dei widget
Lo svuotamento della cache richiede manage_options e mdtf_ajax_nonce. La rinomina delle chiavi richiede un proprio nonce, edit_post e edit_others_posts. Le azioni sui campi dei widget richiedono edit_theme_options. I visitatori non autenticati raggiungono solo le azioni di ricerca del front end (figli dei termini, codifica della ricerca, conteggio, pannello di ricerca, contenuto del pulsante di ricerca). Gli altri gestori registrati per loro controllano da sé l'accesso: le azioni di sottoscrizione del messenger richiedono login e un nonce, l'helper delle statistiche richiede manage_options.
Numeri
wordpress.org- Installazioni attive 1000+ contatore di wordpress.org.
- Recensioni 28 Media 4.5 su 5.
- Anni di supporto 12 Dal 22 aprile 2014, ultimo aggiornamento 13 ottobre 2026.