Neos.Fusion:Case keys with only numbers

So I was playing around with Neos.Fusion:Case a little and found some weird-ish behavior.

Let’s assume this is our Fusion-Case:

someVariable = Neos.Fusion:Case {
	10 {
		condition = ${true}
		renderer = ${'something'}
	}
	50 {
		condition = ${true}
		renderer = ${'anything'}
	}
}

If I change the first name to 10, 100, 1 or a variation thereof, it doesnt display the first case, but goes straight to the second. Quotes (’, ") don’t change this behavior.
False/false/FALSE works. 0, 00,…, works as well as when I add some other number or letter to the first key.

Now I change the name of the first key to 50, and the second to something with a letter in it like ‘name’, it will also display the behavior that it will only display the second case.

So, my question is why? What happens here in the background?

Also I think that the API-Reference (Fusion Reference — Neos CMS dev-master documentation) is quite insufficient. It tells me that key should be a matcher definition and that Neos.Fusion:Matcher is an internal object type. But at least as far as I saw, there is no documentation regarding Neos.Fusion:Matcher where I can look it up easily.
There is documentation about Neos.Fusion:Match, but this also only tells me that the subject to match should be a string which doesn’t explain the behavior above.

You can enforce the order by putting @position properties into the Matchers but i agree this is weird behavior. I would not have expect the name of keys influencing the order

someVariable = Neos.Fusion:Case {
    10 { 
        @position = 1
    }
    50 {
        @position = 2
    }
}

If you want to dive into the code to understand the issue the PositionalArraySorter is the component ordering Matchers.

@AERTurtle Hi and welcome to the Neos community :slight_smile:

I tried to reproduce the issue but I fail.
Your example returns “something”, just like I would have excepted. See:
https://fusionpen.punkt.de/fusionpen/6b517d848c62170dafebe75b31ad79b13a3bc649.html

Can you elaborate on the expected vs actual behavior?

The fun starts when you mix strings and number as keys: FusionPen: Build, Test and Discover Fusion Code for Neos CMS

1 Like

I see… I’d say the order with mixed type keys is not really defined. But even so the result (that “foo” comes before 10) is not really wrong IMO.

Technically it is because the array keys are ordered with the SORT_NUMERIC flag: https://3v4l.org/S9hY6#v8.1.5

the fusion parser does differentiate between '1' = "a" and 1 = "a" but once they are transformed into the merged array tree for the runtime, php doesnt preserve this information in arrays: [1 => 'a'].

Infact php auto converts string numbers to actual numbers when they are php array keys. Thats why there is no technical difference.

When you add a leading 0 to a fusion number key (or fusion string number key), it will be treated either way as a string key since php knows that it cant cast those keys to integer without loosing the information on leading didgits. Eg (at least with the 8.0 parser) they will be treated as string keys fusion: 00 = "a" or "00" = a equals to the php: ["00" = > "a"]

see the tests: neos-development-collection/ParserTest.php at 33ae8ab931984fe4910584bcea0383700a0135c0 · neos/neos-development-collection · GitHub

In the pre 8.0 parser versions there was some custom logic that accidentally transformed 00 keys to 0 keys. (if i recall correctly) but that was cleaned up.

1 Like