1

Sincronizzazione Gestionale Aziendale con WooCommerce

Introduzione

I titolari o gestori di un negozio fisico possono avere in progetto di avviare anche un e-Commerce per la vendita dei prodotti presenti nello store fisico. Uno degli elementi più complessi nella realizzazione di un e-Commerce è il caricamento dei prodotti e il relativo aggiornamento di quantità, prezzi e varianti. In questo articolo vedremo come automatizzare il processo di sincronizzazione del magazzino fisico con l’e-Commerce attraverso il plugin WpAll Import.

Sincronizzazione Magazzino con e-Commerce: Creiamo il Connettore

Il processo di sincronizzazione avviene tramite l’utilizzo di un file CSV/Excel che rappresenta il magazzino del nostro store, è possibile ottenere questo file estraendolo dal vostro gestionale aziendale. All’interno di questo file, oltre ai campi base come taglia, quantità, prezzo e varianti, è fondamentale avere un ID, ovvero un codice identificativo di ogni singolo prodotto. L’ID può essere o un numero oppure si può generare dinamicamente unendo più informazioni di prodotto, come ad esempio: codice articolo + taglia + colore = ID.

L’ID è molto importante sia per la prima importazione sia per i successivi aggiornamenti, in quanto l’aggiornamento utilizzerà come chiave univoca proprio l’ID per aggiornare, ad esempio, la quantità di ogni singola variante prodotto.

Quindi dobbiamo effettuare un’esportazione del magazzino in formato CSV o XLS/XLSX e al suo interno avere, almeno, i seguenti campi:

  • ID prodotto;
  • taglia;
  • colore;
  • quantità;
  • categoria merceologica (ci servirà per creare le categorie in WooCommerce).

WpAll Import: Set-up Plugin per la sincronizzazione

Come primo passaggio da compiere, effettuiamo il download e l’installazione di WpAll Import (link al download)  e dell’add-on per WooCommerce (link al download).

Effettuiamo l’installazione dei due plugin.

Nel menu laterale di WordPress clicchiamo sulla voce “All Import” e successivamente su “New import” e scegliamo la modalità di importazione “Upload a file”, quindi stiamo dicendo a WpAll Import che gli passiamo i dati tramite un file.

Effettuiamo l’upload del nostro file CSV, se vuoi fare una prova ti lascio il link al mio CSV di demo => import_magazzino_demo 

Selezioniamo dal menu a tendina “create new” la voce “WooCommerce Products”, in modo tale da comunicare al plugin che la tipologia di dato da caricare è “prodotti” e poi facciamo click su “Continue to Step 2”.

A questo punto ci appare una schermata di riepilogo, controlliamo che non ci siano anomalie e procediamo con lo step 3.

Allo step 3 vediamo la pagina di configurazione, si tratta di una fase molto importante e delicata, quindi procediamo con attenzione. Per comodità ti ho preparato  un template, che puoi direttamente caricare => Download template TXT se non riesci a scaricarti il file ma il tuo browser ti mostra il contenuto, puoi selezionare tutto il contenuto e aggiungerlo all’interno di un file con estensione .txt.

