XF 2.1 How could you set a Xenforo option to uncheck or deselect after being checked and saved?

Brad Padgett

Well-known member
Hey I'd like to add a reset count option to my [BP] Most Ever Online add-on. I'm trying to set it up so that the checkbox option is unchecked after checking and clicking save. This is because the specific option is for resetting the most ever online counts and if it stayed checked it wouldn't be appropriate.

How could I go about this? Is there some way you can setup the option itself to do this? Or can someone give me a short example of how I can add something to my function to achieve this?

Thanks if you can help.
 
Can anyone help with this? I asked this a long time ago in several old threads and no one replied. As far as I'm concerned all I have to do is set a Boolean on the option but I can't figure out how to use the Boolean in my code to uncheck it if it's selected. Here's the thread I was talking about:

 
This is my function. I've tried a combination of true and false and 0 and 1. Nothing seems to work. However I noticed that if I do it the other way around, where I'm targetting the 1 value what it will do is work the opposite way. For example when I do it the other way around and when deselecting the option stays selected. If I add my code for the opposite way it will proceed with diselecting. So I'm doing something right I know that. It's just a matter of how I can get it to work with unselecting upon saving or the 0 and false way. Here's my function

PHP:
public static function reset()
{

    $options = \XF::options();
    $app = \XF::app();


    if ($options->bp_reset_counts) {

        $app->simpleCache()->getSet('BP/MostEverOnline')->setValue('total_count', 0);
        $app->simpleCache()->getSet('BP/MostEverOnline')->setValue('guest_count', 0);
        $app->simpleCache()->getSet('BP/MostEverOnline')->setValue('member_count', 0);
        $app->simpleCache()->getSet('BP/MostEverOnline')->setValue('total_time', null);
        $app->simpleCache()->getSet('BP/MostEverOnline')->setValue('guest_time', null);
        $app->simpleCache()->getSet('BP/MostEverOnline')->setValue('member_time', null);

}
        if ($options->bp_reset_counts == '1') {
            return '0';
        }


    return true;

}

Now I know there's a better way to do that last part or the correct way regardless but I'm not sure what I'm missing here. As I said it works the other way around when your targetting the 1. For example if I did this


if ($options->bp_reset_counts == '0') { return '1'; }


If I did that I noticed you could deselect the option and it would stay that way. Without it however the option stays selected. So it's sort of working backwards here.

I also want to add that I added a validation call back in the option area as I was vaguely instructed by @Chris D to do so in a different thread months ago.
 
Last edited:
$options->bp_reset_counts == '1'
That condition is equal to simply $options->bp_reset_counts.

I'm honestly not a friend of slaughtering checkboxes into functionality like that, I'd rather make it a button somewhere else, but if you want to go down that route, extend XF\Admin\Controller\Option and check on save there if your value is available and set, then unset it and do your thing.

If you want to go the extra mile and do it in a - imo - more user friendly way, create your own route and controller, make the option a template, have that template display a button that triggers your controller and do your thing there. That way you can also display a confirmation popup before you irreversibly delete data.
 
Last edited:
That condition is equal to simply $options->bp_reset_counts.

Yeah I was aware just trying anything little thing that might work since google wasn't much help.

I'm honestly not a friend of slaughtering checkboxes into functionality like that, I'd rather make it a button somewhere else, but if you want to go down that route, extend XF\Admin\Controller\Option and check on save there if your value is available and set, then unset it and do your thing.

Your sure that extending a class is required? If so I don't mind taking the extra step just wanted to verify this is the only way. Either way that seems to be the right place for me to look for any methods that might help me. Thanks
 
@Lukas W. any idea what method I'm looking for? I know you most likely didn't mean create an actual class extension out of that file. I could use some methods from it though without doing that I suppose which would probably work. I don't think creating a class extension by any means would be required for unticking a checkbox. If so please correct me so I can understand what you meant.
 
