aurovrata / cf7-grid-layout

A WordPress plugin extension for Contact Form 7 to design responsive grid-layout forms.
https://wordpress.org/plugins/cf7-grid-layout/
GNU General Public License v2.0
6 stars 7 forks source link

Cf7_Grid_Layout_Public#setup_grid_values changes $data schema #18

Closed nhance closed 3 years ago

nhance commented 3 years ago

Hi there!

We've developed a plugin to integrate Contact Form 7 with Microsoft Power Automate and have discovered an issue with this plugin that causes our plugin and likely others to fail.

The function setup_grid_values in Cf7_Grid_Layout_Public causes entries in the $data array passed to be changed from a nested array to a flat value.

For example, if the posted data comes into this method like this:

$data = array( 'menu' => array('posted value'))

when the setup_grid_values method fires on the wpcf7_posted_data filter, the above data is returned as:

$data = array('menu' => 'posted value')

And this causes the integration to break as our external data partner expects data integrity to be preserved.

To resolve:

Our customers are unable to use your plugin while this issue persists.

Thanks, Nick

aurovrata commented 3 years ago

Dear nick

As you can imagine the method and data formatting has been implemented for a very specific reason.

Ensure that all values that come into the setup_grid_values as an array are returned as an array.

I reckon you need to make your plugin compatible with the Smart grid.

Simply changing the return format of the data would break countless other sites that have been built already and are expecting this data.

What I can possibly do is look at ways to switch on the array preservation by having your plugin call a hook.

aurovrata commented 3 years ago

In addition, this plugin allows users to build tables of / tabulated sections of repetitive fields. These are processed as single values/or arrays by the CF7 plugin, while the Smart Grid's setup_grid_values method reformat these as arrays of columns (not rows) and in some cases array of arrays, for tables within tabulated sections.

I presume this is one of the functionalities that your plugin users are using, so you will need to modify your plugin to handle such data structures.

Let me know if you are amenable to collaborate on making our respective plugins work with one another.

aurovrata commented 3 years ago

We've developed a plugin to integrate Contact Form 7 with Microsoft Power Automate

is this your plugin: Power Force 7?

nhance commented 3 years ago

Hi @aurovrata Yes it's Power Form 7.

One of the core requirements of our plugin is to be able to describe the data schema produced in the CF7 Submission. Power Automate, and other platforms allow you to build integrations but it means that we have to be able to anticipate what form the data will be presented from the Submission's posted data.

We can modify our plugin so that it looks for selectable-values rather than the field type to determine when the data is an array. This is what determines array format from the Contact Form 7 internals:

https://github.com/takayukister/contact-form-7/blob/master/includes/submission.php#L252

Could your plugin respect that selectable-value field types will be arrays?

We based our plugin on the format provided from the standard installation of Contact Form 7. As you can see in the link above, some fields are returned as arrays and if you explore the code above you'll see how much effort has gone in to ensuring that the arrays are not squashed.

aurovrata commented 3 years ago

Could your plugin respect that selectable-value field types will be arrays?

for single fields yes, for table/tabbed fields no, as they will return as array of arrays since these are repetitive fields. As I mentioned in my previous post, you will need to adapt your plugin to the Smart Grid

We based our plugin on the format provided from the standard installation of Contact Form 7

this has evolved and will likely keep involving.

aurovrata commented 3 years ago

Prior to version 5 of the CF7 plugin, the format of the data preserved that of the $_POST submission.

The Smart Grid-layout extension was designed to bring the CF7 form plugin back into the WP standard as the author was not cooperative when it came to request for changes to make the CF7 plugin compatible with other plugins that relied on WP standards to play nice. (For more details you can read my post on why I wrote this plugin).