Per importare il template, devi aprire su una nuova scheda, la sezione “setting” del plugin (che trovi nel menu laterale di WordPress passando il mouse sulla voce “All Import”. Nella schermata che si apre, fai click sul pulsante “Import templates”. Salva tutto e torna allo step 3.

A questo punto, scorrendo tutto in basso, selezioniamo il template e procediamo allo step 4. Analizziamo tutti i campi di tutte le sezioni, in particolare il box relativo all’add-on di WooCommerce, ricordiamoci di modificare la URL delle immagini, in quanto indichiamo al plugin di caricare le foto dei nostri prodotti tramite URL (ovviamente le foto dovranno essere presenti e leggibili in quel percorso).

Procediamo con l’importazione e avviamo la sincronizzazione. In base alla quantità dei prodotti e al peso delle immagini, il processo può richiedere fino a qualche ora.

Se abbiamo seguito tutti i passaggi, verranno creati i prodotti variabili per il nostro WooCommerce. Se hai riscontrato problemi durante l’importazione, o se hai necessità di una configurazione del plugin differente, scrivimi e cercherò di supportarti.

Conclusioni

Questo articolo vuole essere una guida introduttiva per automatizzare la sincronizzazione del magazzino fisico con un e-commerce. Il vantaggio di lavorare con un file CSV/XLS oppure XML ci permette di avere una fonte standardizzata dei dati, in modo tale da poter utilizzare il processo con qualsiasi gestionale aziendale, anche il più datato o non comune. Lavorando con WpAll Import, ci rendiamo conto, man mano delle grandi potenzialità che il software ha. Possiamo integrare WooCommerce con qualunque tipologia di gestionale, è possibile avere add-on per i campi personalizzati, (custom field) per la gestione dei brand, per YOAST e molto altro. Se avete un minimo di conoscenze in programmazione, avrete a vostra disposizione un prodotto di altamente professionale.

Se hai dubbi, curiosità o vuoi ulteriori dettagli, scrivimi e approfondiamo. Trovi i miei riferimenti in basso. Grazie.




Rimuoviamo Alcuni Termini da Titolo e Contenuto

Introduzione

In questo articolo vediamo come creare un plugin per la rimozione di alcuni termini dal title e dal contenuto dei nostri post. Questa soluzione può tornare molto utile. ad esempio, su siti web con migliaia di contenuti che devono fare re-branding e hanno aggiunto il loro brand nel titolo o è presente nei contenuti oppure nei casi in cui ci sono delle policy che vietano l’utilizzo di un termine. Per seguire correttamente questo articolo è necessario avere buone basi relativamente ai filtri di WordPress e le relative funzioni, per questo facciamo una breve introduzione al concetto prima di creare il nostro plugin.

I Filtri di WordPress (filter hooks)

I filtri appartengono al secondo tipo di hook in WordPress, sono simili agli hook di azione per alcune caratteristiche. I filtri, a differenza degli action hook ci permettono ci danno la possibilità di manipolare come vogliamo gli output di codice.Vediamo come funziona apply_filters() in WordPress per comprendere la logica che sta dietro ai filtri.

<?php
apply_filters( string $tag, mixed $value );

la funzione accetta 2 o più parametri.

  • $tag: nome univoco per il filter hook
  • $value: il valore che viene passato a qualsiasi filtro aggiunto all’hook per la manipolazione
  • $args: come la funzione do_action() per gli hook di azione, la funzione accetta un numero qualsiasi di argomenti aggiuntivi da passare.

I filtri sono una comune funzione PHP che può essere chiamata quando necessario ma è diversa da una funzione in quanto deve essere registrata per un determinato filter hook.

Gli hook filter danno la possibilità agli sviluppatori di plugin di creare funzioni personalizzate che filtrano alcune tipologie di dati seguendo prestabilite indicazioni. quando la funzione apply_filters() viene chiamata ogni filtro agganciato ad essa viene eseguito seguendo l’ordine dato dalla priorità.

Per registrare un filtro dobbiamo utilizzare la funzione add_filter()

<?php
add_filter(
        string $tag,
        callable $function_to_add,
        int $priority = 10,
        int $accepted_args = 1
);

Ci sono molte funzioni per gli hook filter, come ad esempio:

remove_filter | remove_all_filters | apply_filters_ref_array | has_filter | current_filter. Per creare il nostro plugin ci soffermiamo su current_filter, la funzione che ci restituisce il nome del filter hook che è in esecuzione. È una funzione particolarmente utile se utilizziamo una singola funzione filtro o più filter hook. Ipotizziamo di avere la necessità, ad esempio su un sito web con molti articoli, di rimuovere uno o più termini dal page title e dal contenuto; questo può succedere in casi di re-branding oppure per motivazioni legali. In questo caso possiamo utilizzare una sola funzione current_filter() e determiniamo quale hook è in esecuzione (titolo o contenuto). Iniziamo a scrivere un pò di codice!

<?php
/**
 * Plugin Name: Elimina Stringa - Developress
 * Plugin URI:  http://www.developress.it
 * Description: Elimina i termini indesiderati dal page title e dal contenuto.
 * Author:      Developress
 * Author URI:  http://www.developress.it
 */

add_filter( 'the_title',   'developress_rimuovo_termini' );
add_filter( 'the_content', 'developress_rimuovo_termini' );

function developress_rimuovo_termini( $text ) {

	$termini = [];

	if ( 'the_title' === current_filter() ) {
		$termini = [
			'termine_1',
			'termine_2'
		];
	} elseif ( 'the_content' === current_filter() ) {
		$termini = [
			'termine_3',
			'termine_4'
		];
	}

// Ogni termine individuato viene sotituito con uno spazio utilizzando la funzione str_replace di PHP

	if ( $termini ) {
		$text = str_replace( $termini, ' ', $text );
	}

	return $text;
}

Il codice sopra può essere aggiunto direttamente in un file PHP e successivamente compresso. Il file .zip che ottieni, lo puoi caricare direttamente come un comune plugin. Come puoi vedere il plugin ha molto potenziale, può essere utilizzato anche a seguito di un attacco hacker oppure se vogliamo fare un “cerca e sostituisci” per gli usi più disparati. Da tenere in considerazione che se abbiamo bisogno di questa funzionalità, una sola volta, è possibile procedere anche da SQL intervenendo direttamente nel database.




Funzioni degli Action Hook

Introduzione

Quando costruiamo un plugin, spesso utilizziamo soltanto le funzioni add_action() e do_action() per lavorare con gli hook. Ci sono molte altre funzioni utili messe a disposizione da WordPress. Vediamo le principali.

remove_action()

Questa funzione ci permette di rimuovere una action che è stata precedentemente agganciato ad un hook; a volte può essere utile rimuovere una action aggiunta da WordPress oppure da altri plugin/temi. La funzione ci restituisce true se l’action è stata correttamente rimossa e false se l’action non è stata registrata o non può essere rimossa.

<?php
remove_action( string $tag, callable $function_to_remove, int $priority = 10);
?>

La funzione accetta 3 parametri:

  1. $tag: il nome dell’hook che vogliamo rimuovere
  2. $function_to_remove: il nome dell’azione richiamabile da rimuovere dall’action hook
  3. $priority: la priorità dell’action da rimuovere

remove_all_action()

Questa funzione è meno utilizzata, solitamente si utilizza per fare dei test oppure per creare un plugin di debugging e permette di rimuovere tutte le action per un determinato hook oppure tutte le action che hanno una determina priorità in un hook.

<?php
remove_all_action( string $tag, int | bool $priority = false );

Il parametro $tag dovrà essere il nome dell’action hook dal quale rimuovere tutte le action. Impostando la priorità ad un determinato numero, verranno rimosse soltanto le action con questa priorità. Se non impostiamo la priorità, verranno rimosse tutte le relative action, a prescindere dalla priorità.

Se abbiamo necessità di eliminare tutte le action dall’hook wp_head perché, ad esempio, stiamo riscontrando conflitti con i CSS/JS o metatag, o in generale dobbiamo eliminare qualunque codice che viene aggiunto nella sezione <head>, possiamo farlo in questo modo:

<?php
remove_all_action('wp_head');

con la funzione sopra stiamo eliminando tutte le action dall’hook che hanno priorità 1.

do_action_ref_array()

La funzione do_action_ref_array() è molto simile a do_action(), entrambe creano un hook ma la differenza sta nel numero di parametri che possiamo passare, infatti con do_action_ref_array() possiamo passare un array di argomenti.

<?php
do_action_ref_array( string $tag, array $arg );

has_action()

Si tratta di un condizionale che ci restituisce true se l’action viene trovata oppure false se non sono state trovate action. Il controllo funzionerà soltanto se l’action è stat precedentemente aggiunta.

<?php
has_action( string $tag, callable|bool $function_to_check = false );

anche per questa funzione, come abbiamo visto per le altre, il primo parametro è il nome dell’hook che vogliamo cercare. Il secondo parametro è opzionale e di default impostato su false.  Se vogliamo controllare una funzione specifica o metodo agganciato all’hook, possiamo aggiungere il parametro “callable”. Facciamo un esempio:

<?php
if ( has_action('wp_footer' ) ) {
       echo '<p>Ci sono action registrate nel footer</p>';
} else {
echo '<p>Non ci sono action registrate nel footer</p>';
}

Possiamo anche fare un altro esempio per controllare se una specifica action è agganciata ad un hook. Vediamo come fare per controllare se l’action wp_print_footer_scripts è agganciata a wp_footer:

<?php
$priority = has:action( 'wp_footer', 'wp_print_footer_scripts' );

if ( false !== $priority ) {
       printf(
                 'wp_print_footer_scripts ha una priorita di %d',
                 absint ( $priority ) 
                );

}

did_action()

did_action() è una funzione condizionale come has_action(), che determina se un hook di azione è stato già eseguito.

<?php
did_action ( string $tag );

la funzione accetta un solo parametro $tag e restituisce un intero che corrisponde al numero di volte che l’hook di azione è stato avviato. Una delle possibili applicazioni è all’interno di un if PHP:

<?php
did_action( 'plugin_loaded' ) ) {
        // Faccio qualcosa, imposto una variabile ad esempio
}

