1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Ignore option instead of showing error when verifying an option

Discussion in 'XenForo Development Discussions' started by rugk, Feb 25, 2016.

  1. rugk

    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"?
  2. Chris D

    Chris D XenForo Developer Staff Member

    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:
    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?
  3. rugk

    rugk Active Member

    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.
  4. rugk

    rugk Active Member

    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").
      protected '_newData' =>
        array (size=1)
          'xf_option' =>
            array (size=0)
    "$dw->set" still returns true BTW, but it does not seem to set the data correctly.
  5. Lawrence

    Lawrence Well-Known Member

    @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.
  6. rugk

    rugk Active Member

    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.
  7. Lawrence

    Lawrence Well-Known Member

    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.
  8. Chris D

    Chris D XenForo Developer Staff Member

    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):
    $option $dw->getExisting('option_value');
    Lawrence likes this.
  9. rugk

    rugk Active Member

    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: Feb 26, 2016
    Chris D likes this.
  10. Lawrence

    Lawrence Well-Known Member

    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, :)

Share This Page