add_role () ne s'exécute qu'une seule fois?

11

J'ai été surpris de découvrir que add_role () modifie la base de données et échoue si le rôle existe déjà. Il y a deux implications ici, l'une d'abord plus sérieuse que l'autre: 1) si vous êtes en développement et mettez à jour votre code add_role, vous devez d'abord remove_role () 2) une fois que vous avez bien compris, vous ne devriez jamais avoir à exécuter ce code encore.

Donc, généralement, j'ai mis mon add_role () dans un crochet d'action wp_loaded. Et depuis que je suis en développement, j'ai également ajouté un remove_role () avant mon add_role afin que je puisse être sûr que si je modifie ma liste de majuscules, cela prendra effectivement effet.

Mais il est clair que cela est désormais exécuté chaque fois qu'une page du blog est consultée. D'accord, je pourrais le mettre dans une action réservée aux administrateurs, ou je pourrais créer une page de plugin sous Utilisateurs ou Outils, où ce rôle peut être créé une fois. Je suppose que j'espère qu'il existe une solution plus simple et plus élégante.

Je n'imagine pas qu'il y a une sorte d'action run_once, n'est-ce pas?

Ou la meilleure pratique consiste-t-elle simplement à ajouter le rôle, puis à utiliser add_cap () plusieurs fois? Et même alors, j'imagine que add_cap accède à la base de données.

Je pense simplement à la meilleure façon de réduire l'accès inutile aux bases de données. Quelles sont vos bonnes pratiques?

Tom Auger
la source
Impressionnant! Merci pour cette question. L'ajout d'une remove_role()fonction avant add_role()m'a aidé.
beytarovski

Réponses:

10

Les rôles et les capacités des utilisateurs sont enregistrés dans la base de données, donc une fois que vous les avez utilisés, ils sont add_role()enregistrés puis chargés à la prochaine WordPress connaîtra ce rôle, tout comme les rôles intégrés.

Maintenant, si vous regardez la fonction add_role()plus spécifiquement à la ligne 141, vous verrez qu'elle enregistre uniquement le rôle et les capacités dans la base de données si la var $use_dbest définie sur true (ce qu'il est par défaut) afin que vous puissiez simplement la changer avant d'appeler votre add_role()et le rôle ne sera pas enregistré.

essayer:

//globalize $wp_roles
global $wp_roles;
//set use_db to flase
$wp_roles->use_db = false;
//then add your role
$wp_roles->add_role( $role, $display_name, $capabilities );

Mise à jour:

Si c'est dans un environnement de test / développement, je ne vois aucun inconvénient, mais si vous êtes dans un environnement en direct, vous économisez le temps nécessaire pour créer ce rôle à chaque chargement.

En ce qui concerne les meilleures pratiques exécutées une fois, si dans un plugin vous devez utiliser register_activation_hooket pour toute autre chose j'utilise une simple fonction conditionnelle personnalisée:

function run_once($key){
    $test_case = get_option('run_once');
    if (isset($test_case[$key]) && $test_case[$key]){
        return false;
    }else{
        $test_case[$key] = true;
        update_option('run_once',$test_case);
        return true;
    }
}

**usage:**
if (run_once('add_user_role')){
    //do you stuff and it will only run once
}
Bainternet
la source
Oh merde. Je le savais même à propos de certains enracinements antérieurs sur la classe WP_Roles. Pouvez-vous penser à un inconvénient de NE PAS utiliser la base de données pour les rôles? Et existe-t-il une meilleure pratique WP pour ne faire quelque chose qu'une seule fois?
Tom Auger
Merci pour la mise à jour - j'aime la simplicité de la solution update_option
Tom Auger
Pas vraiment satisfaisant mais cela semble être la meilleure solution
Black
Cette fonction run_onceaugmente trop d'opérations de lecture / écriture de base de données à chaque chargement de page. Veuillez ne pas l'utiliser.
Mayank Dudakiya