plugin_loaded è un hook che viene eseguito una volta caricato un singolo plug-in attivato.

Conclusioni

Le funzioni analizzate in questo articolo non sono tutte quelle disponibili ma l’obiettivo è stato quello di fornire una breve guida con gli elementi principali e spiegare la logica di programmazione degli hook e come gestirli. Se sei interessato puoi leggere gli articoli correlati oppure sfogliare la sezione plugin o temi.




Action Hooks: Costruiamo un Plugin

Introduzione

All’interno di WordPress una caratteristica primaria delle Plugin API sono gli hook. Gli hook permettono di “agganciarsi” all’interno del flusso operativo dei codici all’interno del CMS e ne alterano il funzionamento senza apportare modifiche al core di WordPress, quindi anche aggiornando ad una nuova versione del CMS, non verrà persa nessun modifica.

I plugin non potrebbero funzionare senza hook in quanto non avrebbero altro modo per modificare le funzioni di WordPress. In WordPress abbiamo due tipologie di hook: action hook e filter hook, vediamoli.

Action Hook

Questa tipologia di hook permette di eseguire codice in uno specifico momento durante il processo di caricamento del flusso di codici del CMS. Agganciando una funzione ad un action hook, comunichiamoa WordPress che vogliamo “fare qualcosa” in quel preciso evento. La funzione:

do_action()

crea e lancia un hook di azione. Quando agganciamo un action all’hook, non chiamiamo la funzione direttamente. Vediamo un esempio:

do_action( $tag, $args = '' );

questa funzione accetta due parametri:

  1. $tag: il nome o l’identificativo  per l’action hook;
  2. $args: il valore o i valori (separati da virgola) che passiamo per registrare le actions.

Esempio di funzione con parametri multipli:

do_action ( $tag, $arg_1, $arg_2, $arg_3 );

Un hook d’azione molto diffuso in WordPress è wp_head usato in particolare per aggiungere metadati SEO e l’Open Graph per i tag social.

Una Action è una funzione PHP o una classe che viene registrata all’interno di un hook di azione. Senza azioni aggiunte, l’hook non farà nulla, allora iniziamo a fargli fare qualcosa!

Creiamo un piccolo plugin

Quando costruiamo un plugin dobbiamo creare delle action personalizzate che eseguono task specifici, aggiungendole ad action hook. WordPress ci fornisce una add_action() helper function.

<?php
add_action( 
      string $tag,
      callable $function_to_add,
      int $priority = 10,
      int $accepted_args = 1
);

la funzione sopra, accetta fino a 4 parametri:

  1. $tag: il nome dell’action hook ed è il primo parametro per do_action();
  2. $function_to_add: una funzione che viene eseguita quando l’action viene avviato;
  3. $priority: stabilisce l’ordine secondo cui l’action viene eseguito, di default il valore è 10 e accetta anche valori negativi. Poniamo l’ipotesi che altri plugin installati (o temi o stesso WordPress) nel nostro CMS potrebbero avere priorità più o meno del nostro, quindi prima di impostarla è bene avere una panoramica completa di cosa accade nel nostro WordPress;
  4. $accepted_args: il numero di parametri da passare alla funzione di callback.

Dopo questa introduzione doverosa, iniziamo a costruire il nostro piccolo plugin che mostrerà un messaggio di base.

<?php
/** Plugin Name: Footer Message Developress
* Plugin URI: https://www.developress.it/footer-message-developress
* Description: Mostriamo un messaggio nel footer dell sito web
* Author: Developress
* Author URI: https://www.developress.it
*/

