Вопрос или проблема
Я здесь схожу с ума, пытаясь сделать так, чтобы флажок сохранялся на странице настроек плагина.
Сейчас я, как шаблон, работаю с отличным примером, представленным здесь: Пример 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);
}
Заключительные мысли
Надеюсь, приведенные выше шаги помогут вам решить проблему с сохранением чекбоксов на странице настроек вашего плагина. Всегда стоит подробно проверять массивы на наличие значений перед выполнением операций с ними, чтобы избежать неожиданных ошибок. Следующие шаги позволят вам улучшить код и избежать аналогичных проблем в будущем. Успехов в разработке!