Formit is an essential Extra that offers a wide range of functionality for Modx websites. From form validation and email handling to Recapctha integration and data storage, Formit simplifies the process. In this article, I'll introduce a more efficient approach to retrieving and saving submitted Formit forms to the database using the FormitSaveForm
hook.
The Original Approach
A few years ago, I needed a quick and straightforward method to retrieve all the submitted forms saved for a specific form. To access this data, I relied on a simple SQL statement that fetched the data and displayed it. Here's the essence of the snippet I created:
$sql = "SELECT * FROM modx_formit_forms";
foreach($modx->query($sql) as $rows) {
...
}
However, using this SQL statement had several limitations:
- It bypassed the Formit model, which meant working with raw data.
- Decrypting data from an encrypted form was not possible.
- It returned every form ever saved, making it inefficient.
A Better Approach
Recently, I was approached by a Modx user seeking a better solution for accessing encrypted forms. Leveraging my increased knowledge of Modx, I took the opportunity to rewrite the snippet and utilize the Formit model to access the data effectively. Here's the improved version:
// Load the Formit class
$formit = $modx->getService('formit', 'FormIt', $modx->getOption('formit.core_path', null, $modx->getOption('core_path') . 'components/formit/') . 'model/formit/');
// Set snippet properties
$formName = $modx->getOption('name', $scriptProperties, null);
// XPDO query to retrieve forms
$q = $modx->newQuery('FormItForm');
$q->where([
'form' => $formName,
]);
$total = $modx->getCount('FormItForm', $q);
$forms = $modx->getCollection('FormItForm', $q);
Now, the $forms
variable holds an array of FormItForm objects that provide access to various methods defined in the FormItForm model. This allows us to retrieve a saved form by name, and with the flexibility of the XPDO query object, we can further refine our selection.
Accessing Encrypted Data
To access and decrypt encrypted data, we can simply call the decrypt
method of the FormItForm objects:
foreach ($forms as $form) {
$fields = $form->toArray();
// Check if data is encrypted
if ($form->get('encrypted')) {
// The form is encrypted, use the decrypt method to decrypt it
$fields['values'] = $form->decrypt($form->get('values'));
}
// The $fields['values'] now contains the JSON array that can be passed to json_decode()
}
And that's all there is to it! By following this approach, you can efficiently retrieve and process Formit forms, even with encrypted data. You can access the updated GIST here: https://gist.github.com/NatemcM/6a286295f83864e15a6189e7ecddf788.js