add_action( 'wp_footer', developress_footer_message', PHP_INT_MAX );

function developress_footer_message() {
      esc_html_e('Benvenuto su Developress, segui il blog e resta sempre ifnormato sul CMS WordPress', 'developress')
}

Cosa abbiamo fatto? Alla funzione add_action() abbiamo passato 3 parametri:

  1. wp_footer che è l’action hook che comunica a WordPress a quale hook agganciarsi;
  2. developress_footer_message è il nome della funzione da eseguire  quando l’hook viene avviato;
  3. PHP_INT_MAX è la priorità dell’action che abbiamo impostato al numero intero più grande possibile.

Si tratta di una semplice applicazione degli hook di azione ma serve comprendere il loro funzionamento, una volta che abbiamo chiara la logica è molto più semplice e naturale creare nuove applicazioni molto più complesse di questa.




Plugin Random Posts: Costruiamolo Insieme

Introduzione

In questo articolo vedremo come realizzare un semplice plugin che ri-ordina i post del nostro blog in modo random invece dell’ordinamento per data. Se non hai esperienza ti consiglio di leggerti prima questo articolo “Funzioni degli Action Hook” per avere una panoramica completa di quali sono le funzioni principali legate agli hook da utilizzare durante la scrittura di un plugin. Iniziamo!

Creazione Plugin: Random Posts

L’obiettivo è quello di realizzare una funzionalità per cui tutti gli articoli della home page del nostro blog dovranno essere mostrati in ordine random e non per data. Per fare questo dobbiamo registrare una action personalizzata sull’hook pre_get_posts e impostare il riordinamento.

<?php
/**
 * Plugin Name: Random Posts Developress
 * Plugin URI:  http://developress.it/
 * Description: Ordina gli articoli della home page del blog, su base Random
 * Author:      Developress
 * Author URI:  http://developress.it/
 */

add_action( 'pre_get_posts', 'developress_random_posts' );

function developress_random_posts( $query ) {

	if ( $query->is_main_query() && $query->is_home() ) {
		$query->set( 'orderby', 'rand' );
	}
}

Per utilizzare il plugin dovrai semplicemente aggiungere il codice sopra all’interno di un file .php e successivamente comprimerlo. Ad esempio developress_random_posts.zip e questo file lo puoi caricare direttamente in WordPress dalla sezione “Plugin”.




Sviluppo Plugin: Gettiamo le Basi

In questo articolo vedremo quali sono le basi solide che un plugin deve avere, parleremo delle regole per assegnare nomi alle funzioni, dell’organizzazione dei file all’interno della directory di un plugin e della determinazione dei path. Iniziamo!

Requisiti per i plugin

Il sistema di plugin di WordPress è molto flessibile e permette di avere plugin composti da un solo file o una directory con una serie di file. Vediamo quali sono i consigli e le best practices di base.

Definizione del nome del plugin

Una scelta non banale è la definizione del nostro plugin, in quanto dovrà essere unico e una delle best practices è l’utilizzo del nome della nostra attività in abbinamento con la funzionalità principale che il plugin offre. Ad esempio se sto programmando un plugin per la gestione della cache, un valido nome potrebbe essere: Developress Cache System“.

Utilizzo di una cartella

Anche se il sistema plugin di WordPress permette la creazione di plugin formati da un solo file o, in genere, plugin senza directory e sempre buona regola lavorare con le cartelle e utilizzare, ad esempio, una cartella per i CSS, una per JS e altre per tipologia (o ruolo). Anche in questo caso è buona regola utilizzare come nome della cartella, un nome unico, sintetico e in minuscolo che non dovrà contenere spazi, trattini, lettere maiuscole e contenere, in generale, caratteri alfanumerici. Inoltre il nome della directory deve coincidere con il text domain in particolare quando il plugin è destinato per essere tradotto e per essere caricato nel repository ufficiale. Quindi riprendendo l’esempio precedente, un nome della directory corretto è “Developress Cache System”.

Best practices

Come per la programmazione di qualsiasi software o script, i programmatori devono seguire un insieme di regole per avere codice organizzato, pulito e facilmente comprensibile anche da parte di altri programmatori. Vediamo alcune best practices.

Nome delle funzioni

Per evitare conflitti tra funzioni e quindi errori all’interno di WordPress durante lo sviluppo del nostro plugin è necessario assegnare nomi unici alle funzioni. Ad esempio se nominiamo una funzione get_post() questa andrà in conflitto con WordPress in quanto già esiste e si crea un fatal error. Quindi scrivere codice di qualità significa anche non creare conflitti con quanto creato da altri programmatori; il metodo migliore per evitare conflitti è quello di utilizzare un prefisso (esempio develop_) o togliere gli spazi tra i nomi utilizzando la funzione namespace. Quindi una funzione tipo

get_post()

diventerà

develop_get_post()

Per evitare conflitti con altre funzioni è possibile utilizzare la funzione namespace di PHP che ci permette di creare nomi unici per le nuove funzioni, eliminando gli spazi tra le parole, in modo tale da evitare conflitti con i codici scritti da altri programmatori. Quindi nel nostro esempio: Developress Cache System diventerà DevelopressCacheSystem.

namespace DevelopressCacheSystem;

  class Setup {
        public function boot() {}
}

Questi non sono i soli casi in cui dobbiamo fare queste considerazioni ma è necessario prevenire conflitti con i nomi delle funzioni anche per l’aggiunta delle opzioni nel database e il caricamento dei file JavaScript. In questi ultimi casi è importante utilizzare il prefisso: developress_cache_system_option_name e il prefisso per gli script: developress-cache-system-script-name.

Organizzazione dei file in un plugin

In fase di sviluppo di un plugin è di primaria importanza riflettere su come organizzare i file al suo interno  ed avere da subito una struttura solida, in modo tale da aggiungere agevolmente nuove funzionalità. Il file principale e l’unico richiesto per ogni plugin è file PHP primario. Questo file può essere chiamato in qualunque modo e deve risiedere nella directory del plugin. Ad esempio se il file primario è plugin.php dovrà essere collocato qui: developress-cache-system/plugin.php. Alcuni programmatori preferiscono chiamare il file PHP primario con il nome del plugin developress-cache-system.php, si tratta di una scelta e non ci sono regole scritte per scegliere l’uno o l’altro, importante è sempre avere chiaro lo schema dei nomi.

Se abbiamo intenzione di sviluppare un plugin più elaborato che richiede  molti file, ad esempio JavaScript, è buona pratica mantenere il file primario PHP nella root principale del plugin e gli altri file in sottocartelle (ad eccezione del file unistall.php).

Plugin Header

Affinchè WordPress riconosca un plugin, il file PHP primario del plugin, deve avere alcune righe di codice PHP che costituiscono l’header all’inizio del file e che comunicano al CMS che si tratta di un plugin.

<?php
/**
 * Plugin Name: Developress Cache System
 * Plugin URI:  https://esempio.it
 * Description:  Attiva un sistema di cache su tutto il sito web.
* Version: 1.0.0
* Requires at least: 5.3
* Requires PHP: 5.6
* Author:      Developress
* Author URI:  htts://www.developress.it
* License: GPL v2 or later
* Text Domain: developr
 */

Determiniamo i PATHS (percorsi dei file)

Un programmatore non conosce l’URL alla quale un utente installa WordPress quindi è necessario non impostare un path di URL specifico. Ci sono due tipologie di path che possiamo prendere in considerazione quando costruiamo un plugin per WordPress. Il primo è Local Path e il secondo è URL paths che è necessario per il caricamento dei file JavaScript, CSS e altri. Dal momento che WordPress permette di spostare la directory wp-content (dove sono collocati i plugin) in qualsiasi altro posto (URL) nel server, è importante utilizzare le funzioni standard di WordPress per determinare il path corretto.

Local Paths

Local paths si riferiscono alle posizioni sul server. PHP fornisce metodi veloci per determinare un path per qualunque situazione.

<?php
     $path = plugin_dir_path ( $file );
?>

$file (stringa, required): nome del file nella directory attuale. Di seguito vediamo una funzione che restituisce la directory corrente del file:

<?php
echo plugin_dir_path(__FILE__);
?>

L’output dell’esempio sopra è un qualcosa di simile a:

/public_html/wp-content/plugins/developr

Qualunque file può essere passato in questa funzione. Se passiamo __FILE__ dal file PHP primario, avremo il path della root del plugin. Ipotizzando di dovere caricare il file:

/src/functions.php possiamo usare questo codice:

<?php
include plugin_dir_path( __FILE__ )  .  '/src/functions.php'
?>

Una pratica diffusa è di archiviare questo path come variabile o costante nel file primario del plugin per avere un accesso rapido alla root del plugin:

<?php
define ( 'DEVELOPR_DIR'), plugin_dir_path ( __FILE__ ) );
?>

