Обновить меню при сохранении настроек

У меня есть страница настроек для моего плагина, на которой пользователь может включить или отключить пользовательский тип записи. Когда плагин инициализируется, я проверяю этот параметр, чтобы увидеть, должен ли пользовательский тип контента быть зарегистрирован или нет. Метод registerPostType () вызывается для действия init :

class CPT {  private $enabled = false;  public function __construct()  {    //Handle form submission.    add_action('init', array($this, 'checkFormSubmission'), 8);    //Load settings.    $settings = get_option('cpt_settings');    $this->enabled = $settings['enabled'];    //Add menu.    add_action('admin_menu', array($this, 'registerMenu'));    //Register custom post type if enabled.    if ($this->enabled) {        add_action('init', array($this, 'registerPostType'));    }  }  public function registerMenu()  {    add_submenu_page(        'options-general.php',        __('CPT Settings', 'cpt'),        __('CPT Settings', 'cpt'),        'manage_options',        'cpt',        array($this, 'renderSettingsPage')    );  }  public function registerPostType()  {    $args = array(        'labels' => array(          'name' => 'CPT',        ),        'public' => true,        'publicly_queryable' => true,        'show_ui' => true,        'show_in_menu' => true,        'query_var' => true,        'capability_type' => 'post',        'has_archive' => true,        'hierarchical' => false,        'menu_position' => null,        'supports' => array('title', 'editor', 'author', 'thumbnail', 'excerpt')    );    register_post_type('sample-cpt',  $args);  }  public function checkFormSubmission()  {    //Validate so user has correct privileges.    if (!current_user_can('manage_options')) {      die(__('You are not allowed to perform this action.', 'cpt'));    }    //Check if settings form is submitted.    if (filter_input(INPUT_POST, 'cpt-settings', FILTER_SANITIZE_STRING)) {      //Verify nonce and referer.      check_admin_referer('cpt-settings-action', 'cpt-settings-nonce');      $this->enabled = filter_input(          INPUT_POST,          'cpt-enable',          FILTER_VALIDATE_BOOLEAN      );      update_option('cpt_settings', array('enabled' => $this->enabled));    }  }  public function renderSettingsPage()  {    require_once plugin_dir_path(__FILE__ ) . '/admin/templates/settings-page.php';  }}new CPT();

Это работает, как и ожидалось, но проблема в том, что когда я сохраняю Форма пункта меню для настраиваемого типа поста не обновляется, пока я не перезагрузлю страницу. Очевидно, это связано с тем, что меню уже создано.

Сначала я подумал, что я не использую правильные перехватчики для того, чтобы позаботиться о отправке формы и зарегистрировать свой пользовательский пост, или, возможно, перехватчики следует добавить с помощью с более высоким приоритетом?

Я пытался использовать wp_redirect () после сохранения настройки, но я не могу установить какие-либо заголовки, потому что вывод уже начался.

Может кто-нибудь объяснить, как я могу сделать пункт меню для своего пользовательского типа обновления постов при сохранении настроек для моего плагина?

Ответы и комментарии:

Не ответ, а наблюдение ... Я быстро использовал плагин "Типы наборов инструментов", который позволяет создавать и изменять пользовательские типы сообщений (и другие вещи). Я только что создал пользовательский тип сообщения и нажал «Сохранить тип сообщения», и меню «Пользовательский тип сообщения» сразу же появилось в меню администратора. Все это заставляет меня поверить, что нет магии, но что какая-то «основная» проблема является коренной причиной проблемы. В любом случае, правильно ли предположить, что ваше меню для пользовательского типа сообщений появляется в меню администратора самостоятельно, а не «внутри» меню администратора вашего плагина?
Создан 16-09-2018 05:17 Tedinoz

@Tedinoz - Да, мой пользовательский тип поста имеет собственный пункт меню, расположенный на верхнем уровне в меню администратора.
Создан 16-09-2018 05:51 Cyclonecode

Не отвлекаясь от ответа Джанха, могу ли я добавить, что существует общее согласие о том, что не нужно ставить хуки в конструктор? Существует отличный ответ WP_SE и пример кода от gmazzap на тему «Лучший способ инициировать класс в плагине WP?» (второй и более длинный ответ). В его примере используются три класса (frontend, backend и «третий используется в обоих случаях»), а также средства их создания с использованием «правильных» хуков. Может быть, это даст вам другие идеи о вашем коде.
Создан 16-09-2018 02:16 Tedinoz

Кажется, это не решает мою проблему? Проблема в том, что когда я регистрирую свой пользовательский тип сообщения, он не будет отображаться в меню администратора, прежде чем я перезагрузить страницу один раз? RegisterMenu () регистрирует только меню для плагина и, конечно, всегда должен быть видимым, пока плагин активирован?
Создан 16-09-2018 08:48 Cyclonecode

@ Cyclonecode Извините, я вроде как полностью погрузился в свои мысли, которые быстро расходились с тем, что вы написали. Я обновил ответ и считаю, что это должно иметь больше смысла и не походить на случайную тарабарщину.
Создан 16-09-2018 08:27 janh

Вы абсолютно правы. Я изменил свой код, чтобы соответствовать вышеуказанному шаблону, и теперь он работает как надо.
Создан 16-09-2018 09:50 Cyclonecode

Сначала я полностью неправильно понял ваш вопрос (слишком много чая, слишком сосредоточен на моем первоначальном представлении о том, в чем ваша проблема, вместо того, чтобы внимательно читать;).
Я считаю, что проблема не в том, что меню уже создано (admin_menu запускается после init), а в том, что registerPostType будет запускаться только в init, если он включен (а не когда он включен).
Перемещение if ($ this-> enabled) {в registerPostType и его безоговорочное выполнение при init, например, просто положить
if (! $ this-> enabled) return;

в верхней части registerPostType и изменения
// Зарегистрировать пользовательский тип записи, если он включен.
if ($ this-> enabled) {
    add_action ('init', array ($ this, 'registerPostType'));
}

в
// Зарегистрировать пользовательский тип записи, если он включен.
add_action ('init', array ($ this, 'registerPostType'));

кажется наиболее логичным для меня.
Создан 16-09-2018 08:09