Is there an easy way to say "If this text field has a url, don't allow submission"?

I would like to have a feature that if the message contains a link the form gives out an error saying “This field cannot contain links” to avoid spam links.

  • Adam Czajczyk
    • Support Gorilla

    Hi minty_hunter

    I hope you’re well today and thank you for your suggestion!

    For now, the “visibility/conditional logic” solution that was suggested during the chat should do the job quite well, I believe.

    I think, however, that having some “additional custom validation options” there – so you could set some “rules” for each field regardless of conditional logic; for actual form validation – could indeed be quite a handy tool so I’ve passed that idea to our Forminator team already so they’d look into it :slight_smile:

    Best regards,

    Adam

    • Tony G
      • Mr. LetsFixTheWorld

      Adam Czajczyk – I’m thinking this could be done with a hook, where on lost-focus of a field, custom code is executed to check the values of any field in the form.

      I haven’t looked, sorry, but is the server aware of client-side events like has-focus or lost-focus? I think it is because the visibility triggers work, but I don’t know if that’s all in the client or if there is a postback to the server. And if we do get a postback, can we use filters to then change the state of fields in the client-side form?

      If we can do that then all kinds of new things are possible … a lot of hardcoded tweaks in the back-end are no longer required.

  • minty_hunter
    • Flash Drive

    A little context around this:

    Honeypot doesn’t always stop spam, and captcha can be a PITA and adds another layer of stuff for site visitors to have to grind through just to leave a message.

    In many cases, spam submissions contain links in the message field.

    So, if there was a simple checkbox to say “Don’t allow links” in a field, and it was part of the submission process (ie: spits an error that says “This field cannot contain links”, in the same way it might say “This is not a valid email address”:wink:, then it could prevent most spam while making legit entries as simple as possible.

    For now, I’m going to try the chat suggestion: adding a visibility rule to the submission button that hides it if the message field contains “http”. I’ve also added a line in the message field description setting to say that it can’t contain http, just in case a legit person for some reason tries it.

  • Tony G
    • Mr. LetsFixTheWorld

    Today the request is to filter “http” but tomorrow it will be “mailto”, or “sftp” or any number of a list of prohibited words. Rather than hardcoding a checkbox on text fields, we would get infinitely more mileage from a hook where we can filter Any field for Any content.

    What about restricting dates to weekdays that aren’t local holidays?

    What about time fields that are different depending on the day of the week requested in a date field?

    What about email addresses where we want to dynamically validate a domain?

    What about entry of a domain name where we need to verify that there is a domain plus TLD?

    What about compelling passwords that match specific strength criteria?

    What about regex?

    What about limiting a quantity ordered to an available quantity which can’t be hardcoded into a form definition?

    There are any number of valid field validations and there’s no way that DEV is going to process all of them. You’re going to forever be considering new requests, feeling bad about rejecting some, and taking months to process the accepted ones. Why create that scenario unnecessarily?

    Consider, this is what ALL GUI IDEs do – you change a field, you get a change event, and you handle it with code. Where in the world do we ever see a GUI development tool selectively restricting specific field types to hardcoded values? I understand Forminator isn’t classified as a GUI IDE, but there’s no reason for it not to be in this regard – it’s moving in that direction, seemingly without DEV intending it to do so. There are many benefits of putting more power into the hands of users with actions and filters. One of which is that long-term coding at DEV is much easier and less costly, with much less need to consider and process every request for some new hardcoded change – like a checkbox to restrict the text “http”.

    BTW, the text that should be filtered is “http://” and “https://” … otherwise a simple note about an http server would be considered invalid.

    • minty_hunter
      • Flash Drive

      Tony, I understand what you’re saying (and I would be pleased to see hooks too!), but here’s the thing:

      A large swathe of users don’t want to have to read up on hook documentation and then work out how code (and test!) a call. They deal with broader issues: “Can I make it easy for users/visitors to provide the feedback/message/info in this form, while not having to deal with spam?”

      In most cases, that will not include users who want to start talking about http servers. The majority of entries that have http in a message field are spam.

      You could get infinitely more mileage from a car powered by a fusion reactor. It might even open up the ability to make the car fly… as long as you don’t mind engineering wings and stabilisation and advanced braking etc. But if your issue is that most of the time, you just need an extra few miles, then pressing a button marked ‘eco’ might just do the trick: large return for minimum effort.

      And yeah, I could just turn on captcha… as long as I don’t mind dealing with the changes Google’s made to move to v3, and the burden it puts on every single legit visitor to prove they’re legit… that’s why I’m suggesting a checkbox to stop http being valid as an option to allow a single backend click to have the greatest impact across the widest range of users, and possibly the widest range of web devs using Forminator :slight_smile:

      • Tony G
        • Mr. LetsFixTheWorld

        Thanks for the cordial exchanges. :slight_smile: I really do understand you. But as a developer I also understand the consequences of implementing “what you’re asking for versus what you want”. Our friends at DEV take requests very literally sometimes, and that’s not always the best interpretation.

        I’d suggest that to accomplish your goals, you’re looking for a spam-free textbox, not one that specifically eliminates hardcoded text. There are a huge number of ways to spam a text box other than with the text “http”. As soon as you check the new box you asked for here, and a spammer hits your site with something other than “http”, you’re going to come back here and ask for another feature to handle that vector. Let’s address this earlier rather than later.

        To use your vehicle analogy, a single button does a single thing. This is more like the radio : don’t hardcode 91.5FM onto the first button, give me a set of buttons and let me set whatever radio station I want to them, even if I do want that first button to be 91.5FM. You’re right – this isn’t rocket science. :slight_smile:

        If DEV implements field-level hooks, then we all win. They can then hook on that themselves with a function that handles spam validation. We can also hook on that for anything else. They benefit from the feature as much as anyone else. If they hardcode spam handling in-line, where a filter would otherwise call out, we get spam handling but nothing more. Also, they should further hook their own spam handling so that we can override what they do if they botch it. If their idea of spam handling is to only check for the literal text “http”, and we know that’s not enough, we should be able to create a filter that replaces their filter with something we like better. One example would be to pass the text through to Akismet just like any post comment. Now wouldn’t that really be the best solution to the problem you pose? In all of this, you can still get exactly what you’re asking for, the “http” text filter” and I’m sorry if you find that what you’re asking for is ultimately not going to get you what you want. I’m suggesting a mechanism that will really get what you want, true spam filtering, regardless of who provides it.

        This is the WordPress way of doing things. I wrote another thread here somewhere about WPMU DEV making better use of this model, truly “wordpressifying” all of their plugins using the tools that are available, specifically the hook functionality. They’ve done this to some extent, but to paraphrase Spock in Star Trek: The Wrath of Khan, their developers are often still thinking very 2-dimensionally in a 3-dimensional universe.

        • minty_hunter
          • Flash Drive

          Tony, as I said, by all means let’s have hooks.

          But I don’t want to have to build into a hook for every damn bit of functionality. If restricting http gives me 90% success with defeating spam, give me that checkbox and the two seconds it takes to turn it on.

          Sure, maybe spammers will come up with something other than http… but I haven’t seen that yet. And again, if 90% of them can’t be bothered going the extra mile to do that, it’s still a win.

          Both you and Kasia Swiderska suggested Akismet. Which is fine, except it’s another plugin, another processing load as it sends stuff to their servers, and not free for anything other than “personal blogs”.

          “I’m suggesting a mechanism that will really get what you want, true spam filtering”.

          That’s actually not true. I’m looking for a low-hanging fruit answer, a “least effort for maximum gain”. Akismet and/or tying into hooks comes with a specific set of costs (financial/setup/performance etc). Captcha comes at the cost of visitor unfriendliness and vulnerability to sudden Google changes (eg: the recent c3 debacle).

          A checkbox costs me a few seconds to decide to use, is not complex to implement (especially compared to offering and testing a full hook api) and will have a large impact.

          That’s why I’m asking for it.

          • Tony G
            • Mr. LetsFixTheWorld

            I hear you. Again, thanks for the exchanges. As a business owner I agree, going for the low hanging fruit is preferable to asking for something too complex. I also agree about Akismet. I’m only disagreeing with your code level request for how you/we get that functionality.

            If we’re going to ask Dev to do something, let’s always do so in a way that gets them and us much more bang for the same buck. I understand you’re just asking for a checkbox. I’m trying to convey that the time for the UI change and the live check for “http” seems like nothing to you, but there is a cost to implement that change, and we collectively aren’t getting equitable return value for that, for all of the reasons I’ve provided.

            Why is that important? We’ve learned that when Dev is overloaded with requests that their go-to solution is to lighten the load, and reduce the number of requests by reducing the number of plugins in their portfolio. We’ve all recently lost a lot of great plugins. TWICE! I personally attribute that to them being overwhelmed with trying to please everyone with one off requests like this, rather than retrofitting their plugins with hooks so that others can build upon their core. When they try to please everyone, they fail, they make tough decisions, everyone suffers… again, so far, TWICE. Let’s help them to avoid that pain (and avoid passing that pain on to us, again) by offering them better requests which lead to better long-term results for all of us.

            A compromise here could be that Dev could implement hooks with a couple trivial lines of code. Then they can publish about 10 lines of code to paste into functions.php that implements the hook using nothing but a check for “http”. You can edit that in, at no cost, quickly, and you will get exactly what you want without Dev having to create a one shot UI change. There will be less code involved, so no hit on performance. People who choose not to use your feature or the hook will have better performance than if every site is hardcoded with a feature that is not being used. Further, Dev no longer needs to hardcode anything here, they can simply enhance the published function, and others can as well. In fact, this can easily integrate with any anti-spam plugin to provide significant protection beyond the simple text. You’re asking for low hanging fruit but there’s no reason we can’t get that now and then soon afterward get the entire tree for free.

          • minty_hunter
            • Flash Drive

            Hey Tony,

            I admire your passion but I feel like this simple request is getting drowned.

            ” I personally attribute that to them being overwhelmed with trying to please everyone with one off requests like this”

            That’s a big assumption. Perhaps they struggled instead wading through massive comments on a simple request…

            “There will be less code involved, so no hit on performance. “

            Can you explain the big hit on performance for everyone who doesn’t go and manually turn on the checkbox? How does one extra conditional become “a big hit”?

            if (field.httpBan){

            — do checking for http

            }else{

            — absolutely nothing extra to do. Continue as you were.

            }

            I don’t want to spend my time integrating with anti-spam plugins, or putting up with *their* performance hit.

            I’d like an optional extra bit of validation to go along with all the other existing validation (valid email, valid phone number, required etc).

            And I’m happy to wait for WPMU to tell me “nah” without getting a lecture on what I should or shouldn’t be requesting :innocent:

          • Tony G
            • Mr. LetsFixTheWorld

            Hey bud – I never intend for my somewhat sticky responses to be perceived as a hassle (aka lecture), though I know they occasionally are. My clients pay me a lot of money to occasionally help them to get what they want despite what they ask for. :slight_smile: Suffice to say, I won’t pursue this with any more grief.

            To answer your question “Can you explain the big hit on performance for everyone who doesn’t go and manually turn on the checkbox?” I didn’t say “big hit”. I was comparing “some hit” to “no hit”. Where your code says “don’t do anything if the check for http isn’t set, I am proposing:

            if (field.postValidation){
            return apply_filters('forminator_field_postValidation',$value); // true=spam=invalid
            }else{
            -- absolutely nothing extra to do. Continue as you were.
            }

            That can be handled for your purposes with

            function check_forminator_field_spam( $value ) {
            return strpos($value, "http") !== false ;
            }
            add_filter('forminator_field_postValidation','check_forminator_field_spam'), 10, 3 );

            The extra code that is eliminated here is that which is required for the UI. Again, today it’s a request for ‘http’ but inevitably someone will then ask for multiple text values, regex, and options, eventually bulking the admin UI with spam-protection code … which is the role of Akismet, Defender, and other plugins.

            So we have different views on this, not about the ultimate goal but about how we get there. Apparently Dev has already discussed this and they have a plan. I’m content with all of this. I hope you are as well. Thanks!!

        • minty_hunter
          • Flash Drive

          True. Except for the additional performance hit, and:

          “You’ll need an Akismet.com API key to use it. Keys are free for personal blogs; paid subscriptions are available for businesses and commercial sites.”

          Good answer if you’re already using Akismet. Otherwise, I’d like a checkbox :slight_smile:

  • Adam Czajczyk
    • Support Gorilla

    Hey guys!

    There’s some really nice and interesting discussion going on here so let me just add my 2 cents to clear up a bit on how we actually “treated” this feature request :slight_smile:

    This particular request was indeed about URLs but I’ve discussed it with the lead developer of the plugin and we came up with the idea of a bit more “universal solution” that would be custom validation rules.

    Currently we got two “sides” of that: one is just regular validation (and you can e.g. set whether the field is required or not, customize messages and in some cases even set e.g. “format” of data) and the other one is conditional logic that can, to some degree, be used as a kind of additional custom validation.

    But the new idea is to actually add option for custom validation rules. So e.g. an additional tab (like “settings”, “Visibility”:wink: in field setting for each field where you could set/configure field validation rules, for example:

    – contains or cannot contain URL

    – contains a string

    – is not empty

    – must be a number of some format (e.g. valid phone or mail – though these particular ones are already there; you just need to add specific form fields)

    – and so on – just like you were creating your own validation routine

    In general that would be similar to conditional logic rules except they’d be for validation of that particular field they are set for and would make form “submitable” or not, depending on validation results. That would a part of the interface so while it would, most likely, be reflected in Forminator API/hooks, it would be something you could just “click through”.

    So, that’s how we “formulated” the entire feature idea and I believe it would fit-in nicely what’s been discussed here. That’s already on our “planned for future” features list. I don’t have any ETA yet and there’s still a bit too early to say about how this will “ultimately” work but I thought I’ll make it clear that we didn’t “limit” it to “contains http” rule only and confirm that it’s already on the list :slight_smile:

    Best regards,

    Adam

  • Tony G
    • Mr. LetsFixTheWorld

    Um, it looks like we already have the hooks that I’ve been describing.

    This is what Kasia Swiderska was trying to tell us but I didn’t look at the code until just now. Thanks and sorry, Kasia!

    :mega: Nerd Alert! :nerd:

    pluginsforminatorlibrarymodulescustom-formsfrontfront-action.php

    At line 126 there is an opportunity to make process the $response (set to false and set ‘errrors’:wink: before it goes anywhere:

    $response = apply_filters( 'forminator_custom_form_submit_response', $response, $form_id );

    For AJAX responses, see line 206 and filter ‘forminator_custom_form_ajax_submit_response’ where the same success/errors settings will return a JSON error to the browser.

    Line 350 begins function handle_form() which is called just before a preview, if the user makes it that far. At line 724 begins a block to “Handle spam protection” : “Add-ons use this filter to check if content has spam data”

    $is_spam = apply_filters( 'forminator_spam_protection', false, $field_data_array, $form_id, 'custom_form' );
    $entry->is_spam = $is_spam;

    So that’s how custom code can set the spam flag. After handle_form another call is made to ‘forminator_custom_form_ajax_submit_response’, which gives custom code a chance to say “yes, this is spam, so set the success/errors values so that this won’t be posted”.

    There’s also the class-akismet.php. It creates a class Forminator_Akismet which extends Forminator_Spam_Protection. This calls to Akismet, and then it calls another hook to notify local code about what Akismet decided:

    apply_filters( 'forminator_akismet_is_spam', $is_spam, $post_data, $form_id );

    A hook for that filter would be a good place to do custom checking – perhaps in another class that extends Forminator_Spam_Protection.

    Since there isn’t an Integration/Add-on for Akismet, it looks like that call is made automatically if Akismet is activated. So while the plain text “http” is probably not seen by them as an indicator of spam, the more complex stuff already seems to be done for us.

    Adam Czajczyk acknowledged the request for admin tools to be created on the back-end (exactly what Kasia said… :stuck_out_tongue_winking_eye: ). I’ve been petitioning for an API to handle this stuff with code. But that’s already there! minty_hunter can get the functionality that he wants right now with just a few lines added to functions.php. The UI … yeah, that needs to wait for Dev to allocate resources.

    (Um, if I got any of the above wrong, I’m hoping someone with a clue can correct it.)

    Thanks for putting up with me. :blush:

  • Adam Czajczyk
    • Support Gorilla

    Hi Tony G

    Yeah, the hooks that you mentioned are already there and should be working as you described them.So that’s definitely something that can be used in your own custom code.

    The feature I described would add proper UI and, quite possibly (though I’m not really able to tell for sure yet), some additional “code ways” :slight_smile: But we’ll have to wait and see :slight_smile:

    Best regards,

    Adam

Thank NAME, for their help.

Let NAME know exactly why they deserved these points.

Gift a custom amount of points.