Questo permette da la possibilità di fare riferimento a DEVELOPR in qualsiasi momento e in ogni posizione all’interno del plugin.

URL paths

I riferimenti alle URL paths non sono il metodo consigliato per determinare il percorso di un file. Uno dei casi più ricorrenti di utilizzo dei path URL è per determinare il percorso di un file JavaScript, CSS o di una immagine all’interno del nostro plugin. WordPress fornisce la funzione:

<?php
   $url = plugin_dir_url (  $file  );
?>

$file: è il nome del file nel path della directory corrente. Facciamo un esempio:

<?php
echo plugin_dir_url (  __FILE__ );
?>

Il codice sopra restituisce il seguente tipo di URL:

https://www.esempio.it/wp-content/plugin/developr

Se vogliamo determinare il path di un file JS presente qui: /public/js/esempio.js nel nostro plugin, possiamo utilizzare questo codice:

<?php
$url  =  plugin_dir_url ( __FILE__ ) . 'public/js/esempio.js';
?>

In molti casi può tornarci utile determinare le URL di alcune sezioni del nostro sito web, di una pagina o directory. Vediamo alcune funzioni di WordPress molto utili:

  • site_url(): è il path URL dove WordPress è stato installato
  • home_url(): è il path URL della home page del sito web
  • admin_url(): è il path URL del backend di WordPress
  • rest_url(): è il path URL delle REST API
  • includes_url(): è il path URL della cartella includes di WordPress
  • content_url(): è il path URL della cartella content di WordPress

Conclusioni

In questo articolo abbiamo visto come impostare le basi per lo sviluppo di un plugin, dalle tecniche per assegnare nomi alle funzioni fino all’organizzazione dei file all’interno della directory del plugin e, in conclusione, abbiamo visto la gestione dei PATHS. All’interno della categoria “Plugin” puoi leggere altre guide sullo sviluppo di plugin con codici completi e spiegati passo dopo passo, puoi anche utilizzare la funzione di ricerca interno al sito web per argomenti più specifici.




Vantaggi dei plugin

Prima di sviluppare un nuovo plugin è bene capire quali sono i vantaggi e se non possiamo fare ciò di cui abbiamo bisogno tramite il file functions.php o il theme customizer del tema.

Nessuna modifica al Core di WordPress

Uno dei principali vantaggi di avere un plugin è l’abilità di modificare i comportamenti di WordPress senza modificare nessun file del core (ovvero file che appartengono all’installazione del CMS). Quando si effettuano modifiche a file core e si aggiorna il CMS ad una versione, queste modifiche andranno perse in quanto i file verranno sovrascritti con i nuovi. Inoltre avere file di sistema modificati rendono il sito web instabile.

Non c’è bisogno di re-inventare la ruota

