• Resolved sacconi

    (@sacconi)


    I’m used up to now to sanitize text areas and simple text fields, but the following for a checkbox doesnt work:

    update_user_meta( $user_id, '6_checkbox', sanitize_text_field( $_POST['6_checkbox'] ) );

    The page I need help with: [log in to see the link]

Viewing 15 replies - 1 through 15 (of 25 total)
  • For checkboxes, you should use sanitize_key() instead since checkbox values are typically simple on/off values. Here’s the correct way to sanitize a checkbox in the user meta update:

    update_user_meta( $user_id, '6_checkbox', sanitize_key( $_POST['6_checkbox'] ) );

    This works better because sanitize_key() is designed for simple values and will:

    • Convert to lowercase
    • Remove all non-alphanumeric characters
    • Perfect for checkbox values that are typically ‘1’, ‘on’, or empty
    Thread Starter sacconi

    (@sacconi)

    Unluckily the checkbox doesnt remain checked after I save the work…

    Moderator threadi

    (@threadi)

    According to WordPress coding standards, this would at least be the correct spelling:

    if( isset( $_POST['6_checkbox'] ) ) {
    update_user_meta( $user_id, '6_checkbox', absint( wp_unslash( $_POST['6_checkbox'] ) ) );
    }
    else {
    delete_user_meta( $user_id, '6_checkbox' );
    }

    Background:
    It is always necessary to check whether a variable is set in the request.
    It is always necessary to secure incoming values with wp_unslash().
    I would definitely recommend using a numerical value for checkboxes (there is no yes/no as a value), so I would also definitely recommend securing the incoming value with absint().

    The above code has not been tested by me, but would be syntactically correct. If this does not work for you, check by debugging (e.g. with var_dump() and exit;) whether the checkbox with this name exist in the request at all. This may tell you why it is not saved.

    Thread Starter sacconi

    (@sacconi)

    I changed something in my html

    <input type="checkbox" name="6" id="6" value="yes"<?php echo esc_attr( get_the_author_meta( '6', $user->ID ) ); ?>" class="regular-price" />

    and used

    if( isset( $_POST['6'] ) ) {
    update_user_meta( $user_id, '6', absint( wp_unslash( $_POST['6'] ) ) );
    }
    else {
    delete_user_meta( $user_id, '6' );
    }

    but it doesnt work

    Moderator threadi

    (@threadi)

    This is also not possible for several reasons:

    • IDs that begin with numbers and consist only of these are not permitted in HTML. Rename both the ID and the name attribute, e.g. to ‘field_6’.
    • Your value attribute has the value “yes” and not just a “1” as I intended above. If you want to stick with this, you have to adapt the storage and sanitize a string value, i.e: update_user_meta( $user_id, '6', sanitize_text_field( wp_unslash( $_POST['field_6'] ) ) );
    • Your HTML is still incorrect. You simply want to output the stored value from the field, but this does nothing (it would just print ‘yes’ which means nothing in HTML). In HTML, checkboxes with the checked attribute are marked as checked. See Basics: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox – in addition, you have an extra double quotation mark after this output, which means that the entire HTML code is no longer valid and can lead to incorrect output.
      You would therefore have to adapt your HTML code accordingly:
    <input type="checkbox" name="field_6" id="field_6" value="yes"<?php echo ( 'yes' === get_user_meta( $user->ID, '6' ) ? ' checked' : '' ); ?> class="regular-price" />
    Thread Starter sacconi

    (@sacconi)

    ok, I did

    <input type="checkbox" name="checkbox_6" id="checkbox_6" value="checkbox_6"<?php echo esc_attr( get_the_author_meta( 'checkbox_6', $user->ID ) ); ?>" class="regular-price" />

    and

    if( isset( $_POST['checkbox_6'] ) ) {
    update_user_meta( $user_id, 'checkbox_6', absint( wp_unslash( $_POST['checkbox_6'] ) ) );
    }
    else {
    delete_user_meta( $user_id, 'checkbox_6' );
    }

    the first code is inside a longer code, I can see correclty the checkbox, but also this combination doesnt work

    Moderator bcworkz

    (@bcworkz)

    The PHP within your input field is not accomplishing what you want. You probably need to conditionally echo out checked only when the user meta exists? You could use a ternary construct for this:
    <?php echo empty( get_the_author_meta( 'checkbox_6', $user->ID )) ? '' : ' checked'; ?>

    Because the checkbox value is “checkbox_6”, when your update/delete code executes, $_POST[‘checkbox_6’] will have that value. It thus makes no sense to use absint() in such a case. To use absint(), the checkbox value ought to be 1.

    Moderator threadi

    (@threadi)

    Please also take another look at my answer. You have obviously not implemented any of the tips so far.

    Thread Starter sacconi

    (@sacconi)

    @bcworkz I tryed this combination, without effect

    <input type="checkbox" name="checkbox_6" id="checkbox_6" value="checkbox_6"<?php echo empty( get_the_author_meta( 'checkbox_6', $user->ID )) ? '' : ' checked'; ?>" class="regular-price" />
    update_user_meta( $user_id, 'checkbox_6', sanitize_key( $_POST['checkbox_6'] ) );

    @threadi I’ll study better your answer

    Moderator bcworkz

    (@bcworkz)

    The quote in ?>" class= does not belong, please remove it.

    Instead of deleting the user meta record when the box is unchecked, I advise updating the record to false or 0.

    When you base the check box status (checked or unchecked) with get_the_author_meta(), due to a race condition the status might not be reflected when the form is submitted and reloaded. For the check box to reflect the intended status, you should base the lack of the checked attribute upon author meta OR the $_POST[‘checkbox_6’] value being empty.

    Thread Starter sacconi

    (@sacconi)

    The checkbox now stays checked, but how can I traduce in code your advice? Actually I have a related problem here in this topic : https://ww.wp.xz.cn/support/topic/adding-a-conditional-if-a-check-box-is-checked/ that confirms what you were saying, it seems the system is not sensible to the change of status when I check or uncheck and save

    Moderator bcworkz

    (@bcworkz)

    My thought was this:
    <?php echo empty( get_the_author_meta( 'checkbox_6', $user->ID )) || empty( $_POST[‘checkbox_6’]) ? '' : ' checked'; ?>

    Untested though. I have trouble with compound negative logic. It may be we need && instead of ||. Try both, see which works better 🙂

    It’s not that the system is not sensible to change, it’s more like the system cannot save, then retrieve the desired value fast enough. PHP executes faster than the DB can write data. It’s what programmers call a race condition. With the existing code without the additional logic, even if the checkbox does not initially reflect the right choice, if you reloaded the page, the correct choice will be shown because the DB has had time to write the selection.

    Thread Starter sacconi

    (@sacconi)

    maybe with new above string I have to change the sanitize/save code? The current one is no more working, now I have

    update_user_meta( $user_id, 'checkbox_6', sanitize_key( $_POST['checkbox_6'] ) );
    Moderator bcworkz

    (@bcworkz)

    I don’t think that’s the problem. Apparently my complex logic idea doesn’t work with the ternary operator. Or I’m doing it wrong. We can use the longer form if/else logic. And my suspicion was right about negative logic, we want “empty this AND empty that” logic, not “empty this OR empty that”. The latter makes sense to me in spoken language, but it doesn’t work for computer logic. This appears to work for the check box field:

    <?php if ( empty( get_the_author_meta( 'checkbox_6', $user->ID )) && empty( $_POST['checkbox_6'])) {
        $state = ''; 
     } else { 
        $state = 'checked';
     }
     ?> 
    <input type="checkbox" name="checkbox_6" id="checkbox_6" value="checkbox_6" <?php echo $state; ?> class="regular-price" />
    Thread Starter sacconi

    (@sacconi)

    I used the above code but I think I should correct also the following:

    $checkbox_status = get_the_author_meta($post->ID, 'checkbox_6', true);
    .......
    if ( ! empty( trim( $discount_post ) ) && empty($checkbox_status) ) {

    because at the moment checked or unchecked gives me the same result

Viewing 15 replies - 1 through 15 (of 25 total)

The topic ‘Sanitizing a checkbox’ is closed to new replies.