1 (edited by PunBB 2017.07.06 04:55)

Topic: Создаем форму с чекбоксом для расширения

Многие программисты, по крайней мере я уже раз 5 встречал эту ошибку в расширениях, при создании формы делают поверку отправленного запроса формы и соответственно проверку включенного чекбокса. Ну, давайте на примере рассмотрим, что ли?  PunBB_INFO_ICQ/smile

Ну к примеру возьмем расширение Default Avatar. Вот сама форма с чекбоксом:

?>
            <div class="sf-set set<?php echo ++$forum_page['item_count'] ?>">
               <div class="sf-box checkbox">
                  <span class="fld-input"><input type="checkbox" id="fld<?php echo ++$forum_page['fld_count'] ?>" name="form[default_avatar]" value="1"<?php if ($forum_config['o_default_avatar'] == '1') echo ' checked="checked"' ?> /></span>
                  <label for="fld<?php echo $forum_page['fld_count'] ?>"><span><?php echo $lang_default_avatar['Default avatar'] ?></span></label>
               </div>
            </div>

После этого разработчик вешает проверку формы на хук $matches[2]

if (!isset($form['default_avatar']) || $form['default_avatar'] != '1')
   $form['default_avatar'] = '0';

Это означает, что если форма не отправлена или же форма отправлена, но не равна 1, то установится 0. Получается, что если у нас в настройках установлен 1, а мы отключаем чекбокс (снимаем галочку) и сохраняем настройки то $form['default_avatar'] будет равен 0, так как не возвращает единицу.

Но сделаем обратное. В настройка установлен 0, то есть чекбокс снят, ставим, сохраняем. Что видим? Форма отправила еденицу, чтобы чекбокс сохранился отмеченным, но так как туда пришла единица, то условие не сработает и в настройках даже не поменяется значение.

2

Re: Создаем форму с чекбоксом для расширения

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

?>
            <div class="sf-set set<?php echo ++$forum_page['item_count'] ?>">
               <div class="sf-box checkbox">

<input type="hidden" name="form[default_avatar]" value="0" />

                  <span class="fld-input"><input type="checkbox" id="fld<?php echo ++$forum_page['fld_count'] ?>" name="form[default_avatar]" value="1"<?php if ($forum_config['o_default_avatar'] == '1') echo ' checked="checked"' ?> /></span>
                  <label for="fld<?php echo $forum_page['fld_count'] ?>"><span><?php echo $lang_default_avatar['Default avatar'] ?></span></label>
               </div>
            </div>
<?php

Итак, мы добавили в форму скрытое поле значение которого всегда равно 0.

<input type="hidden" name="form[default_avatar]" value="0" />

Что получается?

Здесь механизм следующий: если в форме имеется два одинаковых имени формы, то есть name="form[default_avatar]", то всегда будет отправляться значение последней формы. Пусть у вас их будет хоть тысяча, в все равно решающим будет значение последней формы.

Как это работает?

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

$default_avatar = $_POST['form']['default_avatar'];

После отправки формы, переменная $default_avatar вернет значение установленное в форме соответственно.

3

Re: Создаем форму с чекбоксом для расширения

Честно сказать, до сих пор использую данный вариант проверки чекбоксов.

if (!isset($form['default_avatar']) || $form['default_avatar'] != '1')
$form['default_avatar'] = '0';

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

$form['default_avatar'] = (!isset($form['default_avatar']) || $form['default_avatar'] != '1') ? '0' : '1';

В данном условии если чекбокс будет пуст (не существует) или же не будет отмечен (равен 1), то скрипт вернет 0, в противном случае будет всегда 1.

4

Re: Создаем форму с чекбоксом для расширения

sempai,   PunBB_INFO_ICQ/thumbsup для страницы своих настроек это идеальный вариант. А для системных настроек это и вовсе не требуется. Минус один хук.