Prima di programmare un plugin è sempre buona prassi controllare se tale plugin è stato già rilasciato oppure se le funzionalità che dovrebbe avere sono già presenti in WordPress. Ad esempio non avrebbe senso creare da zero la funzionalità di invio email, in quanto WordPress ha già questa funzione nativamente nel core (funzioni build-in) e, quindi potrebbe essere utile partire da questa per la creazione del plugin e aggiungere funzionalità personalizzate.

Separazione Plugin dai Temi

Una domanda comune è “aggiungo una funzionalità in un plugin o nel tema”? vi invito a leggere questi due articoli per alcuni dettagli importanti in merito:

Plugin o Function.php?  e Theme Customizer e Opzioni dei Temi

Un tema, in linea generale, non dovrebbe contenere funzionalità date da un plugin. Dipende molto dalle esigenze richieste dal sito web ma teniamo sempre a mente che, quando cambieremo tema, tutte le funzionalità aggiunte nei codici, andranno perse mentre quelle create tramite plugin possono essere abilitate anche nel nuovo tema.

Importante:I plugin sono utili per estendere le funzionalità di WordPress mentre il functions.php è utile per funzionalità uniche del tema.

Facilità di aggiornamento

WordPress rende molto semplice l’aggiornamento di un plugin all’ultima versione rilasciata, è sufficiente un click. I plugin che non sono installati tramite la directory dei plugin di WordPress, possono essere aggiornati tramite la funzionalità “auto-update”. Questa funzionalità e tipicamente utilizzata dai plugin a pagamento. Avere anche i plugin, oltre ai temi, sempre aggiornati permette di mantenere il sito web sicuro da vulnerabilità e bug.

Semplicità di condivisione e sicurezza

I plugin sono semplici da condividere con altri programmatori e tramite la community in generale, inoltre è possibile avere uno stesso plugin in un ambiente di lavoro multi-site. Nel caso in cui ci troviamo ad installare un plugin con problemi tecnici (esempio errori nei codici), WordPress automaticamente disattiva il plugin, evitando errori server di tipo 500. Nel caso in cui, il plugin con errori, causa problemi al nostro sito web, è possibile rinominare la directory del plugin e questo verrà disattivato.

Non dimentichiamoci della community di WordPress intorno allo sviluppo di plugin, che condivide codici e conoscenza e rende disponibili plugin molto avanzati e ben strutturati.




Introduzione ai Plugin

Un plugin in WordPress è uno script PHP che stende o altera una funzionalità del core del CMS. Sono dei file installati nel CMS che aggiungono una caratteristica o un insieme di caratteristiche.

I plugin in WordPress possono essere di ogni tipo e con ogni livello di complessità, da un semplice plugin per la gestione dei font ad un sistema più elaborato come un e-commerce. Vediamo come i plugin interagiscono con WordPress.

Plugin: come interagiscono con WordPress

WordPress mette a disposizione differenti APIs per lo sviluppo di un plugin che aiutano ad interagire con il CMS in più modalità. Vediamo quali sono:

  • Plugin: provvedono una serie di hooks che abilitano plugin per accedere a parti specifiche del CMS. WordPress ha due differenti tipi di hooks: Action e Filtri. Gli action hook (hook di azione) permettono di effettuare trigger personalizzati in punti specifici del codice durante la loro esecuzione; ad esempio eseguire una funzione dopo che l’utente si è registrato. Mentre i filtri modificano il testo prima di essere aggiunto o subito dopo essere stato estratto dal database;
  • widget: permettono sia di creare sia di gestire i widget all’interno di un plugin. I widget servono per aggiungere una sidebar registrata all’interno del nostro tema. Le APis permettono di abilitare instance multiple dello stesso widget da utilizzare nelle sidebar;
  • shortcode: uno shortcode è un hook che chiama una funzione PHP tramite una sintassi del tipo [shortcode] da aggiungere ad un post o pagina;
  • HTTP: invia richieste HTTP da un plugin. Questo tipo di API recupera contenuti da URL esterni o per l’invio di contenuti a un URL;
  • REST API: permette ad un programmatore di interagire con WordPress da remoto inviando e ricevendo JSON (JavaScript Object Notation). Possiamo eseguire operazioni CRUD (creare, leggere, aggiornare ed eliminare) all’interno di WordPress;
  • Settings: possiamo inserire delle impostazioni o un’area con una serie di impostazioni per un plugin. La prima motivazione per utilizzare le setting API è la sicurezza, in quando non dobbiamo preoccuparci di attacchi CSRF o XSS;
  • Options: permettono di archiviare e recuperare le opzioni per un plugin. Le API danno la possibilità di creare nuove opzioni, aggiornare quelle già esistenti, eliminarle o recuperare nuove opzioni già definite;
  • dashboard widget: permette di creare un pannello di controllo dei widget. I widget automaticamente appaiono nel back-end di WordPress e contengono le configurazioni standard;
  • rewrite: permette di creare delle regole di riscrittura nel nostro plugin. Questa API ci permette di aggiungere parti di URL statiche (/esempio-pagina/), strutture di tag (%postname%) e link di feed (/feed/json/);
  • transients: permettono di creare opzioni temporanee nel nostro plugin, sono API simili alle Options ma tutte le opzioni ha una data di scadenza.
  • database: permettono di accedere al database di WordPress con azioni di tipo CRUD (create, update, delete e recupero dei record del database da utilizzare nel nostro plugin);
  • theme customization API: permettono di aggiungere opzioni personalizzate del sito web e del tema, direttamente nel WordPress Customizer.

Quelle sopra riportate non sono tutte le API disponibili nel core di WordPress, per vedere la lista completa possiamo visitare: https://make.wordpress.org/core/handbook/best-practices/core-apis/

Quando un plugin viene caricato?

Nell’immagine sotto vediamo un diagramma del processo standard di caricamento di una pagina in WordPress, l’ordine secondo cui vengono caricati file e funzioni.

