Bug issue with Form Scope array bracket notation, setting to disable?


#1

I’m wondering if we can just turn this feature off in Lucee? The Lucee application setting ‘sameFormFieldsAsArray’ is already false by default. So if the intent of this is to prevent Lucee from processing array bracket notation in the form scope, it doesn’t seem to be working.

I recently implemented a fix for open source Slatwall e-commerce platform to circumvent issues caused by Lucee trying to parse array bracket notation in form scope. Slatwall Patch for Lucee Form Scope Issue:

I was seeing some inconsistent behavior between ACF and Lucee with our logic in some cases. It really depends on how Lucee chooses to order the form scope variables and what new variables it litters it with.

The open source Slatwall e-commerce platform has internal logic that constructs the proper object tree using bracket and dot notation with variables from the url/form scopes (similar to what Lucee is trying to do).

Basically if you have form fields like this submitted in the request

<input name="products[1].productID" value="98765" />
<input name="products[1].skus[1].skuID" value="12345" />
<input name="products[1].skus[1].price" value="25.00 />

In ACF, our method will always return the object we are expecting after internal process (using struct notation to describe the returned output here)

{
    products = [
        {
            productID = "98765", 
            skus: [
                { skuID: "12345", price: "25.00" }
            ]
        }
    ]
}

But Lucee creates additional objects in the form scope and not in a way we find useful because of how it is naming keys still keeping the brackets. Take a look at the difference between the construction of the form scope between ACF and Lucee.

CF11 Form Scope Dump:
https://github.com/ten24/slatwall/files/2143366/CF11.Form.Scope.html.pdf

Lucee 4 & 5 Form Scope Dump:
https://github.com/ten24/slatwall/files/2143367/Lucee5.Form.Scope.html.pdf

I can’t upload any attachments here to illustrate, but they are part of the patch for Slatwall on Github:

If you want to see our internal discussion for more details you can look at the comments on the patch’s pull request:


#2

Or maybe add logic to Lucee to not process form fields that have dot notation into structs if they contain [n] since it appears to not be able to handle notation with both a mixture of brackets and dots at the same time. Or fully implement that functionality.


#4

Let me explain first a little WHY things are as they are.

the setting “sameFormFieldsAsArray” is completely unrelated to this.
this influence if lucee combine multiple form/url with the same name to a string list or an array.
what is not the case here, you do not have to items in the form scope with the same name.

That Lucee creates a array in case a form/url field comes with “” at the end exists since Railo 1.0 and also is also completely unrelated to this. this only applies when name ends with “” what it does not in your case.

So the difference is that Lucee interprets the “.” in the name of a form/url variable.
Why if ACF does not?
Very simple acf does not but ACF interprets variable names.
so for example this works in ACF but not in Lucee

request['a.b.c']=1;
writeDump(request.a.b.c);
writeDump(request['a.b.c']);

We do not support this for multiple reasons

  1. make the hole language slower for an edge case.
  2. it is simply illogical

To be more compatible to ACF we decided do read the “.” as struct seprator when parsing url or form scope instead.
it turned out to be the best solution for most users.

But for cases like yours we added the function StructKeyTranslate(form,true,true) that flattens the key in a struct. so you get what you need.

Sure we can discuss a setting to disable that behaviour, should not be a big deal.


#5

Thanks for looking into this Michael.

I think an application setting would be beneficial to disable form/url scope notation interpretation of literals so ACF form == Lucee form. Maybe setting name ‘disableScopeNotationInterpretation’?

I understand request.a.b.c != request['a.b.c'] in Lucee. That makes prefect sense. Lucee always treats ['a.b.c'] as a literal key and not evaluated or interpreted.

I do like how Lucee conveniently interprets ‘.’ in the scopes but for us its currently incomplete since it is limited that it can’t handle array notation. If it could take it another step and inspect the parsed key name to see if the key contains the array notation using a regex:
\S+\[\d+\] (ie. somekey[2] would match)

So form/url scope ?countries[1]=US&countries[2]=MX&countries[3]=UK becomes

countries = ['US', 'MX', 'UK']

That preserves not only order but allows for consolidating complex types using the notation.

?countries[1].name=United States&countries[1].code=US&countries[2].name=Mexico&countries[2].code=MX becomes

countries = [
  {
    name = "United States",
    code = "US" 
  },
  {
    name = "Mexico",
    code = "MX"
  }
]

I think the feature would be beneficial to other app developers.

I played around with the StructKeyTranslate(form,true,true) but I still end up with a structure different than what is needed.