The following form (you can cut and paste into the Smart grid HTML editor if you want to try it out), it has 3 sets of selectable fields. Each set is a single select and a multiple select. The 3 sets are single fields, tabled repetitive fields, and tabbed + tabled repetitive fields. ... (click to view) ```html
[select* single-select "Option A" "Option B" "Option C"]

[select* multiple-select multiple "Option A" "Option B" "Option C"]

[select* single-repetitive-select "Option A" "Option B" "Option C"]

[select* multiple-repetitive-select multiple "Option A" "Option B" "Option C"]

[select* single-tabbed-repetitive-select "Option A" "Option B" "Option C"]

[select* multiple-tabbed-repetitive-select multiple "Option A" "Option B" "Option C"]

```
Here is the `$_POST` submission of values. ... (click to view) ``` [_wpcf7] => 156 [_wpcf7_version] => 5.3.2 [_wpcf7_locale] => en_GB [_wpcf7_unit_tag] => wpcf7-f156-p157-o1 [_wpcf7_container_post] => 157 [_wpcf7_posted_data_hash] => f6a7b5a5b5b25addf8960799417a09d1 [_wpcf7_key] => selectable-fields [_cf7sg_toggles] => [_cf7sg_version] => 4.8.0 [_wpnonce] => 33aa879edf [_map_author] => 1 [single-select] => Option B [multiple-select] => Array ( [0] => Option A [1] => Option B ) [cf7-sg-table-1613715438690] => 2 [single-repetitive-select] => Option A [multiple-repetitive-select] => Array ( [0] => Option A [1] => Option B ) [single-repetitive-select_row-1] => Option B [multiple-repetitive-select_row-1] => Array ( [0] => Option B [1] => Option C ) [cf7-sg-tab-1613715462988] => 2 [cf7-sg-table-1613715473467] => 2 [single-tabbed-repetitive-select] => Option A [multiple-tabbed-repetitive-select] => Array ( [0] => Option A [1] => Option B ) [single-tabbed-repetitive-select_row-1] => Option B [multiple-tabbed-repetitive-select_row-1] => Array ( [0] => Option B [1] => Option C ) [cf7-sg-table-1613715473467_tab-1] => 2 [single-tabbed-repetitive-select_tab-1] => Option B [multiple-tabbed-repetitive-select_tab-1] => Array ( [0] => Option B [1] => Option C ) [single-tabbed-repetitive-select_tab-1_row-1] => Option C [multiple-tabbed-repetitive-select_tab-1_row-1] => Array ( [0] => Option A [1] => Option C ) ```

NOTE: submitted fields such as single-repetitive-select_row-1 will not be handled by the CF7 plugin as teh tag manager will not find the corresponding field tag.

Here is the reformatted $data output from the `setup_grid_values` method. ``` [single-select] => Option B [multiple-select] => Array ( [0] => Option A [1] => Option B ) [cf7-sg-table-1613715438690] => 2 [cf7-sg-tab-1613715462988] => 2 [cf7-sg-table-1613715473467] => 2 [cf7-sg-table-1613715473467_tab-1] => 2 [single-repetitive-select] => Array ( [] => Option A [_row-1] => Option B ) [multiple-repetitive-select] => Array ( [] => Array ( [0] => Option A [1] => Option B ) [_row-1] => Array ( [0] => Option B [1] => Option C ) ) [single-tabbed-repetitive-select] => Array ( [] => Array ( [] => Option A [_row-1] => Option B ) [_tab-1] => Array ( [] => Option B [_row-1] => Option C ) ) [multiple-tabbed-repetitive-select] => Array ( [] => Array ( [] => Array ( [0] => Option A [1] => Option B ) [_row-1] => Array ( [0] => Option B [1] => Option C ) ) [_tab-1] => Array ( [] => Array ( [0] => Option B [1] => Option C ) [_row-1] => Array ( [0] => Option A [1] => Option C ) ) ) ```

Repetitive fields are returned as array of arrays, you will need to ensure your plugin handle those properly if you want it work with the Smart grid.

aurovrata commented 3 years ago

I have introduced a filter in v4.8.1rc1 which preserves the CF7 data schema for single fields,