Also @Lukas W. just noticed your post edit. Yes I could do that but this is an add-on that has already been released and I'd like to keep everything grouped together and not separated. Otherwise users won't know exactly what to look for or might get confused. I just added a date format option based on the php date function letters and also a forum statistics position. Those have already been completed. The last thing is this checkbox unticking which shouldn't be too difficult but haven't figured it out yet. To be honest, I think the format parameters are the part I don't know about. I suppose it must take more by the way you have said I should look into that option file.

Let me know if you have an example or any idea of the method I should locate. I will evaluate the php file shortly
 
I also want to add that I added a validation call back in the option area as I was vaguely instructed by @Chris D to do so in a different thread months ago.
This is the correct thing to do, but if the code you demonstrated above is what you're using, then it doesn't really work like that.
PHP:
public static function verifyOption(&$value, \XF\Entity\Option $option, $optionId)
{
    $value = 0;
    return true;
}
First, validation functions take a number of arguments which make this easier. You get access to the actual value which is passed by reference (because it is prefixed with an &) which means that changes to that variable overwrite the variable in the function that called it.

Therefore, the above code would set the value to 0, even though if it is checked, it would be originally set to 1.

Second, because it is a verification option, it must return true or false. You do not return the value you want the option to be. You return whether the value set is valid, or not. In your case, you will most likely always want this to return true.

To expand slightly, you likely want something like this:

PHP:
public static function verifyOption(&$value, \XF\Entity\Option $option, $optionId)
{
    if ($value) // option is checked
    {
        $value = 0; // option is now unchecked
        // do your reset here
    }
    return true;
}
 
If you always want the checkbox to be unchecked when the page loads (i.e. you don't care what the value was previously saved as because you simply run your reset code upon a checked box and do not use that option value anywhere else), then you could just use a template modification to check for your option ID and then uncheck the box.
This obviously is not as clean or as flexible as extending the options or even creating your own ACP section for your add-on, but if I understood you correctly this is all you want since the rest of your code works and you do not wish to rewrite it?
 
This is the correct thing to do, but if the code you demonstrated above is what you're using, then it doesn't really work like that.
PHP:
public static function verifyOption(&$value, \XF\Entity\Option $option, $optionId)
{
    $value = 0;
    return true;
}
First, validation functions take a number of arguments which make this easier. You get access to the actual value which is passed by reference (because it is prefixed with an &) which means that changes to that variable overwrite the variable in the function that called it.

Therefore, the above code would set the value to 0, even though if it is checked, it would be originally set to 1.

Second, because it is a verification option, it must return true or false. You do not return the value you want the option to be. You return whether the value set is valid, or not. In your case, you will most likely always want this to return true.

To expand slightly, you likely want something like this:

PHP:
public static function verifyOption(&$value, \XF\Entity\Option $option, $optionId)
{
    if ($value) // option is checked
    {
        $value = 0; // option is now unchecked
        // do your reset here
    }
    return true;
}

This community and your support really encourages me quite a bit to get good at this stuff. I really appreciate you taking the time to write that. After examining the source code for some time it doesn't seem at all that it would ever be too difficult to even master at some point. I've come to realize that it's not a difficult venture whatsoever it just takes practice.

I will definitely proceed to set this up shortly. Like I said everything else seems to be working properly without any issues. It was just that one thing I couldn't figure out. And also I knew the code above I posted (except for the reset area) was no good I was just trying to post an example so you guys could work with something in your reply.

Thank you.

If you always want the checkbox to be unchecked when the page loads (i.e. you don't care what the value was previously saved as because you simply run your reset code upon a checked box and do not use that option value anywhere else), then you could just use a template modification to check for your option ID and then uncheck the box.
This obviously is not as clean or as flexible as extending the options or even creating your own ACP section for your add-on, but if I understood you correctly this is all you want since the rest of your code works and you do not wish to rewrite it?

Hey I am also checking for the option ID in the template as well. I basically usually always run a check in the php file and also in the template but there's no direct template code I've seen that would achieve the same thing though I'm sure it's possible. Feel free to share for information purposes for any user that had the same question if you wish to. Either way is fine. I haven't tried the template method either.
 
Top Bottom