wordpress URL called

WordPress mette inoltre a disposizione le funzioni pluggable che ci permettono di sovrascrivere funzioni core nel plugin. Ad esempio

wp_mail()

è una pluggable function e possiamo modificare questa funzione nel nostro plugin ed inviare email usando “Simple Mail Transfer Protocol (SMTP)” al post del metodo di default. Tutte le funzioni di questo tipo sono presenti nel file /wp-includes/pluggable.php.




Plugin per Eliminare i Commenti: Costruiamolo Insieme

Introduzione

Capita molto spesso che ci ritroviamo siti web con molti commenti di Spam da dover eliminare. L’eliminazione dei commenti è un’operazione semplice ma, con grandi quantità di commenti, richiede molto tempo. In questo articolo vediamo come creare un plugin che, automaticamente elimina i commenti in Bulk.

Costruiamo il Plugin

Il primo passo da fare è quello di creare un nuovo file PHP plugin-delete-comments.php per il nostro nuovo plugin. Dal momento che questo plugin ha delle opzioni personalizzate del database è bene riflettere da subito su cosa queste opzioni dovranno fare. Ad esempio possiamo voler eliminare i commenti di spam oppure eliminare i commenti da moderare più vecchi di alcuni giorni.

Il plugin ha bisogno di accedere a queste opzioni più volte quindi è una buona pratica se creiamo una funzione che ci restituisce un’Array con le opzioni:

function developress_delete_comments_options() {

	return get_option( 'developress_delete_comments', [
		'status' => 'spam',
		'days'   => 10
	] );
}

Il codice sopra, cerca un’opzione nel database chiamata developress_delete_comments che archivia tutte le opzioni del plugin in un’Array singolo e, inoltre, passa i valori di default, nel caso in cui non siano ancora stati aggiunti nel database. Le opzioni di default sono: “Spam” e “10 giorni”.

Ora registriamo le impostazioni in WordPress aggiungendo un action hook: admin_init 

add_action( 'admin_init', 'developress_delete_comments_init' );

function developress_delete_comments_init() {

	// Registra le impostazioni nella schermata in "Impostazioni -> discussione".
	register_setting(
		'discussion',
		'developress_delete_comments'
	);

	// Registra il campo dello stato del commento.
	add_settings_field(
		'developress_comment_status',
		'Eliminare i commenti con quale Status?',
		'developress_comment_status_field',
		'discussion',
		'default'
	);

	// Registra il campo dei giorni.
	add_settings_field(
		'developress_comment_days',
		'Eliminare i commenti più vecchi quanti giorni?)',
		'developress_comment_days_field',
		'discussion',
		'default'
	);

	// Pianifica l'evento cron se non pianificato.
	if ( ! wp_next_scheduled( 'developress_delete_comments_event' ) ) {
		wp_schedule_event( time(), 'daily', 'developress_delete_comments_event' );
	}
}

La prima azione che il codice fa è di registrare un’impostazione personalizzata developress_delete_comments all’interno della pagina “Discussione” in Impostazioni -> Discussione. La stringa “discussions” è un valore univoco che permette di comunicare al CMS che vogliamo aggiungere un’impostazione personalizzata nella pagina “Discussione”.

Successivamente andiamo a registrare una funzione per i 2 campi personalizzati, comunicando a WordPress che il nostro plugin avrà due funzioni di callback:

developress_comment_status_field()

e

developress_comment_days_field()

Queste due funzioni mostrano i campi HTML nella schermata “Discussione”. Il blocco di codice finale si occupa dei cron job, registrando un nuovo evento programmato. Quindi aggiungiamo un hook chiamato

developress_delete_comments_event

che si attiverà ogni giorno. Nei codici successivi andiamo a creare le funzioni di callback per le impostazioni di campi:

function developress_comment_status_field() {

	$options = developress_delete_comments_options();
	$status  = $options['status']; ?>

	<select name="developress_delete_comments[status]">
		<option value="spam" <?php selected( $status, 'spam' ); ?>>
			Spam
		</option>
		<option value="moderated" <?php selected( $status, 'moderated' ); ?>>
			Moderato
		</option>
	</select>

<?php }

function developress_comment_days_field() {

	$options = developress_delete_comments_options();
	$days    = absint( $options['days'] );

	printf(
		'<input type="number" name="developress_delete_comments[days]" value="%s">',
		esc_attr( $days )
	);
}

Vediamo il codice step by step. Questa funzione

developress_comment_status_field()

restituisce come output HTMl un <select> dal quale è possibile scegliere lo status dei commenti “spam” o “moderato”. Mentre la seguente funzione

developress_comment_days_field()

restituisce un campo numerico, da notare che abbiamo aggiunto la funzione

absint()

in relazione alla variabile $days per essere certi che il valore inserito sia un intero positivo. Vediamo l’output di tutti i codici scritti fin qui:

 

 

Ora abbiamo bisogno di aggiungere una action all’hook del cron job (creato prima) che si occuperà di gestire l’eliminazione dei commenti.

add_action( 'developress_delete_comments_event', 'developress_delete_comments_task' );

function developress_delete_comments_task() {
	global $wpdb;

	$options = developress_delete_comments_options();
	$status  = $options['status'];
	$days    = absint( $options['days'] );

	// Imposta il valore predefinito comment_approved su spam.
	$comment_approved = 'spam';

	// Se lo stato è moderato, WordPress lo memorizza come "0".
	if ( 'moderated' !== $status ) {
		$comment_approved = '0';
	}

	// Crea ed esegui la query per eliminare i commenti.
	$sql = "DELETE FROM $wpdb->comments
	        WHERE ( comment_approved = '$comment_approved' )
		AND DATEDIFF( now(), comment_date ) > %d";

	$wpdb->query( $wpdb->prepare( $sql, $days ) );
}

