Come far richiedere a un plugin un altro plugin?
Sto sviluppando un plugin che aggiunge funzionalità extra a un plugin principale. Idealmente nella schermata di amministrazione dei plugin, il link "attiva" dovrebbe essere disabilitato e dovrebbe essere aggiunta una nota in linea che informa l'utente di installare e attivare prima il plugin principale prima di poter utilizzare il plugin corrente.

Grazie per le risposte ragazzi. Sebbene entrambe le soluzioni mi abbiano messo sulla strada giusta, nessuna ha funzionato subito senza modifiche. Quindi condivido le mie soluzioni qui sotto.
Metodo 1 - Utilizzo di register_activation_hook:
Crea il Plugin Genitore in plugins/parent-plugin/parent-plugin.php:
<?php
/*
Plugin Name: Parent Plugin
Description: Plugin dimostrativo con un plugin figlio dipendente.
Version: 1.0.0
*/
Crea il Plugin Figlio in plugins/child-plugin/child-plugin.php:
<?php
/*
Plugin Name: Child Plugin
Description: Il Parent Plugin deve essere installato e attivo per utilizzare questo plugin.
Version: 1.0.0
*/
register_activation_hook( __FILE__, 'child_plugin_activate' );
function child_plugin_activate(){
// Richiede il plugin genitore
if ( ! is_plugin_active( 'parent-plugin/parent-plugin.php' ) and current_user_can( 'activate_plugins' ) ) {
// Interrompe l'attivazione e mostra un errore
wp_die('Spiacente, ma questo plugin richiede che il Parent Plugin sia installato e attivo. <br><a href="' . admin_url( 'plugins.php' ) . '">« Ritorna ai Plugin</a>');
}
}
Nota che non sto utilizzando deactivate_plugins( $plugin );
perché per qualche motivo non funziona. Quindi ho usato wp_die per annullare il reindirizzamento dell'attivazione e informare l'utente.
Vantaggio:
- Soluzione semplice e non comporta ulteriori accessi al database rispetto al metodo 2
Svantaggi:
- La schermata wp_die non è esteticamente gradevole
- La schermata wp_die apparirà COMUNQUE se si attivano sia il Parent Plugin che il Child Plugin contemporaneamente utilizzando le caselle di controllo nella schermata di amministrazione dei plugin.
Metodo 2 - Utilizzo di admin_init e admin_notices
Crea il Plugin Genitore in plugins/parent-plugin/parent-plugin.php:
<?php
/*
Plugin Name: Parent Plugin
Description: Plugin dimostrativo con un plugin figlio dipendente.
Version: 1.0.0
*/
Crea il Plugin Figlio in plugins/child-plugin/child-plugin.php:
<?php
/*
Plugin Name: Child Plugin
Description: Il Parent Plugin deve essere installato e attivo per utilizzare questo plugin.
Version: 1.0.0
*/
add_action( 'admin_init', 'child_plugin_has_parent_plugin' );
function child_plugin_has_parent_plugin() {
if ( is_admin() && current_user_can( 'activate_plugins' ) && !is_plugin_active( 'parent-plugin/parent-plugin.php' ) ) {
add_action( 'admin_notices', 'child_plugin_notice' );
deactivate_plugins( plugin_basename( __FILE__ ) );
if ( isset( $_GET['activate'] ) ) {
unset( $_GET['activate'] );
}
}
}
function child_plugin_notice(){
?><div class="error"><p>Spiacente, ma Child Plugin richiede che il plugin Parent sia installato e attivo.</p></div><?php
}
Vantaggio:
- Funziona quando si attivano contemporaneamente sia il Parent che il Child plugin utilizzando le caselle di controllo
Svantaggio:
- Comporta ulteriori accessi al database poiché il plugin viene effettivamente attivato inizialmente e disattivato una volta eseguito admin_init.
Per quanto riguarda la mia domanda sulla disabilitazione del link di attivazione, potrei usare:
add_filter( 'plugin_action_links', 'disable_child_link', 10, 2 );
function disable_child_link( $links, $file ) {
if ( 'child-plugin/child-plugin.php' == $file and isset($links['activate']) )
$links['activate'] = '<span>Attiva</span>';
return $links;
}
Tuttavia, si è rivelato altamente impraticabile in quanto NON c'è un posto dove inserire questo codice. Non potevo metterlo nel plugin genitore perché il plugin genitore deve essere attivo affinché questo codice funzioni. Certamente non appartiene al plugin figlio o a functions.php. Quindi sto abbandonando questa idea.

Il metodo 2 ha funzionato alla grande! L'ho usato per estendere il plugin di qualcun altro.

A partire dalla versione 6.5 di WordPress, puoi definire le dipendenze dei plugin direttamente nel file principale del plugin utilizzando l'intestazione Requires Plugins
. Ad esempio:
/**
* Plugin Name: My Plugin
* Requires Plugins: plugin-one, plugin-two
*/
Basta aggiungere un elenco separato da virgole degli slug dei plugin presenti nel repository di WordPress.org, ed è tutto pronto.
Le dipendenze vengono elencate nella scheda del plugin stesso, nelle schermate Plugin → Tutti i plugin
e Plugin → Aggiungi nuovo
.
Anche i plugin non ospitati su WordPress.org possono essere elencati, ma devono essere installati manualmente.
Nota che questa funzionalità non funziona per i temi, solo per i plugin. Inoltre, non è possibile definire versioni specifiche dei plugin e tutti i plugin elencati saranno obbligatori. Non c'è modo di richiedere solo uno dei plugin elencati.
Leggi l'annuncio completo di questa funzionalità nel post correlato su make.wordpress.org.

