Ignore option instead of showing error when verifying an option

rugk

Active member
When I return "false" when verifying an option XenForo always shows a generic error even I did not manually added an error message to the DataWriter (via $dw->error).

How can I make it to ignore the change without an error and do not change this option, but just "skip it"?
 
If you're verifying an option you need to return true or false. False would throw an error. True wouldn't error, but also it would save the changes.

I'm unsure if there'd be a way of reverting back to the original value... I guess it would be something like:
PHP:
$dw->set('option_value', $dw->getExisting('option_value'));
return true;
Though, really, I haven't tested it (or given it much thought :p) so proceed with caution ;)

EDIT: Probably worth noting that silently not changing an option like this is probably quite an unexpected behaviour for an end user to experience so it's not ideal... are you sure you need to approach it like that?
 
are you sure you need to approach it like that?
Yes, I am, because I modify the option before it is displayed to the user and even if the user just clicks okay without changing this value it is of course detected as changed. That's why I check in my verify part whether the options was indeed changed by the user (and is not my modified one), so that I can skip the change when it is not changed by the user.
 
So your solution does not work. It sets ' _newData' => 'xf_option' to an empty string instead of the previous value (which is correctly returned by "getExisting").
Code:
  protected '_newData' =>
    array (size=1)
      'xf_option' =>
        array (size=0)
          empty

"$dw->set" still returns true BTW, but it does not seem to set the data correctly.
 
@rugk you need to be more clear on what you actually want done. Is your "default" value being sent to the data writer? If it is, then isChanged will always be set to true, as the existing data will be different. Even setInternal would not work. If your default data is not sent to the data writer, try $dw->setInternal('field', 'data') (this does not validate the data sent, only checks to see if it is different, if it is not different, the key is unset from the data writer (which sounds like you want?)).

Personally a controller should be handling this, in my opinion, and let it check to see if the submitted value did change.
 
I would prefer the internal mode, but unfortunately setInternal is not available. There is only "_setInternal", but this is a protected function.

But BTW: Validation should not be an error as my data type is correct (I pass a string to $dw->set and my option is also set to accept strings), but as it seems $dw->set does not work.
 
I would prefer the internal mode, but unfortunately setInternal is not available. There is only "_setInternal", but this is a protected function.

But BTW: Validation should not be an error as my data type is correct (I pass a string to $dw->set and my option is also set to accept strings), but as it seems $dw->set does not work.

I recalled reading up on _setInternal when I looked something up in the datawriter abstract class, and it just stuck with me.

I still think this should be handled by a controller, as _preSave will either return false (throw the error), or return true (save the field, which you do not want). If the datawriter is custom (you are not extending an existing one) you could just remove the _preSave function from your datawriter, but that's not recommended as it is there for a good reason.
 
FWIW, I think my idea should work (with a small tweak) now I looked at it properly.

I forgot that $option was passed by reference, so presumably my original idea falls over because after verification the $dw uses the value of $option to set the option_value, hence using $dw->set there won't have any effect.

This should work (and in my testing, does):
PHP:
$option = $dw->getExisting('option_value');
return true;
 
I tried @Chris D solution and it worked. Indeed it is passed as a reference - I should have sawn this. :)
@Lawrence Yes probably with a controller this may be a more "clean" solution, but it is unnecessary complex to do this especially if you want to do it for multiple options.
So just setting the value (back) to the existing one is a simple and nice solution, which only requires a few code lines for such a small "feature".

But everyone thanks for the help.
 
Last edited:
Thanks for the question @rugk , it is a good one that made me think. And @Chris D, more importantly thanks for the answer, one I am sure I'll be using on my current endeavour, :)
 
Back
Top Bottom