Formit - prevent duplicate submissions based on email address

Hi There,

I have a form using Formit where the user registers to play a quiz.
The first form takes their email address to identify them.
Is there a way to prevent them from playing a second time using the same email address?

I’ve read through the docs but I can’t find anything,
All my submissions are being saved to the database, so somehow i want to look up and see if there’s already an entry.

Is this possible?

Thanks!
Andy

Shortly I believe you need some custom snippet hook, put it at the beginning of &hooks Formit parameter. It should check your database recorded emails and fails if current email value already participated in quiz.

Yes thanks - that’s what I need - but I just don’t know how to do it.

You should be able to grab the email with something like $email = $hook->getValue(‘name of email field’).

Then it’s just:

$user = $modx->getObject('modUserProfile' array('email' => $email));
if ($user) {
   /* set error placeholder here */
    return false;
} 
return true;

I don’t use FormIt, so I’m not sure about the email field name or setting the error message.

Thanks bob. That’s great to start me off. I’ll have a play. Thanks again.

Hi bob.
Just had a play with this but I think that you’ve assumed that the players are registered Modx users. I probably didn’t explain properly. They register to play the game, but do not actually be one modx users. They just fill their details into the first part of the form.
These are stored in the database but not as a user profile.

Hope that makes sense

Thanks
Andy

Hi @tm2000,
If so you need to create other database request to your custom table. Please clarify what exactly do you use? Is this some extra with schema will all necessary and significant characteristics…Or is this some simple table where you store emails somehow(how exactly) ?

it is necessary to understand what is more convenient to build this query

Hi there - thanks for your message.

So I’m just using a standard form with Formit to take the person’s name and email address before they play the quiz.
Once they have played, I’m using the FormItSaveForm hook to save the entry to the database.

On checking the database, they go into a table called: modx_formit_forms
It has a columns called: values
Within this is the entire entry - e.g.
{"Score":2,"one":"2008","two":"Black","three":"1966","four":"Kick Boxing","yourName":"Andy Jones","yourCompany":"TYGA","yourEmail":"andy@emailaddress.com","submit":"Send","datestamp_submitted":"31-03-2020 09:49:53"}

So I need a prehook on the register form which checks to see if there is the same email address within this column.

Maybe it’s not possible because there isn’t a specific email column in the database?

Thanks again for any time you have on this!

Maybe it’s not possible because there isn’t a specific email column in the database?

Yes, we have to look inside json values field:

    $email = $hook->getValue('email'); //form email 
    $query = $modx->newQuery('FormItForm');
    $query->where(array(
       'values:LIKE' => '%$email%',
    ));
    if($modx->getCollection('FormItForm',$query)){
    	return false;
    }
    return true;

Wow thanks for this!

Do I need to add something to locate the relevant table in the database to look up the email address though?

So I’ve been playing around with this adding it as a hook before all other hooks but it doesn’t seem to do anything. I think I probably need more in the snippet to make it work. Sorry - but my php skills are very bad!

Hi @tm2000,
ok, let’s debug it a bit)
Suppose your snippet hook could be called like this: yourCustomHook.

  1. Create separate empty page and call this non-cached snippet: [[!yourCustomHook]]

  2. Update snippet code as follows:

     $email = "existedemail@domain.ltd"; //play with this email, put here emails that occur for the first time or those that are already in the database 
     $query = $modx->newQuery('FormItForm');
     $query->where(array(
        'values:LIKE' => '%$email%',
     ));
     $prepareQuery = $modx->prepare($query);
     $modx->log(xPDO::LOG_LEVEL_ERROR, 'SQL query ='.$prepareQuery->toSQL(), '', 'yourCustomHook');
     if($modx->getCollection('FormItForm',$query)){
     	$modx->log(xPDO::LOG_LEVEL_ERROR, 'Email exists', '', 'yourCustomHook');
     	return false;
     }
     $modx->log(xPDO::LOG_LEVEL_ERROR, 'There are no such emails', '', 'yourCustomHook');
     return true;
    

3.Preview this page in browser
4. Open your MODX backend error log and let me know what you’ve got: /manager/?a=system/event

Hi there - thanks so much for your time on this!!

So I have created a blank page as suggested with the snippet you wrote.
When I try and preview the page, i get a 500 error in the browser.

In the error log I get this:

[2020-04-01 18:06:24] (ERROR @ /home/site/core/xpdo/xpdo.class.php : 644) Could not load class: FormItForm from mysql.formitform.
[2020-04-01 18:06:24] (ERROR @ /home/site/core/xpdo/xpdo.class.php : 592) No class specified for loadClass
[2020-04-01 18:06:24] (ERROR @ /home/site/core/xpdo/xpdo.class.php : 1617) Could not load class 
[2020-04-01 18:06:24] (ERROR @ /home/site/core/xpdo/xpdo.class.php : 592) No class specified for loadClass
[2020-04-01 18:06:24] (ERROR @ /home/site/core/xpdo/xpdo.class.php : 1655) Could not load class !
[2020-04-01 18:06:24] (ERROR @ /home/site/core/xpdo/xpdo.class.php : 592) No class specified for loadClass
[2020-04-01 18:06:24] (ERROR @ /home/site/core/xpdo/xpdo.class.php : 592) No class specified for loadClass
[2020-04-01 18:06:24] (ERROR @ /home/site/core/xpdo/xpdo.class.php : 2529) PHP warning: PDO::prepare() expects parameter 1 to be string, object given

So i think maybe there’s a syntax error in the snippet maybe?

Thanks
Andy

Should ‘FormItForm’ be the name of the table in my Database maybe?

Sorry, I forgot one important row.
This is proper and shorter variant:

<?php
$modx->addPackage('formit', $modx->getOption('core_path').'components/formit/model/');

$email = "test@gmail.com"; //play with this email, put here emails that occur for the first time or those that are already in the database 

if($modx->getCollection('FormItForm',array('values:LIKE' => "%$email%"))){
    $modx->log(xPDO::LOG_LEVEL_ERROR, 'Email exists', '', 'yourCustomHook');
    return false;
}
$modx->log(xPDO::LOG_LEVEL_ERROR, 'There are no such emails', '', 'yourCustomHook');
return true;

If this will work for you I’ll be ready to update it to hook.))

Ah ok thanks I will try it out and let you know!

Thanks again
Andy

Hi there.
So thank you for your detailed snippet code - it worked in it’s own resource with a hard-coded email address in there.
I’ve now added this as my snippet - but when i change the line:
$email = "test@gmail.com"; //hard coded email aDdress for testing

to:

$email = "yourEmail"; // which is the name of the email field in my form

It returns false every time - regardless of what email address I use.
I have tried various syntax including:

$email = "[[+yourEmail]]";

and

$email = "[[+fi.yourEmail]]";

But whatever I try it comes back with the same error:

[2020-04-02 09:11:13] (ERROR in checkEmailExists @ /home/site/core/cache/includes/elements/modsnippet/146.include.cache.php : 11) Email exists

It must be simple, but I can’t work out what’s wrong here (sorry - I have been trying for a while before asking again!)

Thanks
Andy

Hi Andy,

Now you should run this snippet as Formit hook.

  1. Update your snippet with

    $email = $hook->getValue('email'); //form email field

  2. Update Formit hooks parameter:

     [[!Formit?
     ...
     &hooks=`yourCustomSnippet,email`
     ...
     ]]

Perfect that works - thank you so much!

Stay safe!
Andy

Great! Thanks and you too!