Entrambe le soluzioni proposte hanno delle imperfezioni.
Metodo 1: Come menzionato, la schermata wp_die() apparirà COMUNQUE quando il Plugin Genitore e il Plugin Figlio sono attivati contemporaneamente utilizzando le caselle di controllo nella schermata di amministrazione dei plugin.
Metodo 2: In alcuni casi d'uso non è ottimale poiché 'admin_init' viene eseguito molto dopo 'plugins_loaded' (https://codex.wordpress.org/Plugin_API/Action_Reference), e dopo l'hook di disinstallazione (https://codex.wordpress.org/Function_Reference/register_uninstall_hook). Quindi, ad esempio, se vogliamo che l'add-on esegua del codice durante la disinstallazione indipendentemente dal fatto che il plugin genitore sia attivo o meno, questo approccio NON funzionerà.
Soluzione:
Innanzitutto, dobbiamo aggiungere il seguente codice alla fine del file PHP principale del plugin genitore:
do_action( 'my_plugin_loaded' );
Questo invierà un evento/segnale a tutti i sottoscrittori, comunicando che il plugin principale è stato caricato.
Quindi, la classe dell'add-on dovrebbe essere simile alla seguente:
class My_Addon
{
static function init ()
{
register_activation_hook( __FILE__, array( __CLASS__, '_install' ) );
if ( ! self::_is_parent_active_and_loaded() ) {
return;
}
}
#region Controllo Plugin Genitore
/**
* Verifica se il plugin genitore è attivato (non necessariamente caricato).
*
* @author Vova Feldman (@svovaf)
*
* @return bool
*/
static function _is_parent_activated()
{
$active_plugins_basenames = get_option( 'active_plugins' );
foreach ( $active_plugins_basenames as $plugin_basename ) {
if ( false !== strpos( $plugin_basename, '/my-plugin-main-file.php' ) ) {
return true;
}
}
return false;
}
/**
* Verifica se il plugin genitore è attivo e caricato.
*
* @author Vova Feldman (@svovaf)
*
* @return bool
*/
static function _is_parent_active_and_loaded()
{
return class_exists( 'My_Plugin' );
}
/**
*
* @author Vova Feldman (@svovaf)
*/
static function _install()
{
if ( ! self::_is_parent_active_and_loaded() ) {
deactivate_plugins( basename( __FILE__ ) );
// Messaggio di errore + link per tornare indietro.
wp_die( __( 'My Add-on richiede che My Plugin sia installato e attivato.' ), __( 'Errore' ), array( 'back_link' => true ) );
}
}
#endregion Controllo Plugin Genitore
}
if (My_Addon::_is_parent_active_and_loaded())
{
// Se il plugin genitore è già incluso, inizializza l'add-on.
My_Addon::init();
}
else if (My_Addon::_is_parent_activated())
{
// Inizializza l'add-on solo dopo che il plugin genitore è stato caricato.
add_action( 'my_plugin_loaded', array( __CLASS__, 'init' ) );
}
else
{
// Anche se il plugin genitore non è attivato, esegui l'add-on per gli hook di attivazione/disinstallazione.
My_Addon::init();
}
Spero sia utile :)

Anche questa risposta ha un difetto. :-) Presuppone che tu abbia il controllo completo sul plugin genitore dove puoi aggiungere do_action( 'my_plugin_loaded' ); nel suo codice. La risposta selezionata funzionerà con o senza controllo del plugin genitore (ad esempio se il plugin genitore non è tuo)

Prova questo codice, è commentato per aiutarti a comprenderlo meglio.
<?php
register_activation_hook( __FILE__, 'myplugin_activate' ); // Registra myplugin_activate all'attivazione
function myplugin_activate() {
$plugin = plugin_basename( __FILE__ ); // 'myplugin'
if ( is_plugin_active( 'plugin-directory/first-plugin.php' ) ) {
// Il plugin era attivo, esegui l'hook per 'myplugin'
} else {
// Il plugin non era attivo, oh no, non permettere l'attivazione di questo plugin
deactivate_plugins( $plugin ); // Disattiva 'myplugin'
}
}
?>
Se questo genera un errore, potresti anche controllare l'opzione di 'myplugin' e impostarla su false o non attivata.

Penso che tu abbia bisogno di TGM Plugin Activation.
TGM Plugin Activation è una libreria PHP che ti permette di richiedere o raccomandare facilmente plugin per i tuoi temi WordPress (e plugin). Consente ai tuoi utenti di installare, aggiornare e persino attivare automaticamente i plugin in modo singolo o in blocco utilizzando le classi, le funzioni e le interfacce native di WordPress. Puoi fare riferimento a plugin inclusi, plugin dal Repository dei Plugin di WordPress o persino plugin ospitati altrove su internet.
