Better way to access formit form data

Many years ago I commented on this post FormIt Integration Options: Make Form Submissions Easily Accessible to Client Only - #22 by inside-creative a method to access formit forms to build a CSV file. Recently I was contacted regarding the solution, specifically relating to accessing encrypted forms and I want to share the solution here.

Please note, I DO NOT recommend the solution I wrote in my previous comment (I’m unable to update the comment or post) mainly due to the use of an SQL statement to access stored objects rather than using the better-suited $modx->getCollection() method.

Here is my recommended way for accessing Formit form data and returning their fields even if they are encrypted in an example snippet:

MODX 2

<?php

/**
 * Snippet to get formit forms by name
 * usage:
 * [[!getFormitForm? &name=`Name of form`]]
 */

// Load formit class
$formit = $modx->getService('formit', 'FormIt', $modx->getOption('formit.core_path', null, $modx->getOption('core_path') . 'components/formit/') . 'model/formit/');

// Load PDO Tools 
$pdo = $modx->getService('pdoTools');

// set snippet props
$formName = $modx->getOption('name', $scriptProperties, null);

// xpdo query to get forms
$q = $modx->newQuery('FormItForm');
$q->where([
    'form' => $formName,
]);
$total = $modx->getCount('FormItForm', $q);

$forms = $modx->getCollection('FormItForm', $q);

if (!empty($forms)) {
    // Set our inner tpl var
    $dataOutput = '';

    // Loop through each object and tpl up
    foreach ($forms as $form) {

        $fields = $form->toArray();

        // Check if data is encrypted
        if ($form->get('encrypted')) {
            // Form is encrypted, use the objects decrypt method to decyrpt
            $fields['values'] = $form->decrypt($form->get('values'));
        }

        // $fields['values'] contains the JSON array to access pass to json_decode() ie;
        $values = json_decode($fields['values'], true);
        $fields['fields'] = '';
        // then access like: $values['firstName']
        foreach ($values as $key => $value) {
            $fields['fields'] .= "<strong>$key:</strong> $value<br>";
        }

        // Format the date string
        $fields['date'] = date('Y-m-d', $fields['date']);

        // Tpl up our form
        $dataOutput .= $pdo->getChunk(
            "@INLINE <tr>
                <td>[[+id]]</td>
                <td>[[+form]]</td>
                <td>[[+ip]]</td>
                <td>[[+date]]</td>
                <td>[[+hash]]</td>
                <td>[[+fields]]</td>
            </tr>",
            $fields
        );
    }

    // Set wrapper tpl
    $output = $pdo->getChunk("@INLINE <table width='100%'>
        <thead>
            <tr>
                <td>id</td>
                <td>form</td>
                <td>ip</td>
                <td>date</td>
                <td>hash</td>
                <td>values</td>
            </tr>
        </thead>
        <tbody>
            [[+wrapper]]
        </tbody>
        </table>
        <br>
        <strong>Total: [[+total]]</strong>", [
        'wrapper' => $dataOutput,
        'total' => $total
    ]);
}

return $output;

MODX 3

<?php

/**
 * Snippet to get formit forms by name
 * usage:
 * [[!getFormitForm? &name=`Name of form`]]
 */

use Sterc\FormIt\Model\FormItForm;

// Load formit class
$formit = $modx->getService('formit', 'FormIt', $modx->getOption('formit.core_path', null, $modx->getOption('core_path') . 'components/formit/') . 'model/formit/');

// Load PDO Tools 
$pdo = $modx->getService('pdoTools');

// set snippet props
$formName = $modx->getOption('name', $scriptProperties, null);


// xpdo query to get forms
$q = $modx->newQuery(FormItForm::class);
$q->where([
    'form' => $formName,
]);
$total = $modx->getCount(FormItForm::class, $q);

$forms = $modx->getCollection(FormItForm::class, $q);

if (!empty($forms)) {
    // Set our inner tpl var
    $dataOutput = '';

    // Loop through each object and tpl up
    foreach ($forms as $form) {

        $fields = $form->toArray();

        // Check if data is encrypted
        if ($form->get('encrypted')) {
            // Form is encrypted, use the objects decrypt method to decyrpt
            $fields['values'] = $form->decrypt($form->get('values'));
        }

        // $fields['values'] contains the JSON array to access pass to json_decode() ie;
        $values = json_decode($fields['values'], true);
        $fields['fields'] = '';
        // then access like: $values['firstName']
        foreach ($values as $key => $value) {
            $fields['fields'] .= "<strong>$key:</strong> $value<br>";
        }

        // Format the date string
        $fields['date'] = date('Y-m-d', $fields['date']);

        // Tpl up our form
        $dataOutput .= $pdo->getChunk(
            "@INLINE <tr>
                <td>[[+id]]</td>
                <td>[[+form]]</td>
                <td>[[+ip]]</td>
                <td>[[+date]]</td>
                <td>[[+hash]]</td>
                <td>[[+fields]]</td>
            </tr>",
            $fields
        );
    }

    // Set wrapper tpl
    $output = $pdo->getChunk("@INLINE <table width='100%'>
        <thead>
            <tr>
                <td>id</td>
                <td>form</td>
                <td>ip</td>
                <td>date</td>
                <td>hash</td>
                <td>values</td>
            </tr>
        </thead>
        <tbody>
            [[+wrapper]]
        </tbody>
        </table>
        <br>
        <strong>Total: [[+total]]</strong>", [
        'wrapper' => $dataOutput,
        'total' => $total
    ]);
}

return $output;

Hope that helps someone in the future

2 Likes

How about accessing the forms inside a processor I have used the getService call above and created the new instance FormItForm but when I try to use newQuery I get an error about not being able to load the class FormItForm.

Is this MODX 2 or MODX 3?
Can you share your processor code?

1 Like

This is in MODX 3. Actually, I worked it out. Here it is for anyone else that needs it.

I call this in my initialize override in a getlist processor class with the class key set to FormitForm.

$modx = $this->modx;
$this->modx->services->add('formit', function() use ($modx) {
    return new \Sterc\FormI($modx);
});

Then I can set the criteria for the query as normal in my prepareQueryBeforeCount override.

There were some posts from @bobray and @demon.devin somewhere I had seen a while back about getService being depreciated and there they added the service and used the callback to load the class.

There’s more information about this change in loading services in MODX 3 at Dependency Injection Container - Extending MODX | MODX Documentation.

Bro! You made may day! Thanks!!