WOLF
Un editor in stile foglio di calcolo per modificare in blocco, filtrare, esportare e ripristinare articoli, pagine e qualsiasi custom post type.
- Prima versione
- Installazioni attive
- 4000+
- Valutazione
- Leggi le recensioni
Chi sono
WOLF (in precedenza WPBE) è l'equivalente per gli articoli dell'editor di massa WooCommerce BEAR. Mostra gli articoli di qualsiasi tipo di contenuto registrato in una tabella modificabile, permette di filtrarli per campi principali, tassonomie e meta, e poi di modificare, eliminare o esportare l'intero insieme filtrato in una sola operazione.
La parte difficile è che nulla è fisso. Ogni tipo di contenuto porta le proprie tassonomie e chiavi meta, i valori meta possono essere array serializzati, elenchi di ID di immagini o flag con valori personalizzati, e l'insieme di destinazione può essere di migliaia di articoli su hosting condiviso con brevi limiti di tempo PHP.
Il plugin risponde con un registro dei campi ricostruito per tipo di contenuto, un filtro salvato sul server e compilato in un'unica WP_Query, esecuzioni di massa guidate dal browser in lotti di dimensione fissa, e un registro della cronologia che memorizza il valore precedente di ogni campo prima che venga scritto, così anche un'esecuzione di massa può essere ripristinata a lotti.
La versione premium e quella gratuita su wordpress.org condividono una sola base di codice; un singolo flag attiva i limiti della versione gratuita.
WOLF · editor di massa degli articoli
cosa è stato risolto
Un unico editor per qualsiasi tipo di contenuto
shipped · 2019Cosa offreIl personale modifica qualsiasi tipo di contenuto in una tabella che resta veloce su siti grandi, con colonne impostate per persona e per lingua.
- Problema
- Articoli, pagine e custom post type hanno tassonomie, chiavi meta e campi principali applicabili diversi. Una sola tabella deve mostrarli tutti e restare veloce su siti con molti record.
- Soluzione
Un registro dei campi viene ricostruito per il tipo di contenuto attivo e la tabella funziona in modalità server-side di DataTables su WP_Query, così ogni richiesta legge una pagina di articoli.
- Stack
Ogni tipo di contenuto porta il proprio insieme di tassonomieLe colonne di tassonomia sono costruite da get_object_taxonomies() per il tipo di contenuto attivo
WPBE_SETTINGS::get_fields() unisce l'elenco statico dei campi da data/fields.php con una colonna per ogni tassonomia registrata per il tipo di contenuto corrente, poi applica l'ordine e i titoli delle colonne salvati dall'utente. I nuovi campi che compaiono in seguito (una nuova tassonomia, una nuova chiave meta) vengono aggiunti in coda invece di andare persi.
Le definizioni dei campi portano allow_post_types e prohibit_post_types. wrap_field_val() restituisce una cella 'restricted' quando un campo non si applica, per esempio i campi di stato e commenti per gli allegati, il tipo MIME solo per gli allegati, sticky solo per gli articoli. Gli allegati vengono interrogati con lo stato aggiuntivo 'inherit'.
I siti grandi non possono caricare ogni articolo nel browserDataTables lato server: ogni pagina, ordinamento e ricerca è una WP_Query paginata
La tabella è configurata con serverSide: true e chiama wpbe_get_posts con i parametri di paginazione di DataTables. WPBE_POSTS::gets() converte start/length in paged/posts_per_page e passa all'ordinamento meta_value_num quando la colonna di ordinamento è un campo meta numerico o di data.
Le righe per pagina sono limitate a 100 con il commento nel codice 'to avoid 500 error on weak servers'. La versione gratuita le limita a 10.
Il codice dell'editor non deve rallentare il resto di wp-adminEstensioni e modelli vengono caricati solo nella pagina dell'editor e sulle azioni AJAX wpbe_*
init() esegue prima un controllo del ruolo e poi is_should_init(), che restituisce true solo per page=wpbe o per un'azione AJAX il cui nome contiene 'wpbe_'. Sulle altre schermate di amministrazione vengono registrati solo la voce di menu, il pulsante della barra di amministrazione e gli avvisi.
Le estensioni seguono una convenzione di denominazione (ext/<slug>/<slug>.php, classe WPBE_<SLUG>) e ricevono storage, impostazioni e il modello dei post tramite init_vars(). Lo stesso loader carica anche le estensioni di terze parti da wp-content/wpbe_ext.
Ogni utente ha bisogno di colonne proprie, per tipo di contenuto se necessarioOpzioni memorizzate per ID utente, facoltativamente divise per tipo di contenuto (impostazione premium)
Le impostazioni risiedono nell'opzione wpbe_options_<user_id>. Quando l'interruttore 'separate settings' è attivo, il tipo di contenuto viene aggiunto alla chiave, e l'elenco dei campi meta registrati viene diviso per tipo di contenuto allo stesso modo. Il tipo di contenuto attivo è ricordato per utente nello storage del plugin.
L'interruttore è disattivato nella versione gratuita.
Sui siti WPML l'editor deve funzionare nella lingua corrente dell'amministrazioneLingua WPML corrente passata a ogni query; elenco degli articoli in evidenza (sticky) mantenuto per lingua
Quando SitePress è presente, il filtro wpbe_current_language restituisce ICL_LANGUAGE_CODE, gets() chiama $sitepress->switch_lang() prima di costruire WP_Query, e l'opzione degli articoli in evidenza viene letta e scritta sotto sticky_posts_<lang>.
Modifica, eliminazione ed esportazione di massa a lotti
shipped · 2019Cosa offreLe modifiche a migliaia di articoli si concludono in modo affidabile su hosting ordinari, con avanzamento visibile e la possibilità di fermarsi a metà.
- Problema
- Modificare migliaia di articoli in una sola richiesta PHP incontra limiti di tempo e memoria, e l'utente ha bisogno di vedere l'avanzamento e di poter fermare l'esecuzione.
- Soluzione
Il browser guida l'esecuzione in lotti di dimensione fissa di ID di articoli; l'operazione stessa è memorizzata una sola volta sul server sotto una chiave di massa casuale.
- Stack
Una richiesta PHP non può modificare migliaia di articoliID risolti una volta, poi inviati in lotti da 50 a un endpoint worker senza stato
wpbe_bulk_posts_count memorizza il modulo di massa sotto 'wpbe_bulk_<key>' (16 caratteri casuali generati nel browser) e restituisce gli ID corrispondenti al filtro corrente, usando fields=ids e no_found_rows. Il browser divide quell'elenco in lotti da 50 e li invia uno dopo l'altro a wpbe_bulk_posts, aggiornando una barra di avanzamento e un indicatore nella barra di amministrazione. Annulla interrompe l'XHR in sospeso; wpbe_bulk_finish restituisce il totale contato.
L'eliminazione di massa usa lo stesso schema con lotti da 10 e wp_trash_post(), così gli articoli eliminati restano recuperabili dal cestino.
Dopo un'esecuzione il browser ridisegna solo le righe toccate quando sono stati modificati quattro articoli o meno, e ridisegna la pagina corrente negli altri casi.
I campi di testo richiedono modifiche relative al valore correnteAccoda, anteponi, sostituisci (con o senza distinzione delle maiuscole), imposta nuovo; macro per articolo
__process_text_data() legge il valore corrente di ogni articolo e applica il comportamento scelto. I valori possono contenere {TITLE}, {ID}, {MENU_ORDER} e {meta:key}, risolti per articolo, e macro di maiuscole/minuscole come {DO_STRING_UP} o {DO_STRING_TITLE} che usano le funzioni mb_*, così i titoli non latini sono gestiti.
I meta numerici richiedono modifiche relative e arrotondamento in stile prezzoPer valore o percentuale, formula con un'altra chiave meta, intervallo casuale, arrotondamento a .05, .10 o .x9
__process_number_data() supporta aumento/diminuzione per valore o percentuale, poi combina facoltativamente il risultato con un altro campo meta dello stesso articolo (+, -, *, /, con la divisione per zero sostituita da 1) e con un numero casuale da un intervallo scalato da un fattore decimale.
L'arrotondamento della frazione a passi di .05 o .10, o a una terminazione come .99, avviene in update_page_field() nel numero di decimali configurato; i centesimi sono convertiti tramite un passo intero perché il modulo in virgola mobile dà risultati sbagliati.
Le tassonomie gerarchiche e quelle piatte richiedono un input di termini diversoID dei termini per le tassonomie gerarchiche, slug dei termini uno per uno per quelle piatte
WordPress si aspetta ID per le tassonomie gerarchiche e nomi o slug per quelle simili ai tag. Il worker di massa controlla is_taxonomy_hierarchical(); per le tassonomie piatte converte ogni ID in uno slug, e per 'replace' scrive il primo termine con append=false e gli altri con append=true. 'Remove' usa wp_remove_object_terms().
L'hook della cronologia viene attivato manualmente prima delle modifiche ai termini, perché questo percorso aggira update_page_field().
Le esportazioni di selezioni grandi incontrano gli stessi limitiCSV aggiunto per lotto da 10 tramite fputcsv; XML scritto nel formato WXR di WordPress
Il passo di conteggio scrive la riga di intestazione; ogni lotto aggiunge righe con fputcsv() su un file aperto in modalità a+. Il codice osserva che WP_Filesystem non ha un'aggiunta riga per riga, ed è per questo che qui si usano le funzioni di file grezze.
L'esportazione XML costruisce un documento RSS con i namespace WXR 1.2 (wp:, content:, excerpt:), i termini come <category domain nicename> e i meta come wp:postmeta con CDATA, così il file segue il formato dell'esportatore di WordPress. I nomi dei file portano la data e il minuto dell'esportazione, e i file più vecchi di due giorni vengono eliminati da un controllo limitato da un transient.
Filtro per campi, termini e meta
shipped · 2019Cosa offreIl personale seleziona esattamente gli articoli che vuole per campi, categorie, valori personalizzati o elenchi di ID incollati, e modifiche ed esportazioni si applicano a quella stessa selezione.
- Problema
- La modifica di massa e l'esportazione si applicano a ciò che il filtro trova, quindi il filtro deve trasformare molte condizioni sui campi in un'unica WP_Query corretta e restare identico tra richieste AJAX separate e schede del browser.
- Soluzione
Lo stato del filtro viene salvato sul server sotto una chiave casuale per scheda e compilato in clausole tax_query, meta_query e posts_where in un unico hook usato da ogni query.
- Stack
Le richieste di tabella, modifica di massa ed esportazione devono vedere lo stesso filtroFiltro salvato lato server sotto una chiave di 16 caratteri generata per scheda del browser
Il browser genera wpbe_filter_current_key quando un filtro viene applicato e la invia a ogni richiesta; il commento nel sorgente dice che questo consente la modifica di massa per filtro in schede diverse. wpbe_apply_query_filter_data() legge il filtro memorizzato ed è applicata dentro WPBE_POSTS::gets(), così l'elenco di ID per la modifica di massa è costruito dallo stesso codice della tabella visibile.
Per corrispondere a tutti i termini di un insieme serve una clausola tax_query per termineAND diviso in una clausola tax_query per termine; aggiunti EXISTS e NOT EXISTS
Per l'operatore AND ogni termine selezionato diventa una propria clausola unita dalla relazione esterna AND, che è il workaround citato nel commento del codice. Gli altri operatori (IN, NOT IN) passano l'elenco dei termini così com'è. include_children è controllato da un filtro invece che dal valore predefinito di WordPress.
Gli intervalli di meta numerici richiedono un cast DECIMAL con scala esplicitaBETWEEN con cast DECIMAL(30,20); estremi unilaterali e uguali gestiti
Il commento nel codice indica il caso: con DECIMAL senza precisione, una ricerca da 100 a 150 restituiva anche 99.xx. Il filtro usa DECIMAL(30,20), passa a >= quando è impostato solo 'from' e a = quando i due estremi sono uguali. I meta di tipo data passano prima da normalize_calendar_date().
Un valore meta vuoto può essere '' o una riga mancante'Empty' compila in value = '' OR NOT EXISTS; 'not empty' in value != ''
Gli articoli creati prima che una chiave meta venisse introdotta non hanno alcuna riga, quindi un semplice controllo di uguaglianza li perde. Il comportamento 'empty' emette un meta_query annidato con relation OR.
La ricerca testuale richiede OR, AND e NOT senza SQL grezzoPiccola sintassi (^ per OR, ~ per AND, ! per NOT) compilata in REGEXP preparato
posts_txt_where() converte l'input in minuscolo, lo divide su ^ e costruisce condizioni LOWER(column) REGEXP / NOT REGEXP con le modalità begin, end, exact e not. Ogni valore è associato tramite $wpdb->prepare() e la colonna deve trovarsi in una lista consentita di cinque colonne di wp_posts.
Gli utenti incollano elenchi di ID e intervalliInput come '12,40-55' espanso in post__in
Gli elementi separati da virgole sono presi come ID; un elemento con un trattino viene espanso nell'intero intervallo indipendentemente dall'ordine. Gli intervalli di date e numeri sulle colonne di wp_posts (menu_order, post_parent, date degli articoli) passano da un filtro posts_where separato con una lista consentita di colonne.
Cronologia e ripristino
shipped · 2019Cosa offreUna modifica di massa sbagliata può essere annullata in un solo passo invece di correggere a mano migliaia di articoli.
- Problema
- Una modifica di massa sbagliata su migliaia di articoli è difficile da annullare: le revisioni di WordPress non coprono i meta, i termini né la maggior parte dei campi principali, e il ripristino stesso può essere grande quanto la modifica.
- Soluzione
Ogni scrittura di campo è preceduta da una riga di registro con il valore precedente; le righe di una stessa esecuzione di massa condividono la sua chiave e vengono ripristinate a lotti.
- Stack
Catturare il vecchio valore di qualsiasi tipo di campo prima che cambiUn hook prima di ogni scrittura memorizza il valore precedente in wp_wpbe_history
write() è collegata a wpbe_before_update_page_field, che update_page_field() attiva prima di ogni scrittura; il percorso di massa delle tassonomie, che scrive direttamente i termini, la attiva a mano. I valori di tassonomia sono memorizzati come elenco JSON di ID di termini, i meta array come JSON (con JSON_HEX_QUOT e JSON_HEX_TAG per l'editor dei meta serializzati), gli scalari così come sono. Ogni riga ha user_id e post_type, e la chiave di massa quando fa parte di un'esecuzione.
Migliaia di modifiche devono formare un'unica operazione annullabileTabella di testata wpbe_history_bulk per esecuzione: chiavi, numero di articoli e stato
start_bulk() inserisce la riga di testata con l'elenco dei campi modificati come JSON; ogni lotto aggiunge la propria dimensione tramite UPDATE posts_count = posts_count + %d; finish_bulk() segna l'esecuzione come completed. Un'esecuzione annullata dall'utente mantiene lo stato predefinito 'terminated', così l'elenco la mostra come parziale. Entrambe le tabelle sono create con dbDelta e il charset del sito, indicizzate su bulk_key e user_id, ed eliminate alla disinstallazione.
Il ripristino di una grande esecuzione incontra gli stessi limiti di tempoRipristino a porzioni di 10 righe per richiesta; riga di testata rimossa alla fine
Il browser chiede il numero di righe della chiave di massa, poi chiama ripetutamente wpbe_history_revert_bulk_portion con limite 10 e una barra di avanzamento. Ogni riga ripristinata viene eliminata, così la porzione successiva riprende da quelle rimanenti; la riga di testata viene eliminata quando il contatore raggiunge il totale.
Un ripristino non deve registrarsi come nuova modificaremove_all_actions() sull'hook di registrazione prima di scrivere i vecchi valori
revert() scollega lo scrittore della cronologia, decodifica il valore memorizzato in base al tipo di campo (elenchi di ID di termini, array meta JSON) e lo riscrive attraverso lo stesso update_page_field() usato per le modifiche, così save_post ed edit_post scattano per un ripristino come per una modifica.
Modifiche singole ed esecuzioni di massa devono comparire in un'unica linea temporaleRighe singole e testate di massa unite e ordinate per tempo, per utente e tipo di contenuto
get_history() legge le righe singole e le testate di massa dell'utente e del tipo di contenuto correnti, le unisce e le ordina per tempo, le più recenti per prime, così un solo elenco mostra entrambi i tipi di modifica.
La versione gratuita mostra le due voci più recenti ed elimina le righe singole e le testate di massa più vecchie quando l'elenco viene aperto.
Campi meta e contenuti strutturati
shipped · 2019Cosa offreDati personalizzati come elenchi, flag e gallerie di immagini possono essere modificati in sicurezza senza romperli, anche quando il personale non sa come sono memorizzati.
- Problema
- I custom post type conservano la maggior parte dei dati in postmeta, spesso come array serializzati, elenchi di ID di immagini o flag con valori specifici del sito, che una semplice cella di testo corromperebbe.
- Soluzione
Le chiavi meta sono registrate con un tipo e una vista di modifica, e ogni vista ha il proprio lettore, scrittore, filtro e gestore di massa.
- Stack
Gli amministratori non sanno quali chiavi meta usa un tipo di contenutoChiavi lette da un articolo campione; le chiavi registrate diventano colonne, filtri, campi di massa
wpbe_meta_get_keys restituisce le chiavi meta di un ID di articolo inserito dall'amministratore. Una chiave registrata viene iniettata tramite gli hook wpbe_extend_fields, wpbe_filter_* e wpbe_bulk_*, così compare insieme nella tabella, nel pannello dei filtri e nel pannello di massa. Le chiavi sono ripulite dagli spazi ma non convertite in minuscolo, perché chiavi come _woocs_sale_price_USD distinguono maiuscole e minuscole.
La versione gratuita usa solo i primi due campi meta registrati.
Gli array serializzati vanno modificati senza rompere la strutturaIl costruttore in popup invia array chiave/valore; il server ricostruisce gli array annidati
Il popup invia keys[]/values[] per gli array piatti e annidati e keys2[][]/values2[][] per gli elenchi di oggetti. __process_jsoned_meta_data() ricostruisce l'array PHP, decodifica i valori che sono JSON validi e ripiega sul valore grezzo per le stringhe semplici. update_post_meta() lo memorizza poi serializzato come WordPress si aspetta. Lo stesso percorso è usato dal worker di massa.
I flag sono memorizzati come 'yes'/'no' o altre coppie specifiche del sitoRegole di mappatura 'key:on^off' traducono tra l'interruttore 1/0 e i valori memorizzati
over_switcher_swicher_to_val() e over_switcher_val_to_swicher() leggono una stringa di impostazioni come 'dist:yes,stest:true' e convertono in entrambe le direzioni, così l'interfaccia a interruttore funziona con i valori scritti da altri plugin.
Gallerie di immagini conservate nei meta come elenchi di ID di allegatiTipo di meta galleria salvato come elenco di ID di allegati separati da virgole
Il popup della galleria invia un modulo con codifica URL; il gestore rileva la codifica, lo analizza con parse_str(), lo sanitizza e memorizza gli ID come stringa separata da virgole. Il worker di massa accetta lo stesso formato.
Il contenuto dell'editor a blocchi non può essere modificato in una semplice textareaArticolo aperto nell'editor a blocchi dentro un iframe; contenuto letto tramite wp.data
Opzione 'Use gutenberg'. Per i tipi di contenuto che usano l'editor a blocchi, il popup carica post.php con wpbe_popup_editor=1; wp_editor_compatibility() nasconde i controlli di pubblicazione e della barra laterale in quel frame ed espone una funzione che restituisce wp.data.select('core/editor').getEditedPostContent(). La pagina genitore lo legge e salva attraverso il normale aggiornamento del campo.
Controllo degli accessi e protezione delle richieste
shipped · 2023Cosa offreSolo i ruoli di fiducia possono usare l'editor, gli autori lavorano solo con i propri articoli e il personale vede solo i campi che può modificare.
- Problema
- Uno strumento che può riscrivere in blocco qualsiasi campo di qualsiasi articolo è un bersaglio di alto valore: ogni endpoint AJAX deve verificare chi chiama, e l'input dei filtri finisce vicino all'SQL.
- Soluzione
Un unico controllo di ruolo prima che venga registrato qualsiasi endpoint, nonce sulle azioni di campo, massa, strumenti e impostazioni, diritti a livello di campo per i ruoli non amministratori e SQL preparato con liste consentite di colonne.
- Stack
Solo i ruoli di fiducia possono raggiungere qualsiasi endpoint dell'editorIl controllo del ruolo in init() viene eseguito prima che venga aggiunto qualsiasi gestore wp_ajax_wpbe_*
can_manage_data() consente amministratori, editor e i ruoli aggiunti tramite il filtro wpbe_author_area_roles. Se fallisce, init() ritorna prima che le estensioni vengano caricate, così le azioni AJAX non esistono per quell'utente. Gli aggiornamenti dei campi, la modifica e l'eliminazione di massa, il pannello degli strumenti (crea, duplica, elimina, termini), le impostazioni dei meta, il modulo delle opzioni, l'elenco della cronologia e i singoli ripristini controllano anche un nonce.
Gli editor non dovrebbero vedere né modificare ogni campo e tipo di contenutoL'amministratore imposta la visibilità dei campi e i tipi di contenuto consentiti per i ruoli non amministratori (premium)
Per i ruoli non amministratori get_fields() scarta le colonne nascoste, così non vengono offerte nella tabella né nel pannello di massa; update_page_field() controlla is_current_user_can_edit_field() e restituisce 'forbidden' per un campo nascosto; filter_post_types() restringe il selettore dei tipi di contenuto, e il costruttore delle impostazioni sposta l'utente su un tipo di contenuto consentito. Nella versione gratuita le caselle di visibilità sono rese disattivate.
Gli autori devono lavorare solo con i propri articoliI ruoli dell'area autore ricevono author=self nelle query dell'editor e non possono cambiare post_author
Per i ruoli aggiunti tramite il filtro wpbe_author_area_roles, WPBE_AUTHOR_AREA aggiunge 'author' => ID dell'utente corrente tramite il filtro di query usato dalla tabella, dall'elenco di ID di massa e dall'esportazione, così queste liste mostrano solo gli articoli dell'utente. La sua callback wpbe_user_can_edit blocca post_author per questi ruoli.
L'input dei filtri e i dati copiati degli articoli finiscono in SQLNomi di colonna da liste consentite, ogni valore associato tramite $wpdb->prepare()
I filtri di testo e di intervallo accettano solo colonne di wp_posts elencate e associano i valori tramite prepare(). Le query della cronologia associano utente, tipo di contenuto e chiave di massa, e costruiscono elenchi NOT IN da segnaposto di array_fill().
La duplicazione copia i termini per slug e tutto il postmeta tranne _wp_old_slug in una sola istruzione INSERT ... SELECT %d, %s, %s UNION ALL, con ogni riga costruita con prepare(), poi imposta la copia come bozza.
I campi di contenuto devono mantenere gli embed ma eliminare gli scriptwp_kses con la lista consentita dei post più un elenco ristretto di attributi iframe
wpbe_update_page_field() sanitizza gli array in modo ricorsivo con wp_kses e la lista consentita dei post. Per contenuto, riassunto e campi di testo ricco aggiunge iframe con un insieme fisso di attributi, così gli embed video sopravvivono. Un filtro può passare a sanitize_text_field() per i siti più rigorosi.
Numeri
wordpress.org- Installazioni attive 4000+ contatore di wordpress.org.
- Recensioni 27 Media 4.7 su 5.
- Anni di supporto 7 Dal 3 settembre 2019, ultimo aggiornamento 12 ottobre 2026.