Страница настроек плагина, флажок не сохраняется – один массив опций с подсистемой.

Вопрос или проблема

Я здесь схожу с ума, пытаясь сделать так, чтобы флажок сохранялся на странице настроек плагина.

Сейчас я, как шаблон, работаю с отличным примером, представленным здесь: Пример API настроек с массивами

Я также обращаюсь к очень полезному уроку на https://www.smashingmagazine.com/2016/04/three-approaches-to-adding-configurable-fields-to-your-plugin/, с подробным гитом по адресу https://github.com/rayman813/smashing-custom-fields/blob/master/smashing-fields-approach-1/smashing-fields.php

Я также прочитал около дюжины постов с похожими вопросами, но ни один из них не дал мне ответа, по крайней мере, того, который я смог найти и понять.

Думаю, я запнулся на синтаксисе функции checked().

— Обновленный код —

Вот ключевые части кода:

Общие данные в функции, которая вызывает register_setting(), add_settings_section() и add_settings_fields

   $option_name="rpq_plugin_option_name"; // можно выбрать это имя

// Получаем существующие параметры.
$option_values = get_option( $option_name );

$default_values = array (
    'number' => 500,
    'color'  => 'blue',
    'long'   => '',
    'activity' => array(
        'baseball' => '',
        'golf'     => '',
        'hockey'   => '')
);
$data = shortcode_atts( $default_values, $option_values );

Функция add_settings_field() для флажков:

    add_settings_field(
    'section_2_field_2',
    'Флажки',
    'rpq_plugin_render_section_2_field_2', // обратный вызов для рендеринга html
    'rpq-default-settings',  // слаг меню
    'section_2',
    array (
        'label_for'   => 'label4', // делает имя поля кликабельным,
        'name'        => 'activity', // значение для атрибута 'name'
        'value'       => array_map( 'esc_attr', $data['activity'] ) ,
        'options'     => array (
            'baseball'  => 'Бейсбол',
            'golf'      => 'Гольф',
            'hockey'    => 'Хоккей'
        ),
        'option_name' => $option_name
    )
);

Обратный вызов для рендеринга html:

   function rpq_plugin_render_section_2_field_2( $args )
{
$options_markup = '';
$iterator = 0;
$values = $args['value'];
$options = $args['options'];
rpq_plugin_debug_var( $options, 'Options: ' );
rpq_plugin_debug_var( $values, 'Values: ' );

foreach ( $args['options'] as $key => $title ) {
    rpq_plugin_debug_var( $key, 'Key: ' );
    rpq_plugin_debug_var( $title, 'Title: ' );
    $checked = checked((in_array($title, $values)), true, false);

    rpq_plugin_debug_var($checked, 'Checked: ');

    $iterator ++;
    $options_markup .= sprintf(
        '<label for="%1$s_%6$s"><input id="%1$s_%6$s" name="%1$s[%2$s]" type="checkbox" value="%3$s" %4$s /> %5$s</label><br/>', 

        $args['option_name'],
        $args['name'],
        $key,
        $checked,
        $title,
        $iterator
    );


}
        printf( '<fieldset>%s</fieldset>', $options_markup );

//print '</select>';

rpq_plugin_debug_var( $values, 'Values: ');
}

Вывод из отладочной дампа начальных переменных такой, как я и ожидал:

Options:  = array (
  'baseball' => 'Бейсбол',
  'golf' => 'Гольф',
  'hockey' => 'Хоккей',
)

Values:  = array (
  'baseball' => '',
  'golf' => '',
  'hockey' => '',
)

Key:  = 'baseball'

Title:  = 'Бейсбол'

Checked:  = ''

Key:  = 'golf'

Title:  = 'Гольф'

Checked:  = ''

Key:  = 'hockey'

Title:  = 'Хоккей'

Checked:  = ''

После попытки сохранить я получаю:

Values: = NULL

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

Я наконец-то разобрался с этим. Я напишу решение для любого другого неопытного человека, как я, который пытается работать с массивом флажков, используя всего лишь один массив параметров.

Во-первых, две статьи, на которые я ссылался в начале вопроса, хороши для изучения основ темы.

Решение – первая часть:

Я использую массив параметров со всеми возможными параметрами и массив значений, чтобы хранить только отмеченные элементы. Я создавал массив значений неправильно. Вместо того, чтобы быть ассоциативным массивом, он должен быть просто “обычным массивом”, содержащим только ключи из массива параметров.