You'll need to add this hook to your plugin, ```php add_filter('cf7sg_preserve_cf7_data_schema', '__return_true'); ``` resulting in the following output to the above posted form, ... (click to view) ``` [single-select] => Array ( [0] => Option A ) [multiple-select] => Array ( [0] => Option A [1] => Option B ) [cf7-sg-table-1613715438690] => 2 [cf7-sg-tab-1613715462988] => 1 [cf7-sg-table-1613715473467] => 2 [single-repetitive-select] => Array ( [] => Option A [_row-1] => Option B ) [multiple-repetitive-select] => Array ( [] => Array ( [0] => Option A [1] => Option B ) [_row-1] => Array ( [0] => Option B [1] => Option C ) ) [single-tabbed-repetitive-select] => Array ( [] => Array ( [] => Option A [_row-1] => Option B ) ) [multiple-tabbed-repetitive-select] => Array ( [] => Array ( [] => Array ( [0] => Option A [1] => Option B ) [_row-1] => Array ( [0] => Option B [1] => Option C ) ) ) ```

However, you'll still need to handle repetitive fields.

If this works for you, then I can release this version on the WP repo.

nhance commented 3 years ago

@aurovrata Thanks for this but it won't work for us as once converted to JSON the data will be described as objects, not an array.

When I look at the form you provided, I see 6 input fields, which if we assume the form represents HTML (because it looks like HTML) we would expect to see 6 values in the incoming data. One for each field.

However, your plugin is adding magic and special meaning to the tags beyond what can be seen from the HTML. In other words, there is no way to know, other than having read the code for your plugin, that this form will return more than 6 values. (Whatever makes those repetitive tags repeat isn't contained within the tags themselves.)

In practice we don't care what the form sends, but we have to know the schema of the incoming data before we get it and do so in a way that respects the vast majority of the 5+ million CF7 installations in use.

Assuming that the form HTML represents the expected format of the incoming data is the only way I can see us being able to do this. I can see nothing within the form tags that indicates the schema would be different? Why would our plugin need to understand the internals of yours beyond form tags?

You are free to take liberties with your approach, but if you are going to modify the schema of the standard out-of-the-box CF7 fields I can't see how we can hope to be compatible. Additional form-tag details we can support, but parsing the html/classes is ripe for maintenance headaches we can't support. (Again, please know I have not read your code to understand how repetitions are done. It looks like javascript.)

This is absolutely okay to do, but we would need to mark this plugin as incompatible with ours.

Further thoughts:

A potential format we could support would require the following:

Our plugin essentially allows users to develop their own programs powered by the output of the contact form. Unless we can know exactly what's going to be sent we can't provide an interface for low-code/no-code developers to use.

aurovrata commented 3 years ago

Whatever makes those repetitive tags repeat isn't contained within the tags themselves.

indeed, and if you know the ins and outs of the CF7 plugin you will know that is not possible as the tag manager does not expose its functionality.

Why would our plugin need to understand the internals of yours beyond form tags?

Your plugin does not need to, but you do need to understand what it does. I really don't understand how you hope to make it compatible otherwise. You need to get your hands dirty, you can hardly expect me to just provide you with a solution which works without making any changes to your code.

You are requesting changes without making any attempts to understand why your users would want to use the Smart Grid.

This is absolutely okay to do, but we would need to mark this plugin as incompatible with ours.

that would be your loss at this point. Furthermore, there are other CF7 extensions that provide repetitive fields. Non mark tags as this is not possible, so your plugin would be just as incompatible with those plugins too. That would be bummer don't you think?

Further thoughts: A potential format we could support would require the following:

Some way to know that a tag is going to send data in a different format

there is no way this is achievable.

The Smart Grid does track fields that are included in repetitive sections, so exposing this meta-data would be possible,

aurovrata commented 3 years ago

Since you have not got back to me on this, I am assuming you have solved or abandoned this issue and therefore I am closing it.