Il y a trois crochets différents . Ils se déclenchent dans les cas suivants:
- Désinstaller
- Désactivation
- Activation
Comment déclencher des fonctions en toute sécurité pendant les scénarios
Ce qui suit montre les bonnes manières d’accrocher en toute sécurité des fonctions de rappel déclenchées au cours des actions mentionnées.
Comme vous pourriez utiliser ce code dans un plugin qui utilise
- fonctions simples,
- une classe ou
- une classe externe,
Je vais montrer trois plugins de démonstration que vous pouvez inspecter, puis implémenter le code dans vos propres plugins.
Remarque importante dès le départ!
Comme ce sujet est extrêmement difficile et très détaillé et compte une douzaine de cas, cette réponse ne sera jamais parfaite. Je vais continuer à l'améliorer avec le temps, alors revenez régulièrement.
(1) Activer / Désactiver / Désinstaller des plugins.
Les rappels de configuration du plugin sont déclenchés par core et vous n’avez aucune influence sur la manière dont le core le fait. Il y a quelques points à garder à l'esprit:
- Jamais , jamais
echo/print
rien (!) Pendant les rappels d'installation. Cela conduira à un headers already sent
message et le noyau recommandera de désactiver et de supprimer votre plugin ... ne demandez pas: je sais ...
- Vous ne verrez aucune sortie visuelle. Mais j'ai ajouté des
exit()
déclarations à tous les rappels afin que vous puissiez avoir un aperçu de ce qui se passe réellement. Il suffit de les commenter pour que les choses fonctionnent.
- Il est extrêmement important de vérifier si
__FILE__ != WP_PLUGIN_INSTALL
et (si ce n’est pas le cas: abandonnez!) Pour voir s’il désinstalle réellement le plug-in. Je recommanderais simplement de déclencher des on_deactivation()
rappels pendant le développement, afin de vous faire gagner du temps. Tout au moins, c'est ce que je fais.
- Je fais aussi des trucs de sécurité. Certains sont effectués par noyau également, mais bon! Mieux vaut prévenir que guérir! .
- Tout d'abord, je refuse l'accès direct aux fichiers lorsque le coeur n'est pas chargé:
defined( 'ABSPATH' ) OR exit;
- Ensuite, je vérifie si l'utilisateur actuel est autorisé à effectuer cette tâche.
- En dernier lieu, je vérifie le référant. Remarque: il peut y avoir des résultats inattendus avec un
wp_die()
écran demandant les autorisations appropriées (et si vous voulez réessayer ... ouais, bien sûr ), lorsque vous recevez une erreur. Cela se produit lorsque le noyau vous redirige, définit le courant $GLOBALS['wp_list_table']->current_action();
sur error_scrape
, puis vérifie le référent check_admin_referer('plugin-activation-error_' . $plugin);
, où $plugin
est $_REQUEST['plugin']
. Donc, la redirection se produit à la moitié du chargement de la page et vous obtenez cette barre de défilement câblée et l'écran des puces insight la notification / message jaune de l'administrateur. Si cela se produit: restez calme et recherchez l'erreur avec un exit()
débogage pas à pas.
(A) Plugin des fonctions simples
N'oubliez pas que cela pourrait ne pas fonctionner si vous associez les rappels avant la définition de la fonction.
<?php
defined( 'ABSPATH' ) OR exit;
/**
* Plugin Name: (WCM) Activate/Deactivate/Uninstall - Functions
* Description: Example Plugin to show activation/deactivation/uninstall callbacks for plain functions.
* Author: Franz Josef Kaiser/wecodemore
* Author URL: http://unserkaiser.com
* Plugin URL: http://wordpress.stackexchange.com/questions/25910/uninstall-activate-deactivate-a-plugin-typical-features-how-to/25979#25979
*/
function WCM_Setup_Demo_on_activation()
{
if ( ! current_user_can( 'activate_plugins' ) )
return;
$plugin = isset( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : '';
check_admin_referer( "activate-plugin_{$plugin}" );
# Uncomment the following line to see the function in action
# exit( var_dump( $_GET ) );
}
function WCM_Setup_Demo_on_deactivation()
{
if ( ! current_user_can( 'activate_plugins' ) )
return;
$plugin = isset( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : '';
check_admin_referer( "deactivate-plugin_{$plugin}" );
# Uncomment the following line to see the function in action
# exit( var_dump( $_GET ) );
}
function WCM_Setup_Demo_on_uninstall()
{
if ( ! current_user_can( 'activate_plugins' ) )
return;
check_admin_referer( 'bulk-plugins' );
// Important: Check if the file is the one
// that was registered during the uninstall hook.
if ( __FILE__ != WP_UNINSTALL_PLUGIN )
return;
# Uncomment the following line to see the function in action
# exit( var_dump( $_GET ) );
}
register_activation_hook( __FILE__, 'WCM_Setup_Demo_on_activation' );
register_deactivation_hook( __FILE__, 'WCM_Setup_Demo_on_deactivation' );
register_uninstall_hook( __FILE__, 'WCM_Setup_Demo_on_uninstall' );
(B) Une architecture de classe / POO
C'est l'exemple le plus courant dans les plugins actuels.
<?php
defined( 'ABSPATH' ) OR exit;
/**
* Plugin Name: (WCM) Activate/Deactivate/Uninstall - CLASS
* Description: Example Plugin to show activation/deactivation/uninstall callbacks for classes/objects.
* Author: Franz Josef Kaiser/wecodemore
* Author URL: http://unserkaiser.com
* Plugin URL: http://wordpress.stackexchange.com/questions/25910/uninstall-activate-deactivate-a-plugin-typical-features-how-to/25979#25979
*/
register_activation_hook( __FILE__, array( 'WCM_Setup_Demo_Class', 'on_activation' ) );
register_deactivation_hook( __FILE__, array( 'WCM_Setup_Demo_Class', 'on_deactivation' ) );
register_uninstall_hook( __FILE__, array( 'WCM_Setup_Demo_Class', 'on_uninstall' ) );
add_action( 'plugins_loaded', array( 'WCM_Setup_Demo_Class', 'init' ) );
class WCM_Setup_Demo_Class
{
protected static $instance;
public static function init()
{
is_null( self::$instance ) AND self::$instance = new self;
return self::$instance;
}
public static function on_activation()
{
if ( ! current_user_can( 'activate_plugins' ) )
return;
$plugin = isset( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : '';
check_admin_referer( "activate-plugin_{$plugin}" );
# Uncomment the following line to see the function in action
# exit( var_dump( $_GET ) );
}
public static function on_deactivation()
{
if ( ! current_user_can( 'activate_plugins' ) )
return;
$plugin = isset( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : '';
check_admin_referer( "deactivate-plugin_{$plugin}" );
# Uncomment the following line to see the function in action
# exit( var_dump( $_GET ) );
}
public static function on_uninstall()
{
if ( ! current_user_can( 'activate_plugins' ) )
return;
check_admin_referer( 'bulk-plugins' );
// Important: Check if the file is the one
// that was registered during the uninstall hook.
if ( __FILE__ != WP_UNINSTALL_PLUGIN )
return;
# Uncomment the following line to see the function in action
# exit( var_dump( $_GET ) );
}
public function __construct()
{
# INIT the plugin: Hook your callbacks
}
}
(C) Une architecture de classe / OOP avec un objet de configuration externe
Ce scénario suppose que vous avez un fichier de plugin principal et un second fichier nommé setup.php
dans un sous - répertoire du plugin nommé inc
: ~/wp-content/plugins/your_plugin/inc/setup.php
. Cela fonctionnera également lorsque le dossier du plug-in se trouve en dehors de la structure de dossiers WP par défaut, ainsi que lorsque le répertoire de contenu est renommé ou dans les cas où votre fichier d'installation porte un nom différent. Seul le inc
dossier doit avoir le même nom et le même emplacement que le répertoire racine des plugins.
Note: Vous pouvez simplement prendre les trois register_*_hook()*
fonctions et les classes et les déposer dans votre plugin.
Le fichier de plugin principal:
<?php
defined( 'ABSPATH' ) OR exit;
/**
* Plugin Name: (WCM) Activate/Deactivate/Uninstall - FILE/CLASS
* Description: Example Plugin
* Author: Franz Josef Kaiser/wecodemore
* Author URL: http://unserkaiser.com
* Plugin URL: http://wordpress.stackexchange.com/questions/25910/uninstall-activate-deactivate-a-plugin-typical-features-how-to/25979#25979
*/
register_activation_hook( __FILE__, array( 'WCM_Setup_Demo_File_Inc', 'on_activation' ) );
register_deactivation_hook( __FILE__, array( 'WCM_Setup_Demo_File_Inc', 'on_deactivation' ) );
register_uninstall_hook( __FILE__, array( 'WCM_Setup_Demo_File_Inc', 'on_uninstall' ) );
add_action( 'plugins_loaded', array( 'WCM_Setup_Demo_File', 'init' ) );
class WCM_Setup_Demo_File
{
protected static $instance;
public static function init()
{
is_null( self::$instance ) AND self::$instance = new self;
return self::$instance;
}
public function __construct()
{
add_action( current_filter(), array( $this, 'load_files' ), 30 );
}
public function load_files()
{
foreach ( glob( plugin_dir_path( __FILE__ ).'inc/*.php' ) as $file )
include_once $file;
}
}
Le fichier d'installation:
<?php
defined( 'ABSPATH' ) OR exit;
class WCM_Setup_Demo_File_Inc
{
public static function on_activation()
{
if ( ! current_user_can( 'activate_plugins' ) )
return;
$plugin = isset( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : '';
check_admin_referer( "activate-plugin_{$plugin}" );
# Uncomment the following line to see the function in action
# exit( var_dump( $_GET ) );
}
public static function on_deactivation()
{
if ( ! current_user_can( 'activate_plugins' ) )
return;
$plugin = isset( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : '';
check_admin_referer( "deactivate-plugin_{$plugin}" );
# Uncomment the following line to see the function in action
# exit( var_dump( $_GET ) );
}
public static function on_uninstall()
{
if ( ! current_user_can( 'activate_plugins' ) )
return;
check_admin_referer( 'bulk-plugins' );
// Important: Check if the file is the one
// that was registered during the uninstall hook.
if ( __FILE__ != WP_UNINSTALL_PLUGIN )
return;
# Uncomment the following line to see the function in action
# exit( var_dump( $_GET ) );
}
}
(2) Mises à jour du plugin
Si vous écrivez un plug-in qui possède sa propre table de base de données ou ses propres options, il peut arriver que vous deviez modifier ou mettre à niveau des éléments.
Malheureusement, il n’existe jusqu’à présent aucune possibilité d’exécuter quelque chose sur l’installation ou la mise à jour / mise à niveau du plugin / thème. Heureusement, il existe un moyen de contourner le problème: associez une fonction personnalisée à une option personnalisée (oui, c'est nul, mais cela fonctionne).
function prefix_upgrade_plugin()
{
$v = 'plugin_db_version';
$update_option = null;
// Upgrade to version 2
if ( 2 !== get_option( $v ) )
{
if ( 2 < get_option( $v ) )
{
// Callback function must return true on success
$update_option = custom_upgrade_cb_fn_v3();
// Only update option if it was an success
if ( $update_option )
update_option( $v, 2 );
}
}
// Upgrade to version 3, runs just after upgrade to version 2
if ( 3 !== get_option( $v ) )
{
// re-run from beginning if previous update failed
if ( 2 < get_option( $v ) )
return prefix_upgrade_plugin();
if ( 3 < get_option( $v ) )
{
// Callback function must return true on success
$update_option = custom_upgrade_cb_fn_v3();
// Only update option if it was an success
if ( $update_option )
update_option( $v, 3 );
}
}
// Return the result from the update cb fn, so we can test for success/fail/error
if ( $update_option )
return $update_option;
return false;
}
add_action('admin_init', 'prefix_upgrade_plugin' );
La source
Cette fonction de mise à jour est un exemple pas très agréable / bien écrit, mais comme il est dit: C’est un exemple et la technique fonctionne bien. Améliorera cela avec une mise à jour ultérieure.