- Posts: 3
- Thank you received: 0
Welcome to the LimeSurvey Community Forum
Ask the community, share ideas, and connect with other LimeSurvey users!
LEM functions and lack of support for ===
- dapster105
- Topic Author
- Offline
- New Member
Less
More
4 years 2 weeks ago #195130
by dapster105
LEM functions and lack of support for === was created by dapster105
Hi,
I'm just recovering from some nerve-shredding debugging on a live survey which was behaving very badly.
The root cause was that some LEM expressions evaluate differently in javascript (client side) than they do in PHP (server side).
This, I believe, originates from an early mistake of deciding to follow javascipt type flexibility in return types which is not easy to replicate in PHP.
For example, strpos returns an int (if found) or false (yuk). But the int can be zero if the $needle is found as position zero of $haystack. If not careful, this zero can be interpreted as 'false', e.g. strpos('abc','a') == false.
The javascript thing to do then is to use '===' operator to type match, so:
strpos(haystack,needle)!==false
Unfortunately LEM doesn't understand or support '===' or '!===', presumably because this would be very difficult to replicate in PHP?
I thought all might be saved when I saw the is_int() LEM function. But it does not work consistently in javascript LEM implementation and PHP.
to illustrate...
is_int(strpos('abcd','e'))
evaluates to true(!!) in PHP side but false in javascript.
This led to a situation where the PHP decided that a group (with this condition) should be shown to the respondent, and that a mandatory question with the same condition inside the group should be required, but when rendered in the browser, the javascript hides the mandatory question and the user cannot continue!
Clearly having PHP and javascript LEM expressions making different decisions is... ahem... "sub-optimal" to put it politely.
I can find no documented acknowledgement of this problem in the Limesurvey manuals. What is the general view on how to work around these issues and/or resolve them in the long-term?
My own view is that following javascript type flexibility in the first place was probably a mistake and that life would be much simpler if functions like these returned -1 (int) rather than an entirely different type as in javascript. That would allow consistent implementation across javascript and PHP (or any other strongly typed language in future). But I appreciate that would be a breaking change so would require newly named versions of the functions (e.g. f_strpos) with a recommendation to migrate to / use these in future survey scripts to guarantee consistency between server-side and client-side interpretation?
For the time being my hack is to prepend $haystack with a filler character and then offset the search by 1 so that strpos will always return > 0 if it finds a match, e.g.
(strpos(join('#',haystack), needle, 1) > 0) or !(strpos(join('#',haystack), needle, 1) > 0)
So far, this appears to behave consistently between the server and client-side expression managers. Can't have been the original plan though, right?
I'm just recovering from some nerve-shredding debugging on a live survey which was behaving very badly.
The root cause was that some LEM expressions evaluate differently in javascript (client side) than they do in PHP (server side).
This, I believe, originates from an early mistake of deciding to follow javascipt type flexibility in return types which is not easy to replicate in PHP.
For example, strpos returns an int (if found) or false (yuk). But the int can be zero if the $needle is found as position zero of $haystack. If not careful, this zero can be interpreted as 'false', e.g. strpos('abc','a') == false.
The javascript thing to do then is to use '===' operator to type match, so:
strpos(haystack,needle)!==false
Unfortunately LEM doesn't understand or support '===' or '!===', presumably because this would be very difficult to replicate in PHP?
I thought all might be saved when I saw the is_int() LEM function. But it does not work consistently in javascript LEM implementation and PHP.
to illustrate...
is_int(strpos('abcd','e'))
evaluates to true(!!) in PHP side but false in javascript.
This led to a situation where the PHP decided that a group (with this condition) should be shown to the respondent, and that a mandatory question with the same condition inside the group should be required, but when rendered in the browser, the javascript hides the mandatory question and the user cannot continue!
Clearly having PHP and javascript LEM expressions making different decisions is... ahem... "sub-optimal" to put it politely.
I can find no documented acknowledgement of this problem in the Limesurvey manuals. What is the general view on how to work around these issues and/or resolve them in the long-term?
My own view is that following javascript type flexibility in the first place was probably a mistake and that life would be much simpler if functions like these returned -1 (int) rather than an entirely different type as in javascript. That would allow consistent implementation across javascript and PHP (or any other strongly typed language in future). But I appreciate that would be a breaking change so would require newly named versions of the functions (e.g. f_strpos) with a recommendation to migrate to / use these in future survey scripts to guarantee consistency between server-side and client-side interpretation?
For the time being my hack is to prepend $haystack with a filler character and then offset the search by 1 so that strpos will always return > 0 if it finds a match, e.g.
(strpos(join('#',haystack), needle, 1) > 0) or !(strpos(join('#',haystack), needle, 1) > 0)
So far, this appears to behave consistently between the server and client-side expression managers. Can't have been the original plan though, right?
The topic has been locked.
- jelo
- Offline
- Platinum Member
Less
More
- Posts: 5070
- Thank you received: 1263
4 years 2 weeks ago #195131
by jelo
You might state what version of LimeSurvey you use.
Sometimes there are some fixes in some parts of ExpressionScript/ExpressionManager. LS3 and LS4 still have a lot of surprises around that topic.
The discussion about these issues are mostly in the bugtracker, where the rootcause of an issue is than the JS/PHP differences in ExpressionScript.
Example:
Many users are not getting in touch with the issues so you won't see one hot topic in the forum or in the manual.
Perhaps a manual section here would be helpful.
manual.limesurvey.org/ExpressionScript_for_developers
The meaning of the word "stable" for users
www.limesurvey.org/forum/development/117...ord-stable-for-users
Replied by jelo on topic LEM functions and lack of support for ===
You're right and I'm not aware of a masterplan.dapster105 wrote: So far, this appears to behave consistently between the server and client-side expression managers. Can't have been the original plan though, right?
You might state what version of LimeSurvey you use.
Sometimes there are some fixes in some parts of ExpressionScript/ExpressionManager. LS3 and LS4 still have a lot of surprises around that topic.
The discussion about these issues are mostly in the bugtracker, where the rootcause of an issue is than the JS/PHP differences in ExpressionScript.
Example:
bugs.limesurvey.org/view.php?id=1550115501: relevanceStatus : different evaluation in JS and PHP
Many users are not getting in touch with the issues so you won't see one hot topic in the forum or in the manual.
Perhaps a manual section here would be helpful.
manual.limesurvey.org/ExpressionScript_for_developers
The meaning of the word "stable" for users
www.limesurvey.org/forum/development/117...ord-stable-for-users
The topic has been locked.
- DenisChenu
- Offline
- LimeSurvey Community Team
Less
More
- Posts: 13935
- Thank you received: 2551
4 years 2 weeks ago #195133
by DenisChenu
Assistance on LimeSurvey forum and LimeSurvey core development are on my free time.
I'm not a LimeSurvey GmbH member, professional service on demand , plugin development .
I don't answer to private message.
Replied by DenisChenu on topic LEM functions and lack of support for ===
For strpos i use strpos(join("#",myvalue.NAOK)) then i'm sure it's up to 0.
Else : if there are a difference between JS and PHP with the last version or the last LTS version : please report the issue clearly .
Else : if there are a difference between JS and PHP with the last version or the last LTS version : please report the issue clearly .
Assistance on LimeSurvey forum and LimeSurvey core development are on my free time.
I'm not a LimeSurvey GmbH member, professional service on demand , plugin development .
I don't answer to private message.
The topic has been locked.