We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 26027
    • 145 Posts
    I have a Formit form prepared by a developer. It has a number of bells and whistles like hooks, thank you emails, and an anti-spambot honeypot field.

    I'm encountering a recent problem where a "hostile" is submitting mailing list requests where the email address is of the format "[email protected]".

    I want to create a custom validation that checks the field "email" to see if it contains the string "noreply" or "donotreply" and return "false" from the snippet. I'd like the hostile to think his request was honored so he'll walk away with a smirk on his face rather than hang around trying other bogus email addresses. I basically want to avoid a confirmation email being sent to our employee who handles these requests.

    I'm not all that good writing Formit code but I did some research that suggested I need a custom validation statement that identifies a processing snippet and another statement to associate the field being so validated with this snippet.

    Can someone point me to some tutorial that may provide an example of the required snippet code and its 'contains' clause and the syntax of the statements that define the presence of custom validation and the one that associated the field to the name of the snippet.

    Any help would be appreciated.

    Thanks ... Sam Gerber (samg)

    This question has been answered by Steeve. See the first response.

    • discuss.answer
      • 28432
      • 372 Posts
      Hi,

      You can make your own validators with Formit extra. You can find documentation here :
      https://docs.modx.com/extras/revo/formit/formit.validators#FormIt.Validators-CustomValidators

      Formit call example :
      [[!FormIt?
      ...
      ...
      &customValidators=`testEmail`
      ...
      ...
      &validate=`emailField:testEmail`


      Then you make a snippet named testEmail in my example with something like this inside :
      $email = $value;
      $findme   = 'noreply';
      $pos = strpos($email, $findme);
      
      if ($pos === false) {
         $success = false;
      } else {
          $success = true;
      }
      
      if ($success == false) {
        // Note how we can add an error to the field here.
        $validator->addError($key,'Email with noreply is not accepted ');
      }
        • 26027
        • 145 Posts
        Quote from: Steeve at Oct 26, 2016, 10:56 AM
        Hi,

        You can make your own validators with Formit extra. You can find documentation here :
        https://docs.modx.com/extras/revo/formit/formit.validators#FormIt.Validators-CustomValidators

        Formit call example :
        [[!FormIt?
        ...
        ...
        &customValidators=`testEmail`
        ...
        ...
        &validate=`emailField:testEmail`


        Then you make a snippet named testEmail in my example with something like this inside :
        $email = $value;
        $findme   = 'noreply';
        $pos = strpos($email, $findme);
        
        if ($pos === false) {
           $success = false;
        } else {
            $success = true;
        }
        
        if ($success == false) {
          // Note how we can add an error to the field here.
          $validator->addError($key,'Email with noreply is not accepted ');
        }

        Steeve, THANK YOU VERY MUCH! After a quick reading of your post it looks like you've spoon-fed me most everything I need to exercise my desired custom validation. I have a couple newbie questions beyond Formit re PHP coding.

        1. When I fall out of this routine, I'll need a return $success statement, yes? That's almost obvious but I'm not a PHP programmer so I'll ask you anyway.

        2. If I don't want to make the hostile human aware of the reason for my rejecting his request, can I simply return false (i.e. return $success) without an error message? If that won't work, can I fake a "Thank you for completing the form" and also return false, or will the return false prevent this message?

        3. If I want to also check for a second string such as "donotreply" in addition to "noreply" can you suggest the cleanest way to test for either string?

        4. As a final question, since I don't understand your if ($pos === false) test, it seemed to me that $pos is false if the string is NOT found, in which case $success would be true. I'm probably wrong but I needed to ask.

        Steeve, if I'm wasting your time by asking these additional newbie questions it's OK if you don't answer them. I'll get to my solution on my own from the significant assistance you've already provided me.

        Thanks again Steeve, especially for such a quick response.

        Best ... Sam Gerber
          • 28432
          • 372 Posts
          I'm glad my post helped you @samg !

          1. When I fall out of this routine, I'll need a return $success statement, yes? That's almost obvious but I'm not a PHP programmer so I'll ask you anyway.
          You do the same to with a success == true like this :
          if ($success == false) {
            // Note how we can add an error to the field here.
            $validator->addError($key,'Email with noreply is not accepted ');
          }else if($success == true){
            // Note how we can add an success to the field here.
            $validator->addError($key,'Good email ! ');
          }


          EDIT : This is wrong! The form with adderror is not submited. Sorry for this!

          Sorry i don't understand your second question (English is not my first language, i'm French).
          And i'm not a good PHP coder. You can learn a lot from PHP manual.

          3. If I want to also check for a second string such as "donotreply" in addition to "noreply" can you suggest the cleanest way to test for either string?
          $findme = array('noreply', 'donotreply', 'othertest');


          4. As a final question, since I don't understand your if ($pos === false) test, it seemed to me that $pos is false if the string is NOT found, in which case $success would be true. I'm probably wrong but I needed to ask.
          The pos PHP function definition is : Find the position of the first occurrence of a substring in a string.
          You can learn more in the PHP manual there :
          http://php.net/manual/en/function.strpos.php

          Steeve, if I'm wasting your time by asking these additional newbie questions it's OK if you don't answer them. I'll get to my solution on my own from the significant assistance you've already provided me.

          Thanks again Steeve, especially for such a quick response.
          That's the MODX community ;-) [ed. note: Steeve last edited this post 9 years, 11 months ago.]
            • 26027
            • 145 Posts
            Quote from: Steeve at Oct 27, 2016, 07:46 AM
            I'm glad my post helped you @samg !

            1. When I fall out of this routine, I'll need a return $success statement, yes? That's almost obvious but I'm not a PHP programmer so I'll ask you anyway.
            You do the same to with a success == true like this :
            if ($success == false) {
              // Note how we can add an error to the field here.
              $validator->addError($key,'Email with noreply is not accepted ');
            }else if($success == true){
              // Note how we can add an success to the field here.
              $validator->addError($key,'Good email ! ');
            }


            EDIT : This is wrong! The form with adderror is not submited. Sorry for this!

            Steeve, if I read this correctly, the form will not be submitted if we have a return false OR if we have a $validator addError statement, even if the return is true. Yes?

            3. If I want to also check for a second string such as "donotreply" in addition to "noreply" can you suggest the cleanest way to test for either string?
            $findme = array('noreply', 'donotreply', 'othertest');


            Thank you Steeve. This way of testing multiple tests is much better than anything I would have come up with!

            4. As a final question, since I don't understand your if ($pos === false) test, it seemed to me that $pos is false if the string is NOT found, in which case $success would be true. I'm probably wrong but I needed to ask.
            The pos PHP function definition is : Find the position of the first occurrence of a substring in a string.
            You can learn more in the PHP manual there :
            http://php.net/manual/en/function.strpos.php

            I think you're agreeing with me Steeve. If ($pos === false) in your example, I should set $success === true because no bad string was found and we want the form submitted. You accidentally had set $success === false if ($pos === false).

            I guess that's about it Steeve. I'll try out all your suggestions and see how I do.

            Thanks again ... Sam Gerber (samg)
              • 28432
              • 372 Posts
              Steeve, if I read this correctly, the form will not be submitted if we have a return false OR if we have a $validator addError statement, even if the return is true. Yes?
              True! The form will not be submitted.

              Thank you Steeve. This way of testing multiple tests is much better than anything I would have come up with!
              You're welcome!

              I think you're agreeing with me Steeve. If ($pos === false) in your example, I should set $success === true because no bad string was found and we want the form submitted. You accidentally had set $success === false if ($pos === false).
              You're right!

              I guess that's about it Steeve. I'll try out all your suggestions and see how I do.

              Thanks again ... Sam Gerber (samg)
              You're welcome! Again!

              If it's alright for you, can you put the post to answered ?
                • 26027
                • 145 Posts
                Quote from: Steeve at Oct 28, 2016, 03:42 AM

                You're welcome! Again!

                Steeve, if you're still following this thread, I need to run something by you. I tested my customer validator and it should have rejected the form but instead it let it go through. I'm sure I have some syntax problem or logic problem. I'll try to be a brief as possible here.

                First, here are my 2 statements in the Formit call:

                [[!FormIt?
                &emailSubject=`Request from ELC Join Our Network Form`
                &customValidators=`filter.noreplyaddresses`
                &validate=`nospam:blank,name:required,email:email:required:filter.noreplyaddresses`
                &successMessage=`<style>#joinournetwork{display:none;}</style><h3>THANK YOU!</h3><p>Your information was successfully submitted.</p>`


                Is it OK to name the validator snippet as I did? Also, if I'm performing 3 tests on the 'email;' field, is it OK to do it the way I did it? That is by using the colon 3 times in email:email:required:filter.noreplyaddresses.

                Finally I'd like to show you my snippet, filter.noreplyaddresses.

                <?php
                /* reject email addresses containing noreply, donotreply */
                $email = $value;
                if (strpos($email, 'noreply') !== false || strpos($email, 'donotreply') !== false) {
                      return false; 
                } 
                else {
                return true;
                }
                


                I used your example when I wrote $email = $value;

                I basically didn't understand why I wrote this. In looking back at it it looks like I'm changing the email form's value to whatever was in the $value filed which was probably null. Did I actually set my 'email' field to blanks or null? Should I have eliminated the statement $email = $value;?

                I guess that's it, Steeve. When I tested the form I used an email address of [email protected].

                Sorry to burden you with this but I didn't want to start a new thread.

                Thanks for any further help ... Sam [ed. note: samg last edited this post 9 years, 11 months ago.]
                  • 28432
                  • 372 Posts
                  Quote from: samg at Oct 28, 2016, 04:51 PM
                  Quote from: Steeve at Oct 28, 2016, 03:42 AM

                  You're welcome! Again!

                  Steeve, if you're still following this thread, I need to run something by you. I tested my customer validator and it should have rejected the form but instead it let it go through. I'm sure I have some syntax problem or logic problem. I'll try to be a brief as possible here.

                  First, here are my 2 statements in the Formit call:

                  [[!FormIt?
                  &emailSubject=`Request from ELC Join Our Network Form`
                  &customValidators=`filter.noreplyaddresses`
                  &validate=`nospam:blank,name:required,email:email:required:filter.noreplyaddresses`
                  &successMessage=`<style>#joinournetwork{display:none;}</style><h3>THANK YOU!</h3><p>Your information was successfully submitted.</p>`


                  Is it OK to name the validator snippet as I did? Also, if I'm performing 3 tests on the 'email;' field, is it OK to do it the way I did it? That is by using the colon 3 times in email:email:required:filter.noreplyaddresses.

                  I never tried to name validator like this (with a dot). Maybe it's better to try camel name style like this : filterNoReplyAddress. It's maybe better to put your custom validator before required filter :
                  email:email:filter.noreplyaddresses:required
                  Quote from: samg at Oct 28, 2016, 04:51 PM


                  Finally I'd like to show you my snippet, filter.noreplyaddresses.

                  <!--?php
                  /* reject email addresses containing noreply, donotreply */
                  $email = $value;
                  if (strpos($email, 'noreply') !== false || strpos($email, 'donotreply') !== false) {
                        return false; 
                  } 
                  else {
                  return true;
                  }
                  


                  I used your example when I wrote $email = $value;

                  I basically didn't understand why I wrote this. In looking back at it it looks like I'm changing the email form's value to whatever was in the $value filed which was probably null. Did I actually set my 'email' field to blanks or null? Should I have eliminated the statement $email = $value;?

                  It's just to be more readable by human. I prefer to know i test an email variable than to test a value variable. But you can eliminate this line and change all $email to $value. $value contain the value applied by the filter.
                  For more example : https://docs.modx.com/extras/revo/formit/formit.validators#highlighter_595530
                  Quote from: samg at Oct 28, 2016, 04:51 PM


                  I guess that's it, Steeve. When I tested the form I used an email address of [email protected].

                  Sorry to burden you with this but I didn't want to start a new thread.
                  No problemQuote from: samg at Oct 28, 2016, 04:51 PM


                  Thanks for any further help ... Sam-->
                  You're welcome
                    • 26027
                    • 145 Posts
                    Quote from: Steeve at Oct 29, 2016, 03:40 AM
                    Quote from: samg at Oct 28, 2016, 04:51 PM
                    Quote from: Steeve at Oct 28, 2016, 03:42 AM

                    You're welcome! Again!

                    Steeve, if you're still following this thread, I need to run something by you. I tested my customer validator and it should have rejected the form but instead it let it go through. I'm sure I have some syntax problem or logic problem. I'll try to be a brief as possible here.

                    First, here are my 2 statements in the Formit call:

                    [[!FormIt?
                    &emailSubject=`Request from ELC Join Our Network Form`
                    &customValidators=`filter.noreplyaddresses`
                    &validate=`nospam:blank,name:required,email:email:required:filter.noreplyaddresses`
                    &successMessage=`<style>#joinournetwork{display:none;}</style><h3>THANK YOU!</h3><p>Your information was successfully submitted.</p>`


                    Is it OK to name the validator snippet as I did? Also, if I'm performing 3 tests on the 'email;' field, is it OK to do it the way I did it? That is by using the colon 3 times in email:email:required:filter.noreplyaddresses.

                    I never tried to name validator like this (with a dot). Maybe it's better to try camel name style like this : filterNoReplyAddress. It's maybe better to put your custom validator before required filter :
                    email:email:filter.noreplyaddresses:required
                    Quote from: samg at Oct 28, 2016, 04:51 PM


                    Finally I'd like to show you my snippet, filter.noreplyaddresses.

                    <!--?php
                    /* reject email addresses containing noreply, donotreply */
                    $email = $value;
                    if (strpos($email, 'noreply') !== false || strpos($email, 'donotreply') !== false) {
                          return false; 
                    } 
                    else {
                    return true;
                    }
                    


                    I used your example when I wrote $email = $value;

                    I basically didn't understand why I wrote this. In looking back at it it looks like I'm changing the email form's value to whatever was in the $value filed which was probably null. Did I actually set my 'email' field to blanks or null? Should I have eliminated the statement $email = $value;?

                    It's just to be more readable by human. I prefer to know i test an email variable than to test a value variable. But you can eliminate this line and change all $email to $value. $value contain the value applied by the filter.
                    For more example : https://docs.modx.com/extras/revo/formit/formit.validators#highlighter_595530
                    Quote from: samg at Oct 28, 2016, 04:51 PM


                    I guess that's it, Steeve. When I tested the form I used an email address of [email protected].

                    Sorry to burden you with this but I didn't want to start a new thread.
                    No problemQuote from: samg at Oct 28, 2016, 04:51 PM


                    Thanks for any further help ... Sam-->
                    You're welcome

                    No cigar for me, Steeve! I'm obviously doing something wrong but have no clue what it is.

                    Once I understood that it was OK to have "$email = $value", I left it in.

                    I changed "filter.noreplyaddresses" to "filterNoReplyAddresses" as you suggested.

                    I changed the order of the filters to "email:email:filterNoReplyAddresses:required".

                    None of this mattered. Sigh!

                    Thanks, Steeve, for all your suggestions.
                      • 28432
                      • 372 Posts
                      You still have a problem with it ?