L’azione principale che compie il codice sopra è di effettuare una query al database per eliminare i commenti seguendo le impostazioni selezionate dall’utente. La query eliminerà i commenti basandosi sul campo comment_approved che è il campo nella tabella $wpdb->comments che archivia lo status dei commenti.

Conclusioni e Download

L’obiettivo di questo articolo è quello di fornire una panoramica delle impostazioni e best practices di base che un plugin deve avere. È molto interessante la funzionalità dei cron job di WordPress in quanto ha un’infinità di ambiti di applicazione e può essere utile per molti interventi anche a livelli avanzati.

Ti invito a scaricarti il codice completo (crea un file .zip del file plugin-delete-comments.php) e a provarlo sul tuo sito web in un ambiente di prova (caricandolo come un comune plugin), così da poter “toccare con mano” ciò che hai imparato in questo articolo. Grazie per la lettura!

<?php
/**
 * Plugin Name: Bulk Delete Comments Developress
 * Plugin URI:  https://www.developress.it
 * Description: Questo plugin ti consente di eliminare in massa i commenti
 * Author:      DEVELOPRESS
 * Author URI:  https://www.developress.it
 */

function developress_delete_comments_options() {

	return get_option( 'developress_delete_comments', [
		'status' => 'spam',
		'days'   => 10
	] );
}

add_action( 'admin_init', 'developress_delete_comments_init' );

function developress_delete_comments_init() {

	// Registra le impostazioni nella schermata della discussione.
	register_setting(
		'discussion',
		'developress_delete_comments'
	);

	// Registra il campo dello stato del commento.
	add_settings_field(
		'developress_comment_status',
		'Eliminare i commenti con quale Status?',
		'developress_comment_status_field',
		'discussion',
		'default'
	);

	// Registra il campo dei giorni.
	add_settings_field(
		'developress_comment_days',
		'Eliminare i commenti più vecchi quanti giorni?)',
		'developress_comment_days_field',
		'discussion',
		'default'
	);

	// Pianifica l'evento cron se non pianificato.
	if ( ! wp_next_scheduled( 'developress_delete_comments_event' ) ) {
		wp_schedule_event( time(), 'daily', 'developress_delete_comments_event' );
	}
}

function developress_comment_status_field() {

	$options = developress_delete_comments_options();
	$status  = $options['status']; ?>

	<select name="developress_delete_comments[status]">
		<option value="spam" <?php selected( $status, 'spam' ); ?>>
			Spam
		</option>
		<option value="moderated" <?php selected( $status, 'moderated' ); ?>>
			Moderato
		</option>
	</select>

<?php }

function developress_comment_days_field() {

	$options = developress_delete_comments_options();
	$days    = absint( $options['days'] );

	printf(
		'<input type="number" name="developress_delete_comments[days]" value="%s">',
		esc_attr( $days )
	);
}

add_action( 'developress_delete_comments_event', 'developress_delete_comments_task' );

function developress_delete_comments_task() {
	global $wpdb;

	$options = developress_delete_comments_options();
	$status  = $options['status'];
	$days    = absint( $options['days'] );

	// Imposta il valore predefinito comment_approved su spam.
	$comment_approved = 'spam';

	// Se lo stato è moderato, WordPress lo memorizza come "0".
	if ( 'moderated' !== $status ) {
		$comment_approved = '0';
	}

	// Crea ed esegui la query per eliminare i commenti.
	$sql = "DELETE FROM $wpdb->comments
	        WHERE ( comment_approved = '$comment_approved' )
		AND DATEDIFF( now(), comment_date ) > %d";

	$wpdb->query( $wpdb->prepare( $sql, $days ) );
}

register_deactivation_hook( __FILE__, 'developress_delete_comments_deactivate' );

function developress_delete_comments_deactivate() {

	$timestamp = wp_next_scheduled( 'developress_delete_comments_event' );

	if ( false !== $timestamp ) {
		wp_unschedule_event( $timestamp, 'developress_delete_comments_event' );
	}
}

 




Plugin e database

Quando sviluppiamo un plugin…

A volte può essere necessario archiviare i dati del database per far sì che i plugin funzionano correttamente, dall’archiviazione di alcune semplici opzioni all’aggiunta ddi tabelle complete con più dati per l’utente, il database è uno strumento che deve essere sfruttato al meglio. Avere i dati nel database vuol dire poter effettuare query più facilmente.

Ma… avere un database con molti dati non è semplice da gestire e dobbiamo assicurarci che l’utente sia in grado di disinstallare i dati archiviati dal plugin; se questo non è possibile dobbiamo decidere dove salvare questi dati. Ad esempio possiamo utilizzare la tabella creata da WordPress, utile per impostazioni minori oppure (soluzione migliore) creare una nostra tabella all’interno del database da utilizzare per il nostro plugin. Se scegliamo questa ultima opzione, ricordiamo di effettuare il backup completo del database manualmente, in quanto WordPress non la salva nei suoi “backup di base”.

Oltre a quanto detto dobbiamo affrontare l’argomento caching, in particolare se questo recupera i dati da un servizio esterno a intervalli regolari. Possiamo utilizzare i file per il caching ma un’altra opzione è l’API Transients, creata proprio per tali operazioni.

In conclusione, cosa è meglio fare nel database quando programmiamo un plugin? Personalmente consiglio di collocare le impostazioni nelle opzioni, quando si tratta di un contenuto vero e proprio (o quantità grandi di dati), è meglio utilizzare l’opzione della tabella esterna. Assicuriamoci sempre che è possibile effettuare una pulizia dopo la disinstallazione e di informare le persone che lavorano/utilizzano il sito web.