Так что в моей настройке, вместо того чтобы устанавливать ‘activities’ в стандартных настройках на

 array (
            'baseball'  => '',
            'golf'      => '',
            'hockey'    => ''
        ), 

Я хочу просто

   array ()  

Решение – вторая часть

Если флажки не выбраны, когда настройки сохраняются, массив $values становится NULL. Но мне нужно использовать функции, которые требуют массив, чтобы сделать свои тесты на валидацию и для оценки флажков. Поэтому мне нужно убедиться, что $values всегда является массивом. Итак, мне нужно

    if (is_null($data['activity'])) {
    $data['activity'] = array();
}

Решение – третья часть

Моя функция checked() была неправильной. Как только я исправил свой массив, как обсуждалось выше, я проверяю, является ли текущий $key из массива $options значением из массива $values.

$checked = checked((in_array($key, $values)), true, false);

Решение – четвертая часть

Поскольку ‘activities’ является подмассивом значений параметров, я должен установить переменную name в инструкциях флажков соответствующим образом.

Поэтому я использую

name="%1$s[%2$s][]"

что генерирует

name="rpq_plugin_option_name[activity][]"

Теперь мои флажки обновляются и сохраняются.

Ответ или решение

Ваш вопрос о проблеме сохранения состояния чекбоксов на странице настроек плагина является достаточно распространенным среди разработчиков WordPress, и я рад помочь вам в этом. Рассмотрим шаги, которые необходимо предпринять для корректного сохранения и отображения чекбоксов с использованием массива опций и подмассивов.

1. Основные моменты настройки

Прежде всего, необходимо правильно определить структуру массивов для опций и значений. Вам нужно создать основной массив опций и отдельный массив значений для хранения состояния чекбоксов. Ваша текущая ошибка заключается в том, что вы создаете массив значений как ассоциативный массив, тогда как он должен представлять собой обычный массив.

Пример правильной структуры массива:

$default_values = array(
    'number' => 500,
    'color'  => 'blue',
    'long'   => '',
    'activity' => array() // Здесь должен быть пустой массив
);

2. Обработка сохранения

Во время сохранения настроек, если ни один чекбокс не выбран, массив $_POST['rpq_plugin_option_name']['activity'] будет равен NULL. Нам необходимо убедиться, что $values всегда является массивом для обработки.

Решение:

if (is_null($data['activity'])) {
    $data['activity'] = array();
}

3. Проверка состояния чекбоксов

Ваш метод проверки состояния активной опции с использованием функции checked() предполагает, что вы проверяете наличие текущего ключа из массива опций в массиве значений. Убедитесь, что ваша проверка выглядит следующим образом:

$checked = checked(in_array($key, $values), true, false);

4. Корректное именование чекбоксов

Если вы используете подмассивы в ваших опциях (в данном случае, подмассив activity), убедитесь, что атрибут name вашей HTML формы правильно отражает эту структуру. Чекбокс должен иметь следующий атрибут:

name="%1$s[%2$s][]"

Который будет генерировать:

name="rpq_plugin_option_name[activity][]"

5. Итоговый код

Вот как должно выглядеть ваше полное решение для чекбоксов:

function rpq_plugin_render_section_2_field_2($args) {
    $options_markup = '';
    $values = $args['value'];
    $options = $args['options'];

    // Если $values NULL, присвоим ему пустой массив
    if (is_null($values)) {
        $values = array();
    }

    foreach ($options as $key => $title) {
        $checked = checked(in_array($key, $values), true, false);

        $options_markup .= sprintf(
            '<label for="%1$s_%2$s"><input id="%1$s_%2$s" name="%1$s[%3$s][]" type="checkbox" value="%4$s" %5$s /> %6$s</label><br/>',
            $args['option_name'],
            $key,
            $args['name'],
            $key,
            $checked,
            $title
        );
    }

    printf('<fieldset>%s</fieldset>', $options_markup);
}

Заключительные мысли

Надеюсь, приведенные выше шаги помогут вам решить проблему с сохранением чекбоксов на странице настроек вашего плагина. Всегда стоит подробно проверять массивы на наличие значений перед выполнением операций с ними, чтобы избежать неожиданных ошибок. Следующие шаги позволят вам улучшить код и избежать аналогичных проблем в будущем. Успехов в разработке!

Оцените материал
Добавить комментарий

Капча загружается...