add_role () запускается только один раз?

11

Я был удивлен, обнаружив, что add_role () изменяет базу данных и дает сбой, если роль уже существует. Здесь есть два значения, одно из которых более серьезное, чем другое: 1) если вы разрабатываете и обновляете свой код add_role, вы должны сначала удалить remove_role () 2), как только вы все сделаете правильно, вам никогда не придется запускать этот код опять таки.

Поэтому обычно я помещаю свой add_role () в хук действия wp_loaded. И так как я нахожусь в разработке, я также добавил remove_role () перед моим add_role, так что я могу быть уверен, что если я изменю свой список заглавных букв, он действительно вступит в силу.

Но очевидно, что это теперь выполняется каждый раз, когда к странице блога обращаются. Хорошо, я мог бы поместить это в действие только для администратора, или я мог бы создать страницу плагина, возможно, в разделе «Пользователи» или «Инструменты», где эту роль можно создать один раз. Я надеюсь, что есть более простое и элегантное решение.

Я не думаю, что есть какое-то действие типа run_once?

Или лучше всего добавить роль, а затем несколько раз использовать add_cap ()? И даже тогда я представляю, что add_cap обращается к БД.

Просто думать с точки зрения лучшего способа уменьшить ненужный доступ к БД. Каковы ваши лучшие практики?

Том Оже
источник
Потрясающие! Спасибо за этот вопрос. Просто добавление remove_role()функции, прежде чем add_role()мне помогли.
бейтаровский

Ответы:

10

Роли и возможности пользователей сохраняются в базе данных, поэтому, как только вы их использовали, вы add_role()сохраните их, а затем при следующей загрузке WordPress узнает эту роль точно так же, как встроенные роли.

Теперь, если вы посмотрите на функцию add_role()более конкретно на строку 141, вы увидите, что она сохраняет роль и возможности в базе данных только в том случае, если для переменной $use_dbустановлено значение true (по умолчанию он используется), поэтому вы можете просто изменить ее перед вызовом add_role()функция и роль не будет сохранена.

пытаться:

//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 );

Обновить:

Если это в среде тестирования / разработки, то я не вижу недостатков, но если вы работаете в реальной среде, вы экономите время, необходимое для создания этой роли при каждой загрузке.

Что касается лучшей практики, запустите один раз, если в плагине вы должны использовать register_activation_hookи для чего-то еще я использую простую пользовательскую условную функцию:

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
источник
Ой дерьмо. Я даже знал об этом тоже по некоторым ранним рутинам о классе WP_Roles. Можете ли вы вспомнить какой-либо недостаток, если НЕ использовать базу данных для ролей? И есть ли в WP наилучший способ сделать что-то только один раз?
Том Оджер
Спасибо за обновление - мне нравится простота решения update_option
Tom Auger
Не совсем удовлетворительно, но, похоже, это лучшее решение 👍
Blackbam
Эта функция run_onceувеличивает нагрузку на операции чтения / записи при каждой загрузке страницы. Пожалуйста, не используйте это.
Маянк Дудакия