LimeSurvey API - Master branch

LimeExpressionManager
in package

Table of Contents

Properties

$alias2varName  : array<string|int, mixed>
array of mappings of knownVar aliases to the JavaScript variable names.
$allOnOnePage  : bool
internally set to true (1) for survey.php so get group-specific logging but keep javascript variable namings consistent on the page.
$currentGroupSeq  : int
current Group sequence (0-based index)
$currentQID  : int
used in Question-by-Question mode
$currentQset  : array<string|int, mixed>|null
set of the current set of questions to be displayed, indexed by QID - at least one must be relevant
$currentQuestionSeq  : int
for Question-by-Question mode, the 0-based index
$debugLevel  : int
sum of LEM_DEBUG constants - use bitwise AND comparisons to identify which parts to use
$debugTimingMsg  : string
Message generated to show debug timing values, if debugLevel includes LEM_DEBUG_TIMING
$em  : ExpressionManager
Implements the recursive descent parser that processes expressions
$gRelInfo  : array<string|int, mixed>
array of Group-level relevance status Indexed by gseq; only shows groups that have been visited
$groupId2groupSeq  : array<string|int, mixed>
map of gid to 0-based sequence number of groups
$groupRelevanceInfo  : array<string|int, mixed>
$groupSeqInfo  : array<string|int, mixed>
array of info about each Group, indexed by GroupSeq
$gseq2info  : array<string|int, mixed>
array of group sequence number to static info One entry per group, indexed on gseq
$gseq2relevanceStatus  : array<string|int, mixed>
tracks which groups have at least one relevant, non-hidden question
$indexGseq  : array<string|int, mixed>
array of information needed to generate navigation index in group-by-group mode One entry for each group, indexed by gseq
$indexQseq  : array<string|int, mixed>
array of information needed to generate navigation index in question-by-question mode One entry for each question, indexed by qseq
$initialized  : bool
True (1) if calling LimeExpressionManager functions between StartSurvey and FinishProcessingPage Used (mostly deprecated) to detect calls to LEM which happen outside of the normal processing scope
$instance  : LimeExpressionManager
LimeExpressionManager is a singleton. $instance is its storage location.
$invalidAnswerString  : array<string|int, string>
Array of invalid answer, key is sgq, value is the clear string to be shown Must be always unset after using (EM are in $_SESSION and never new ....)
$jsVar2qid  : array<string|int, mixed>
array of mappings of JavaScript Variable names to Question number (qid)
$knownVars  : array<string|int, mixed>
Collection of variable attributes, indexed by SGQA code
$lastMoveResult  : array<string|int, mixed>|null
last result of NavigateForwards, NavigateBackwards, or JumpTo Array of status information about last movement, whether at question, group, or survey level
$maxGroupSeq  : int
the maximum groupSeq reached - this is needed for Index
$maxQuestionSeq  : int
the maximum Question reached sequencly ordered, used to show error to the user if we stop before this step with indexed survey.
$multiflexiAnswers  : array<string|int, mixed>
array of 2nd scale answer lists for types ':' and ';' -- needed for convenient print of logic file Indexed on qid; available for all questions
$numGroups  : int
Number of groups in survey (number of possible pages to display)
$numQuestions  : int
Numer of questions in survey (counting display-only ones?)
$pageRelevanceInfo  : array<string|int, mixed>
Array of relevance information for each page (gseq), indexed by gseq.
$pageTailorInfo  : array<string|int, mixed>|null
$ParseResultCache  : array<string|int, mixed>
temporary variable to reduce need to parse same equation multiple times. Used for relevance and validation Array, indexed on equation, providing the following information:
$processedRelevance  : bool
True (1) if have already processed the relevance equations (so don't need to do it again)
$q2subqInfo  : array<string|int, mixed>
/** mapping of questions to information about their subquestions.
$qans  : array<string|int, mixed>
array of enumerated answer lists indexed by qid These use a tilde syntax to indicate which scale the answer is part of.
$qattr  : array<string|int, mixed>
array of advanced question attributes for each question Indexed by qid; available for all quetions
$qcode2sgq  : array<string|int, mixed>
maps name of the variable to the SGQ name (without the A suffix)
$qcode2sgqa  : array<string|int, mixed>|null
maps qcode varname to SGQA code
$qid2code  : array<string|int, mixed>
array of mappings of Question # (qid) to pipe-delimited list of SGQA codes used within it
$qid2exclusiveAuto  : array<string|int, mixed>
Array, keyed on qid, to JavaScript and list of variables needed to implement exclude_all_others_auto
$qid2validationEqn  : array<string|int, mixed>
maps question # to the validation equation(s) for that question.
$qrootVarName2arrayFilter  : array<string|int, mixed>
Linked list of array filters
$questionId2groupSeq  : array<string|int, mixed>
map question # to the group it is within, using an incremental count of group order
$questionId2questionSeq  : array<string|int, mixed>
map question # to an incremental count of question order across the whole survey
$questionSeq2relevance  : array<string|int, mixed>
keeps relevance in proper sequence so can minimize relevance processing to see what should be see on page and in indexes Array is indexed on qseq
$runtimeTimings  : array<string|int, mixed>
Array of timing information to debug how long it takes for portions of LEM to run.
$sessid  : string
String identifier for the active session
$sgqaNaming  : bool
used to specify whether to generate equations using SGQA codes or qcodes Default is to convert all qcode naming to sgqa naming when generating javascript, as that provides the greatest backwards compatibility TSV export of survey structure sets this to false so as to force use of qcode naming
$sid  : int
The survey ID
$sPreviewMode  : string|false
sPreviewMode used for relevance equation and to disable save value in DB 'question' or 'group' string force relevance to 1 if needed
$subQrelInfo  : array<string|int, mixed>
list of needed subquestion relevance (e.g. array_filter) Indexed by qid then sgqa; only generated for current group of questions
$surveyMode  : string
survey mode. One of 'survey', 'group', or 'question'
$surveyOptions  : array<string|int, mixed>
a set of global survey options passed from LimeSurvey
$tempVars  : array<string|int, mixed>
variables temporarily set for substitution purposes temporarily mean for this page, until reset. Not for next page
$updatedValues  : array<string|int, mixed>
Array of values to be updated
$varNameAttr  : array<string|int, mixed>
JavaScript array of mappings of canonical JavaScript variable name to key attributes.

Methods

__clone()  : mixed
Prevent users to clone the instance
_CreateSubQLevelRelevanceAndValidationEqns()  : void
Process all question attributes that apply to EM (1) subquestion-level relevance: e.g. array_filter, array_filter_exclude, relevance equations entered in SQ-mask (2) Validations: e.g. min/max number of answers; min/max/eq sum of answers
_ValidateGroup()  : array<string|int, mixed>
Check a group and all of the questions it contains
_ValidateQuestion()  : array<string|int, mixed>
For the current set of questions (whether in survey, gtoup, or question-by-question mode), assesses the following: (a) mandatory - if so, then all relevant subquestions must be answered (e.g. pay attention to array_filter and array_filter_exclude) (b) always-hidden (c) relevance status - including subquestion-level relevance (d) answered - if $_SESSION[$LEM->sessid][sgqa]=='' or NULL, then it is not answered (e) validity - whether relevant questions pass their validity tests
addFrontendFlashMessage()  : void
Add a flash message to state-key 'frontend{survey ID}' The flash messages are templatereplaced in startpage.tstpl, {FLASHMESSAGE}
addValidityString()  : void
Set or log an invalid answer string
ConvertConditionsToRelevance()  : array<string|int, mixed>
If $qid is set, returns the relevance equation generated from conditions (or NULL if there are no conditions for that $qid) If $qid is NULL, returns an array of relevance equations generated from Condition, keyed on the question ID
convertNonLatinNumerics()  : string
Convert non-latin numerics in string to latin numerics Used for datepicker (Hindi, Arabic numbers)
FinishProcessingGroup()  : void
Should be called after each group finishes
FinishProcessingPage()  : void
Should be called at end of each page
FinishProcessPublicPage()  : string|null
End public HTML
GetAllVarNamesForQ()  : string
Expand "self.suffix" and "that.qcode.suffix" into canonical list of variable names
getAnswerSetsForEM()  : array<string|int, mixed>
Return array of language-specific answer codes
GetDebugTimingMessage()  : string
Return a formatted table showing how much time each part of EM consumed
getEMlanguage()  : string
Get the current public language
GetGroupIndexInfo()  : array<string|int, mixed>
Get array of info needed to display the Group Index
getGroupInfoForEM()  : array<string|int, mixed>
Returns group info needed for indexes
GetGroupSeq()  : int
Translate GID to 0-index Group Sequence number
GetLastMoveResult()  : array<string|int, mixed>|null
Get last move information, optionally clearing the substitution cache
GetLastPrettyPrintExpression()  : string
Used to show potential syntax errors of processing Relevance or Equations.
getLEMqcode2sgqa()  : array<string|int, mixed>
Return array database name as key, LEM name as value
getLEMsurveyId()  : int
Returns the survey ID of the EM singleton
GetQuestionIndexInfo()  : array<string|int, mixed>
Get array of info needed to display the Question Index
GetQuestionSeq()  : int
Get question sequence number from QID
GetQuestionStatus()  : mixed
getRegexpValidAttributes()  : string
Return the regexp used to check if suffix is valid
GetRelevanceAndTailoringJavaScript()  : mixed
GetStepIndexInfo()  : array<string|int, mixed>
Return entries needed to build the navigation index
getUpdatedValues()  : array<string|int, mixed>
GetVarAttribute()  : mixed
GroupIsIrrelevantOrHidden()  : bool
Return whether group $gseq is relevant
GroupIsRelevant()  : bool
Returns true if the group is relevant and should be shown
htmlSpecialCharsUserValue()  : string
return a value entered by user to be shown or used in expression
isInitialized()  : bool
Did LEM is currently initialized
isValidVariable()  : mixed
JumpTo()  : array<string|int, mixed>
Jump to a specific question or group sequence. If jumping forward, it re-validates everything in between
loadTokenInformation()  : void
This function loads the relevant data about tokens for a survey.
NavigateBackwards()  : mixed
NavigateForwards()  : array<string|int, mixed>|null
ProcessAllNeededRelevance()  : void
Check the relevance status of all questions on or before the current group.
ProcessCurrentResponses()  : mixed
Cleanse the $_POSTed data and update $_SESSION variables accordingly
ProcessRelevance()  : bool
Compute Relevance, processing $eqn to get a boolean value. If there are syntax errors, return false.
ProcessStepString()  : string
Translate all Expressions, Macros, registered variables, etc. in $string for current step
ProcessString()  : string
Translate all Expressions, Macros, registered variables, etc. in $string
QuestionIsRelevant()  : bool
Return whether question $qid is relevanct
resetTempVars()  : mixed
Reset the current temporary variable replacement Done automatically when page start or page finish ( @param array $vars
RevertUpgradeConditionsToRelevance()  : int
This reverses UpgradeConditionsToRelevance(). It removes Relevance for questions that have Condition
setCurrentQset()  : void
Set currentQset. Used by unit-tests.
SetDirtyFlag()  : void
Tells ExpressionScript Engine that something has changed enough that needs to eliminate internal caching
SetEMLanguage()  : void
Sets the language for ExpressionScript Engine. If the language has changed, then EM cache must be invalidated and refreshed
setKnownVars()  : void
Used for unit tests.
setPageRelevanceInfo()  : void
Used for unit tests.
SetPreviewMode()  : void
Set the previewmode
SetRelevanceTo()  : void
Set the relevance status to the $step
SetSurveyId()  : mixed
Set the SurveyId - really checks whether the survey you're about to work with is new, and if so, clears the LEM cache
setTempVars()  : mixed
SetThisAsAliasForSGQA()  : void
Set the 'this' variable as an alias for SGQA within the code.
setValueToKnowVar()  : mixed
Helper function to update a Read only value
setVariableAndTokenMappingsForExpressionManager()  : bool|null
Create the arrays needed by ExpressionManager to process LimeSurvey strings.
SetVariableValue()  : int
ShowStackTrace()  : mixed
ShowSurveyLogicFile()  : array<string|int, mixed>
Create HTML view of the survey, showing everything that uses EM
singleton()  : LimeExpressionManager
Ensures there is only one instances of LEM. Note, if switch between surveys, have to clear this cache
SplitStringOnExpressions()  : array<string|int, mixed>
Returns an array of string parts, splitting out expressions
StartProcessingGroup()  : void
This should be called each time a new group is started, whether on same or different pages. Sets/Clears needed internal parameters.
StartProcessingPage()  : void
Should be first function called on each page - sets/clears internally needed variables
StartSurvey()  : array<string|int, mixed>
Initialize a survey so can use EM to manage navigation
SubQuestionIsRelevant()  : bool
Return whether a subquestion is relevant
UnitTestConvertConditionsToRelevance()  : array<string|int, mixed>
Return list of relevance equations generated from conditions
UnitTestProcessStringContainingExpressions()  : mixed
Unit test strings containing expressions
UnitTestRelevance()  : mixed
Unit test Relevance using a simplified syntax to represent questions.
updateReplacementFields()  : mixed
Add or replace fixed variable replacement for current page (or until self::resetTempVars was called)
UpgradeConditionsToRelevance()  : array<string|int, mixed>
Do bulk-update/save of Condition to Relevance
UpgradeQuestionAttributes()  : mixed
Deprecate obsolete question attributes.
usingCommaAsRadix()  : bool
Returns true if the survey is using comma as the radix
__construct()  : mixed
A private constructor; prevents direct creation of object
_GetVarAttribute()  : mixed
_ProcessGroupRelevance()  : void
_ProcessRelevance()  : bool
Compute Relevance, processing $eqn to get a boolean value. If there are syntax errors, return false.
_ProcessSubQRelevance()  : bool
Create JavaScript needed to process subquestion-level relevance (e.g. for array_filter and _exclude)
_recursivelyFindAntecdentArrayFilters()  : array<string|int, mixed>
Recursively find all questions that logically preceded the current array_filter or array_filter_exclude request Note, must support: (a) semicolon-separated list of $qroot codes for either array_filter or array_filter_exclude (b) mixed history of array_filter and array_filter_exclude values
_UpdateValuesInDatabase()  : string
Write values to database.
_ValidateSurvey()  : array<string|int, mixed>
Check the entire survey
checkValidityAnswer()  : bool
Check a validity of an answer, Put the string to show to user $this->invalidAnswerString See mantis #10827, #11611 and #14649
getConditionsForEM()  : mixed
getQuestionAttributesForEM()  : array<string|int, mixed>
Return array of language-specific answer codes
getValidityString()  : string|null
return the actual validity string , and reset the variable used ($_SESSION)
gT()  : mixed
ngT()  : mixed
throwFatalError()  : mixed
Kills the survey session and throws an exception with the specified message.

Properties

$alias2varName

array of mappings of knownVar aliases to the JavaScript variable names.

private array<string|int, mixed> $alias2varName

This maps both the SGQA and qcode alias names to the same 2 dimensional array

Tags
example

['p1_sex'] = array( 'jsName' => // the JavaScript variable name used by EM -- e.g. "java38612X11X147" 'jsPart' => // the JavaScript fragment used in EM's ____ array -- e.g. "'p1_sex':'java38612X11X147'" );

example

['afDS_sq1_1] = array( 'jsName' => "java26626X37X705sq1#1" 'jsPart' => "'afDS_sq1_1':'java26626X37X705sq1#1'" );

$allOnOnePage

internally set to true (1) for survey.php so get group-specific logging but keep javascript variable namings consistent on the page.

private bool $allOnOnePage = \false

$currentGroupSeq

current Group sequence (0-based index)

private int $currentGroupSeq
Tags
example

1

$currentQset

set of the current set of questions to be displayed, indexed by QID - at least one must be relevant

private array<string|int, mixed>|null $currentQset = \null

The array has N entries, where N is the number if qids in the Qset. Each has the following contents:

Tags
example

[705] = array( 'info' => array() // this is an exact copy of $questionSeq2relevance[$qseq] -- TODO - remove redundancy 'relevant' => 1 // 1 if the question is currently relevant 'hidden' => 0 // 1 if the question is always hidden 'relEqn' => '' // the relevance equation -- TODO - how different from ['info']['relevance']? 'sgqa' => // pipe-separated list of SGQA codes for this question -- e.g. "26626X37X705sq1#0|26626X37X705sq1#1|26626X37X705sq2#0|26626X37X705sq2#1|26626X37X705sq3#0|26626X37X705sq3#1|26626X37X705sq4#0|26626X37X705sq4#1|26626X37X705sq5#0|26626X37X705sq5#1" 'unansweredSQs' => // pipe-separated list of currently unanswered SGQA codes for this question -- e.g. "26626X37X705sq1#0|26626X37X705sq1#1|26626X37X705sq3#0|26626X37X705sq3#1|26626X37X705sq5#0|26626X37X705sq5#1" 'valid' => 0 // 1 if the current answers pass all of the validation criteria for the question 'validEqn' => // the auto-generated validation criteria, based upon advanced question attributes -- e.g. "((count(if(count(26626X37X705sq1#0.NAOK,26626X37X705sq1#1.NAOK)==2,1,''), if(count(26626X37X705sq2#0.NAOK,26626X37X705sq2#1.NAOK)==2,1,''), if(count(26626X37X705sq3#0.NAOK,26626X37X705sq3#1.NAOK)==2,1,''), if(count(26626X37X705sq4#0.NAOK,26626X37X705sq4#1.NAOK)==2,1,''), if(count(26626X37X705sq5#0.NAOK,26626X37X705sq5#1.NAOK)==2,1,'')) >= (minSelect)) and (count(if(count(26626X37X705sq1#0.NAOK,26626X37X705sq1#1.NAOK)==2,1,''), if(count(26626X37X705sq2#0.NAOK,26626X37X705sq2#1.NAOK)==2,1,''), if(count(26626X37X705sq3#0.NAOK,26626X37X705sq3#1.NAOK)==2,1,''), if(count(26626X37X705sq4#0.NAOK,26626X37X705sq4#1.NAOK)==2,1,''), if(count(26626X37X705sq5#0.NAOK,26626X37X705sq5#1.NAOK)==2,1,'')) <= (maxSelect)))" 'prettyValidEqn' => // syntax-highlighted version of validEqn, only showing syntax errors 'validTip' => // html fragment to insert for the validation tip -- e.g. "

Please select between 1 and 3 answer(s)
" 'prettyValidTip' => // version of validTip that can be parsed by EM to create dynmamic validation -- e.g. "
Please select between {fixnum(minSelect)} and {fixnum(maxSelect)} answer(s)
" 'validJS' => // JavaScript fragment that can perform validation. This is the result of parsing validEqn -- e.g. "LEMif(LEManyNA('minSelect', 'maxSelect'),'',(((LEMcount(LEMif(LEMcount(LEMval('26626X37X705sq1#0.NAOK') , LEMval('26626X37X705sq1#1.NAOK') ) == 2, 1, ''), LEMif(LEMcount(LEMval('26626X37X705sq2#0.NAOK') , LEMval('26626X37X705sq2#1.NAOK') ) == 2, 1, ''), LEMif(LEMcount(LEMval('26626X37X705sq3#0.NAOK') , LEMval('26626X37X705sq3#1.NAOK') ) == 2, 1, ''), LEMif(LEMcount(LEMval('26626X37X705sq4#0.NAOK') , LEMval('26626X37X705sq4#1.NAOK') ) == 2, 1, ''), LEMif(LEMcount(LEMval('26626X37X705sq5#0.NAOK') , LEMval('26626X37X705sq5#1.NAOK') ) == 2, 1, '')) >= (LEMval('minSelect') )) && (LEMcount(LEMif(LEMcount(LEMval('26626X37X705sq1#0.NAOK') , LEMval('26626X37X705sq1#1.NAOK') ) == 2, 1, ''), LEMif(LEMcount(LEMval('26626X37X705sq2#0.NAOK') , LEMval('26626X37X705sq2#1.NAOK') ) == 2, 1, ''), LEMif(LEMcount(LEMval('26626X37X705sq3#0.NAOK') , LEMval('26626X37X705sq3#1.NAOK') ) == 2, 1, ''), LEMif(LEMcount(LEMval('26626X37X705sq4#0.NAOK') , LEMval('26626X37X705sq4#1.NAOK') ) == 2, 1, ''), LEMif(LEMcount(LEMval('26626X37X705sq5#0.NAOK') , LEMval('26626X37X705sq5#1.NAOK') ) == 2, 1, '')) <= (LEMval('maxSelect') )))))" 'invalidSQs' => // current list of subquestions that fail validation criteria -- e.g. "26626X37X705sq1#0|26626X37X705sq1#1|26626X37X705sq2#0|26626X37X705sq2#1|26626X37X705sq3#0|26626X37X705sq3#1|26626X37X705sq4#0|26626X37X705sq4#1|26626X37X705sq5#0|26626X37X705sq5#1" 'relevantSQs' => // current list of subquestions that are relevant -- e.g. "26626X37X705sq1#0|26626X37X705sq1#1|26626X37X705sq2#0|26626X37X705sq2#1|26626X37X705sq3#0|26626X37X705sq3#1|26626X37X705sq4#0|26626X37X705sq4#1|26626X37X705sq5#0|26626X37X705sq5#1" 'irrelevantSQs' => // current list of subquestions that are irrelevant -- e.g. "26626X37X705sq2#0|26626X37X705sq2#1|26626X37X705sq4#0|26626X37X705sq4#1" 'subQrelEqn' => // TODO - ?? 'mandViolation' => 0 // 1 if the question is mandatory and fails the mandatory criteria 'anyUnanswered' => 1 // 1 if any parts of the question are unanswered 'mandTip' => '' // message to display if the question fails mandatory criteria 'message' => '' // TODO ?? 'updatedValues' => // array of values that should be updated for this question, as [$sgqa] = $value 'sumEqn' => '' // 'sumRemainingEqn' => '' // );

$currentQuestionSeq

for Question-by-Question mode, the 0-based index

private int $currentQuestionSeq
Tags
example

3

$debugLevel

sum of LEM_DEBUG constants - use bitwise AND comparisons to identify which parts to use

private int $debugLevel = 0

$debugTimingMsg

Message generated to show debug timing values, if debugLevel includes LEM_DEBUG_TIMING

private string $debugTimingMsg = ''

$gRelInfo

array of Group-level relevance status Indexed by gseq; only shows groups that have been visited

private array<string|int, mixed> $gRelInfo = []
Tags
example

[1] = array( 'gseq' => 1 // group sequence 'eqn' => '' // the group-level relevance 'result' => 1 // result of processing the group-level relevance 'numJsVars' => 0 // the number of on-page javascript variables in the group-level relevance equation 'relevancejs' => '' // the javascript version of the relevance equation 'relevanceVars' => '' // the pipe-delimited list of on-page javascript variable names used within the group-level relevance equation 'prettyPrint' => '' // a pretty-print version of the group-level relevance equation, only if there are errors );

$groupId2groupSeq

map of gid to 0-based sequence number of groups

private array<string|int, mixed> $groupId2groupSeq
Tags
example

[10] = 0 // means that the first group (gseq=0) has gid=10

$groupSeqInfo

array of info about each Group, indexed by GroupSeq

private array<string|int, mixed> $groupSeqInfo
Tags
example

[2] = array( 'qstart' => 9 // the first qseq within that group 'qend' => 13 //the last qseq within that group );

$gseq2info

array of group sequence number to static info One entry per group, indexed on gseq

private array<string|int, mixed> $gseq2info
Tags
example

[0] = array( 'group_order' => 0 // gseq 'gid' => "34" // group id 'group_name' => 'G2' // the group title 'description' => // the description of the group (e.g. gtitle) 'grelevance' => '' // the group-level relevance );

$gseq2relevanceStatus

tracks which groups have at least one relevant, non-hidden question

private array<string|int, mixed> $gseq2relevanceStatus
Tags
example

[2] = 0 // means that the third group (gseq==2) is currently irrelevant

$indexGseq

array of information needed to generate navigation index in group-by-group mode One entry for each group, indexed by gseq

private array<string|int, mixed> $indexGseq
Tags
example

[0] = array( 'gtext' => // the description for the group 'gname' => 'G1' // the group title 'gid' => '34' // the group id 'anyUnanswered' => 0 // 1 if any questions within the group are unanswered 'anyErrors' => 0 // 1 if any of the questions within the group fail either validity or mandatory constraints 'valid' => 1 // 1 if at least question in the group is relevant and non-hidden 'mandViolation' => 0 // 1 if at least one relevant, non-hidden question in the group fails mandatory constraints 'show' => 1 // 1 if there is at least one relevant, non-hidden question within the group );

$indexQseq

array of information needed to generate navigation index in question-by-question mode One entry for each question, indexed by qseq

private array<string|int, mixed> $indexQseq
Tags
example

[4] = array( 'qid' => "700" // the question id 'qtext' => 'How old are you?' // the question text 'qcode' => 'age' // the variable name 'qhelp' => '' // the help text 'anyUnanswered' => 0 // 1 if there are any subquestions answered. Used for index display 'anyErrors' => 0 // 1 if there are any errors among the subquestions. Could be used for index display 'show' => 1 // 1 if there are any relevant, non-hidden subquestions. Only if so, then display the index entry 'gseq' => 0 // the group sequence 'gtext' => // text description for the group 'gname' => 'G1' // the group title 'gid' => "34" // the group id 'mandViolation' => 0 // 1 if the question as a whole fails the mandatory criteria 'valid' => 1 // 0 if any part of the question fails validation criteria. );

$initialized

True (1) if calling LimeExpressionManager functions between StartSurvey and FinishProcessingPage Used (mostly deprecated) to detect calls to LEM which happen outside of the normal processing scope

private bool $initialized = \false

$invalidAnswerString

Array of invalid answer, key is sgq, value is the clear string to be shown Must be always unset after using (EM are in $_SESSION and never new ....)

private array<string|int, string> $invalidAnswerString = []

$jsVar2qid

array of mappings of JavaScript Variable names to Question number (qid)

private array<string|int, mixed> $jsVar2qid
Tags
example

['java38612X13X161other'] = '161'

$knownVars

Collection of variable attributes, indexed by SGQA code

private array<string|int, mixed> $knownVars = []

Actual variables are stored in this structure: $knownVars[$sgqa] = array( 'jsName_on' => // the name of the javascript variable if it is defined on the current page - often 'answerSGQA' 'jsName' => // the name of the javascript variable when referenced on different pages - usually 'javaSGQA' 'readWrite' => // 'Y' for yes, 'N' for no - currently not used 'hidden' => // 1 if the question attribute 'hidden' is true, otherwise 0 'question' => // the text of the question (or subquestion) 'qid' => // the numeric question id - e.g. the Q part of the SGQA name 'gid' => // the numeric group id - e.g. the G part of the SGQA name 'grelevance' => // the group level relevance string 'relevance' => // the question level relevance string 'qcode' => // the qcode-style variable name for this question (or subquestion) 'qseq' => // the 0-based index of the question within the survey 'gseq' => // the 0-based index of the group within the survey 'type' => // the single character type code for the question 'sgqa' => // the SGQA name for the variable 'ansList' => // ansArray converted to a JavaScript fragment - e.g. ",'answers':{ 'M':'Male','F':'Female'}" 'ansArray' => // PHP array of answer strings, keyed on the answer code = e.g. array['M']='Male'; 'scale_id' => // '0' for most answers. '1' for second scale within dual-scale questions 'rootVarName' => // the root code / name / title for the question, without any subquestion or answer-level suffix. This is from the title column in the questions table 'subqtext' => // the subquestion text 'rowdivid' => // the JavaScript ID of the row identifier for a question. This is used to show/hide entire question rows 'onlynum' => // 1 if only numbers are allowed for this variable. If so, then extra processing is needed to ensure that can use comma as a decimal separator );

Reserved variables (e.g. TOKEN:xxxx) are stored with this structure: $knownVars[$token] = array( 'code' => // the static value for the variable 'type' => // '' 'jsName_on' => // '' 'jsName' => // '' 'readWrite' => // 'N' - since these are always read-only variables );

$lastMoveResult

last result of NavigateForwards, NavigateBackwards, or JumpTo Array of status information about last movement, whether at question, group, or survey level

private array<string|int, mixed>|null $lastMoveResult = \null
Tags
example

= array( 'finished' => 0 // 1 if the survey has been completed and needs to be finalized 'message' => '' // any error message that needs to be displayed 'seq' => 1 // the sequence count, using gseq, or qseq units if in 'group' or 'question' mode, respectively 'mandViolation' => 0 // whether there was any violation of mandatory constraints in the last movement 'valid' => 0 // 1 if the last movement passed all validation constraints. 0 if there were any validation errors 'unansweredSQs' => // pipe-separated list of any subquestions that were not answered 'invalidSQs' => // pipe-separated list of any subquestions that failed validation constraints );

$maxGroupSeq

the maximum groupSeq reached - this is needed for Index

private int $maxGroupSeq

$maxQuestionSeq

the maximum Question reached sequencly ordered, used to show error to the user if we stop before this step with indexed survey.

private int $maxQuestionSeq = -1

In question by question mode : $maxQuestionSeq==$SESSION['survey'.surveyid]['maxstep'], use it ?

$multiflexiAnswers

array of 2nd scale answer lists for types ':' and ';' -- needed for convenient print of logic file Indexed on qid; available for all questions

private array<string|int, mixed> $multiflexiAnswers
Tags
example

[706] = array( '1~1' => '1|Never', '1~2' => '2|Sometimes', '1~3' => '3|Always' );

$numGroups

Number of groups in survey (number of possible pages to display)

private int $numGroups = 0

$numQuestions

Numer of questions in survey (counting display-only ones?)

private int $numQuestions = 0

$pageRelevanceInfo

Array of relevance information for each page (gseq), indexed by gseq.

private array<string|int, mixed> $pageRelevanceInfo

Within a page, it contains a sequential list of the results of each relevance equation processed array( 'qid' => // question id -- e.g. 154 'gseq' => // 0-based group sequence -- e.g. 2 'eqn' => // the raw relevance equation parsed -- e.g. "!is_empty(p2_sex)" 'result' => // the Boolean result of parsing that equation in the current context -- e.g. 0 'numJsVars' => // the number of dynamic JavaScript variables used in that equation -- e.g. 1 'relevancejs' => // the actual JavaScript to insert for that relevance equation -- e.g. "LEMif(LEManyNA('p2_sex'),'',( ! LEMempty(LEMval('p2_sex') )))" 'relevanceVars' => // a pipe-delimited list of JavaScript variables upon which that equation depends -- e.g. "java38612X12X153" 'jsResultVar' => // the JavaScript variable in which that result will be stored -- e.g. "java38612X12X154" 'type' => // the single character type of the question -- e.g. 'S' 'hidden' => // 1 if the question should always be hidden 'hasErrors' => // 1 if there were parsing errors processing that relevance equation

$pageTailorInfo

private array<string|int, mixed>|null $pageTailorInfo

Array of array of information about HTML id to update with javascript function [[ 'questionNum' : question number 'num' : internal number of javascript function 'id' : id of HTML element 'raw' : Raw Expression 'result' : 'vars' : var used in javascript function 'js' : final javascript function ]]

$ParseResultCache

temporary variable to reduce need to parse same equation multiple times. Used for relevance and validation Array, indexed on equation, providing the following information:

private array<string|int, mixed> $ParseResultCache
Tags
example

['!is_empty(num)'] = array( 'result' => 1 // result of processing the equation in the current scope 'prettyPrint' => '' // syntax-highlighted version of equation if there are any errors 'hasErrors' => 0 // 1 if there are any syntax errors );

$processedRelevance

True (1) if have already processed the relevance equations (so don't need to do it again)

private bool $processedRelevance = \false

$q2subqInfo

/** mapping of questions to information about their subquestions.

private array<string|int, mixed> $q2subqInfo

One entry per question, indexed on qid

Tags
example

[702] = array( 'qid' => 702 // the question id 'qseq' => 6 // the question sequence 'gseq' => 0 // the group sequence 'sgqa' => '26626X34X702' // the root of the SGQA code (reallly just the SGQ) 'varName' => 'afSrcFilter_sq1' // the full qcode variable name - note, if there are subquestions, don't use this one. 'type' => 'M' // the one-letter question type 'fieldname' => '26626X34X702sq1' // the fieldname (used as JavaScript variable name, and also as database column name 'rootVarName' => 'afDS' // the root variable name 'preg' => '/[A-Z]+/' // regular expression validation equation, if any 'subqs' => array() of subquestions, where each contains: 'rowdivid' => '26626X34X702sq1' // the javascript id identifying the question row (so array_filter can hide rows) 'varName' => 'afSrcFilter_sq1' // the full variable name for the subquestion 'jsVarName_on' => 'java26626X34X702sq1' // the JavaScript variable name if the variable is defined on the current page 'jsVarName' => 'java26626X34X702sq1' // the JavaScript variable name to use if the variable is defined on a different page 'csuffix' => 'sq1' // the SGQ suffix to use for a fieldname 'sqsuffix' => '_sq1' // the suffix to use for a qcode variable name );

$qans

array of enumerated answer lists indexed by qid These use a tilde syntax to indicate which scale the answer is part of.

private array<string|int, mixed> $qans
Tags
example

['0~4'] = "4|Child" // this means that code 4 in scale 0 has a coded value of 4 and a display value of 'Child'

example

(for [705]): ['1~2'] = '2|Sometimes' // this means that the second scale for this question uses the coded value of 2 to represent 'Sometimes'

example

// TODO - add example from survey using assessments

$qattr

array of advanced question attributes for each question Indexed by qid; available for all quetions

private array<string|int, mixed> $qattr
Tags
example

[784] = array( 'array_filter_exclude' => 'afSrcFilter' 'exclude_all_others' => 'sq5' 'max_answers' => '3' 'min_answers' => '1' 'other_replace_text' => '{afSrcFilter_other}' );

$qcode2sgq

maps name of the variable to the SGQ name (without the A suffix)

private array<string|int, mixed> $qcode2sgq
Tags
example

['p1_sex'] = "38612X10X147"

example

['afDS_sq1_1'] = "26626X37X705sq1#1"

$qcode2sgqa

maps qcode varname to SGQA code

private array<string|int, mixed>|null $qcode2sgqa
Tags
example

['gender'] = '38612X10X145'

$qid2code

array of mappings of Question # (qid) to pipe-delimited list of SGQA codes used within it

private array<string|int, mixed> $qid2code
Tags
example

[150] = "38612X11X150|38612X11X150other"

$qid2exclusiveAuto

Array, keyed on qid, to JavaScript and list of variables needed to implement exclude_all_others_auto

private array<string|int, mixed> $qid2exclusiveAuto = []

$qid2validationEqn

maps question # to the validation equation(s) for that question.

private array<string|int, mixed> $qid2validationEqn

These are grouped by qid then validation type, such as 'value_range', and 'num_answers'

Tags
example

[703] = array( 'eqn' => array( 'value_range' = "((is_empty(26626X34X703.NAOK) || 26626X34X703.NAOK >= (0)) and (is_empty(26626X34X703.NAOK) || 26626X34X703.NAOK <= (5)))" ), 'tips' => array( 'value_range' = "Each answer must be between {fixnum(0)} and {fixnum(5)}" ), 'subqValidEqns' = array( [] = array( 'subqValidSelector' => '' // 'subqValidEqn' => "(is_empty(26626X34X703.NAOK) || 26626X34X703.NAOK >= (0)) && (is_empty(26626X34X703.NAOK) || 26626X34X703.NAOK <= (5))" ), 'sumEqn' => '' // the equation to compute the current sum of the responses 'sumRemainingEqn' => '' // the equation to how much is left (for the question attribute that lets you specify the exact value of the sum of the answers) );

$qrootVarName2arrayFilter

Linked list of array filters

private array<string|int, mixed> $qrootVarName2arrayFilter = []

$questionId2groupSeq

map question # to the group it is within, using an incremental count of group order

private array<string|int, mixed> $questionId2groupSeq
Tags
example

[157] = 2 // means that qid 157 is in the 3rd page of questions (gseq = 2)

$questionId2questionSeq

map question # to an incremental count of question order across the whole survey

private array<string|int, mixed> $questionId2questionSeq
Tags
example

[157] = 13 // means that that 14th question in the survey has qid=157

$questionSeq2relevance

keeps relevance in proper sequence so can minimize relevance processing to see what should be see on page and in indexes Array is indexed on qseq

private array<string|int, mixed> $questionSeq2relevance
Tags
example

[3] = array( 'relevance' => "!is_empty(num)" // the question-level relevance equation 'grelevance' => "" // the group-level relevance equation 'qid' => "699" // the question id 'qseq' => 3 // the 0-index question sequence 'gseq' => 0 // the 0-index group sequence 'jsResultVar_on' => 'answer26626X34X699' // the javascript variable holding the input value 'jsResultVar' => 'java26226X34X699' // the javascript variable (often hidden) holding the value to be submitted 'type' => 'N' // the one character question type 'hidden' => 0 // 1 if it should be always_hidden 'gid' => "34" // group id 'mandatory' => 'N' // 'Y' if mandatory, 'S' if soft mandatory 'eqn' => "" // TODO ?? 'help' => "" // the help text 'qtext' => "Enter a larger number than {num}" // the question text 'code' => 'afDS_sq5_1' // the full variable name 'other' => 'N' // whether the question supports the 'other' option - 'Y' if true 'rowdivid' => '2626X37X705sq5' // the javascript id for the row - in this case, the 5th subquestion 'aid' => 'sq5' // the answer id 'sqid' => '791' // the subquestion's qid (only populated for some question types) );

$runtimeTimings

Array of timing information to debug how long it takes for portions of LEM to run.

private array<string|int, mixed> $runtimeTimings = []

Array of timing information (in seconds) for EM to help with debugging

Tags
example

[1] = array( [0]="LimeExpressionManager::NavigateForwards" [1]=1.7079849243164 );

$sgqaNaming

used to specify whether to generate equations using SGQA codes or qcodes Default is to convert all qcode naming to sgqa naming when generating javascript, as that provides the greatest backwards compatibility TSV export of survey structure sets this to false so as to force use of qcode naming

private bool $sgqaNaming = \true

$sPreviewMode

sPreviewMode used for relevance equation and to disable save value in DB 'question' or 'group' string force relevance to 1 if needed

private string|false $sPreviewMode = \false

$subQrelInfo

list of needed subquestion relevance (e.g. array_filter) Indexed by qid then sgqa; only generated for current group of questions

private array<string|int, mixed> $subQrelInfo = []
Tags
example

[708][26626X37X708sq2] = array( 'qid' => '708' // the question id 'eqn' => "((26626X34X702sq2 != ''))" // the auto-generated subquestion-level relevance equation 'prettyPrintEqn' => '' // only generated if there errors - shows syntax highlighting of them 'result' => 0 // result of processing the subquestion-level relevance equation in the current context 'numJsVars' => 1 // the number of on-page javascript variables in 'eqn' 'relevancejs' => // the generated javascript from 'eqn' -- e.g. "LEMif(LEManyNA('26626X34X702sq2'),'',(((LEMval('26626X34X702sq2') != ""))))" 'relevanceVars' => "java26626X34X702sq2" // the pipe-separated list of on-page javascript variables in 'eqn' 'rowdivid' => "26626X37X708sq2" // the javascript id of the question row (so can apply array_filter) 'type' => 'array_filter' // semicolon delimited list of types of subquestion relevance filters applied 'qtype' => 'A' // the single character question type 'sgqa' => "26626X37X708" // the SGQ portion of the fieldname 'hasErrors' => 0 // 1 if there are any parse errors in the subquestion validation equations );

$surveyMode

survey mode. One of 'survey', 'group', or 'question'

private string $surveyMode = 'group'

$surveyOptions

a set of global survey options passed from LimeSurvey

private array<string|int, mixed> $surveyOptions = []

For example, array( 'rooturl' => // URL prefix needed to be able to click on a syntax-highlighted variable name and have it open the needed editting window 'hyperlinkSyntaxHighlighting' => // true if should be able to click on variables to edit them 'active' => // 0 for inactive, 1 for active survey 'allowsave' => // 0 for do not allow save; 1 for allow save 'anonymized' => // 1 for anonymous 'assessments' => // 1 for use assessments 'datestamp' => // 1 for use date stamps 'ipaddr' => // 1 for capture IP address 'radix' => // '.' for use period as decimal separator; ',' for use comma as decimal separator 'savetimings' => // "Y" if should save survey timings 'startlanguage' => // the starting language -- e.g. 'en' 'surveyls_dateformat' => // the index of the language specific date format -- e.g. 1 'tablename' => // the name of the table storing the survey data, if active -- e.g. lime_survey_38612 'target' => // the path for uploading files -- e.g. '/temp/files/' 'timeadjust' => // the time offset -- e.g. 0 'tempdir' => // the temporary directory for uploading files -- e.g. '/temp/' );

$tempVars

variables temporarily set for substitution purposes temporarily mean for this page, until reset. Not for next page

private array<string|int, mixed> $tempVars = []

These are typically the LimeReplacement Fields passed in via templatereplace() Each has the following structure: array( 'code' => // the static value of the variable 'jsName_on' => // '' 'jsName' => // '' 'readWrite' => // 'N' );

$updatedValues

Array of values to be updated

private array<string|int, mixed> $updatedValues = []

$varNameAttr

JavaScript array of mappings of canonical JavaScript variable name to key attributes.

private array<string|int, mixed> $varNameAttr

These fragments are used to create the JavaScript varNameAttr array.

Tags
example

['java38612X11X147'] = "'java38612X11X147':{ 'jsName':'java38612X11X147','jsName_on':'java38612X11X147','sgqa':'38612X11X147','qid':147,'gid':11,'type':'G','default':'','rowdivid':'','onlynum':'','gseq':1,'answers':{ 'M':'Male','F':'Female'}}"

example

['java26626X37X705sq1#1'] = "'java26626X37X705sq1#1':{ 'jsName':'java26626X37X705sq1#1','jsName_on':'java26626X37X705sq1#1','sgqa':'26626X37X705sq1#1','qid':705,'gid':37,'type':'1','default':'','rowdivid':'26626X37X705sq1','onlynum':'','gseq':1,'answers':{ '0~1':'1|Low','0~2':'2|Medium','0~3':'3|High','1~1':'1|Never','1~2':'2|Sometimes','1~3':'3|Always'}}"

Methods

_CreateSubQLevelRelevanceAndValidationEqns()

Process all question attributes that apply to EM (1) subquestion-level relevance: e.g. array_filter, array_filter_exclude, relevance equations entered in SQ-mask (2) Validations: e.g. min/max number of answers; min/max/eq sum of answers

public _CreateSubQLevelRelevanceAndValidationEqns([int|null $onlyThisQseq = null ]) : void
Parameters
$onlyThisQseq : int|null = null
  • only process these attributes for the specified question

_ValidateGroup()

Check a group and all of the questions it contains

public _ValidateGroup(int $groupSeq[, bool $force = false ]) : array<string|int, mixed>
Parameters
$groupSeq : int
  • the index-0 sequence number for this group
$force : bool = false

: force validation to true, even if there are error

Return values
array<string|int, mixed>

Detailed information about this group

_ValidateQuestion()

For the current set of questions (whether in survey, gtoup, or question-by-question mode), assesses the following: (a) mandatory - if so, then all relevant subquestions must be answered (e.g. pay attention to array_filter and array_filter_exclude) (b) always-hidden (c) relevance status - including subquestion-level relevance (d) answered - if $_SESSION[$LEM->sessid][sgqa]=='' or NULL, then it is not answered (e) validity - whether relevant questions pass their validity tests

public _ValidateQuestion(int $questionSeq[, bool $force = false ]) : array<string|int, mixed>
Parameters
$questionSeq : int
  • the 0-index sequence number for this question
$force : bool = false

: force validation to true, even if there are error, this allow to save in DB even with error

Return values
array<string|int, mixed>

Array of information about this question and its subquestions

addFrontendFlashMessage()

Add a flash message to state-key 'frontend{survey ID}' The flash messages are templatereplaced in startpage.tstpl, {FLASHMESSAGE}

public static addFrontendFlashMessage(string $type, string $message, int $surveyid) : void
Parameters
$type : string

Yii type of flash: error, notice, 'success'

$message : string
$surveyid : int
Tags
todo

: validate if it work : unsure it was shown always to user (nojs ?)

addValidityString()

Set or log an invalid answer string

public addValidityString(string $sgqa, mixed $value, string $message[, bool $add = true ]) : void
Parameters
$sgqa : string

: the SGQ (answer column / SGQA)

$value : mixed
$message : string

: the message

$add : bool = true

: add it to current validity or only og it

ConvertConditionsToRelevance()

If $qid is set, returns the relevance equation generated from conditions (or NULL if there are no conditions for that $qid) If $qid is NULL, returns an array of relevance equations generated from Condition, keyed on the question ID

public static ConvertConditionsToRelevance(int $surveyId[, int|null $qid = null ]) : array<string|int, mixed>
Parameters
$surveyId : int
$qid : int|null = null
  • if passed, only generates relevance equation for that question - otherwise genereates for all questions with conditions
Return values
array<string|int, mixed>

of generated relevance strings, indexed by $qid

convertNonLatinNumerics()

Convert non-latin numerics in string to latin numerics Used for datepicker (Hindi, Arabic numbers)

public static convertNonLatinNumerics(string $str, string $lang) : string
Parameters
$str : string
$lang : string
Return values
string

FinishProcessingGroup()

Should be called after each group finishes

public static FinishProcessingGroup([bool|null $skipReprocessing = false ]) : void
Parameters
$skipReprocessing : bool|null = false

FinishProcessingPage()

Should be called at end of each page

public static FinishProcessingPage() : void

FinishProcessPublicPage()

End public HTML

public static FinishProcessPublicPage([mixed $applyJavaScriptAnyway = false ]) : string|null
Parameters
$applyJavaScriptAnyway : mixed = false
Tags
todo

: add directly hidden input in page without return it.

Return values
string|null

: hidden inputs needed for relevance

GetAllVarNamesForQ()

Expand "self.suffix" and "that.qcode.suffix" into canonical list of variable names

public static GetAllVarNamesForQ(int $qseq, string $varname) : string
Parameters
$qseq : int
$varname : string
Return values
string

getAnswerSetsForEM()

Return array of language-specific answer codes

public getAnswerSetsForEM([int|null $surveyid = null ][, string|null $lang = null ]) : array<string|int, mixed>
Parameters
$surveyid : int|null = null
$lang : string|null = null
Return values
array<string|int, mixed>

GetDebugTimingMessage()

Return a formatted table showing how much time each part of EM consumed

public static GetDebugTimingMessage() : string
Return values
string

getEMlanguage()

Get the current public language

public static getEMlanguage() : string
Return values
string

GetGroupIndexInfo()

Get array of info needed to display the Group Index

public static GetGroupIndexInfo([string $gseq = null ]) : array<string|int, mixed>
Parameters
$gseq : string = null
Return values
array<string|int, mixed>

getGroupInfoForEM()

Returns group info needed for indexes

public getGroupInfoForEM(int $surveyid[, string|null $sLanguage = null ]) : array<string|int, mixed>
Parameters
$surveyid : int
$sLanguage : string|null = null
Return values
array<string|int, mixed>

GetGroupSeq()

Translate GID to 0-index Group Sequence number

public static GetGroupSeq(int $gid) : int
Parameters
$gid : int
Return values
int

GetLastMoveResult()

Get last move information, optionally clearing the substitution cache

public static GetLastMoveResult([bool $clearSubstitutionInfo = false ]) : array<string|int, mixed>|null
Parameters
$clearSubstitutionInfo : bool = false
Return values
array<string|int, mixed>|null

GetLastPrettyPrintExpression()

Used to show potential syntax errors of processing Relevance or Equations.

public static GetLastPrettyPrintExpression() : string
Return values
string

getLEMqcode2sgqa()

Return array database name as key, LEM name as value

public static getLEMqcode2sgqa(int $iSurveyId) : array<string|int, mixed>
Parameters
$iSurveyId : int
Return values
array<string|int, mixed>

*@example (['gender'] => '38612X10X145')

getLEMsurveyId()

Returns the survey ID of the EM singleton

public static getLEMsurveyId() : int
Return values
int

GetQuestionIndexInfo()

Get array of info needed to display the Question Index

public static GetQuestionIndexInfo() : array<string|int, mixed>
Return values
array<string|int, mixed>

GetQuestionSeq()

Get question sequence number from QID

public static GetQuestionSeq(int $qid) : int
Parameters
$qid : int
Return values
int

GetQuestionStatus()

public static GetQuestionStatus(mixed $qid) : mixed
Parameters
$qid : mixed

getRegexpValidAttributes()

Return the regexp used to check if suffix is valid

public static getRegexpValidAttributes() : string
Return values
string

GetRelevanceAndTailoringJavaScript()

public static GetRelevanceAndTailoringJavaScript([mixed $bReturnArray = false ]) : mixed
Parameters
$bReturnArray : mixed = false

GetStepIndexInfo()

Return entries needed to build the navigation index

public static GetStepIndexInfo([int|null $step = null ]) : array<string|int, mixed>
Parameters
$step : int|null = null
  • if specified, return a single value, otherwise return entire array
Return values
array<string|int, mixed>
  • will be either question or group-level, depending upon $surveyMode

getUpdatedValues()

public getUpdatedValues() : array<string|int, mixed>
Return values
array<string|int, mixed>

GetVarAttribute()

public static GetVarAttribute(mixed $name, string|null $attr, mixed $default, int $gseq, int $qseq) : mixed
Parameters
$name : mixed
$attr : string|null
$default : mixed
$gseq : int
$qseq : int

GroupIsIrrelevantOrHidden()

Return whether group $gseq is relevant

public static GroupIsIrrelevantOrHidden(int $gseq) : bool
Parameters
$gseq : int
Return values
bool

GroupIsRelevant()

Returns true if the group is relevant and should be shown

public static GroupIsRelevant(int $gid) : bool
Parameters
$gid : int
Return values
bool

htmlSpecialCharsUserValue()

return a value entered by user to be shown or used in expression

public static htmlSpecialCharsUserValue(string $string) : string
Parameters
$string : string
Return values
string

isInitialized()

Did LEM is currently initialized

public static isInitialized() : bool
Return values
bool

isValidVariable()

public static isValidVariable(mixed $varName) : mixed
Parameters
$varName : mixed

JumpTo()

Jump to a specific question or group sequence. If jumping forward, it re-validates everything in between

public static JumpTo(int $seq[, string|false $preview = false ][, bool $processPOST = true ][, bool $force = false ][, bool $changeLang = false ]) : array<string|int, mixed>
Parameters
$seq : int
  • the sequential step
$preview : string|false = false

@see var $sPreviewMode

$processPOST : bool = true
  • add the updated value to be saved in the database
$force : bool = false
  • if true, then skip validation of current group (e.g. will jump even if there are errors)
$changeLang : bool = false
Return values
array<string|int, mixed>

$this->lastMoveResult

loadTokenInformation()

This function loads the relevant data about tokens for a survey.

public loadTokenInformation(int $iSurveyId[, string|null $sToken = null ][, bool|null $bAnonymize = false ]) : void

If specific token is not given it loads empty values, this is used for question previewing and the like.

Parameters
$iSurveyId : int
$sToken : string|null = null
$bAnonymize : bool|null = false

NavigateForwards()

public static NavigateForwards([bool $force = false ]) : array<string|int, mixed>|null
Parameters
$force : bool = false
  • if true, continue to go forward even if there are violations to the mandatory and/or validity rules
Return values
array<string|int, mixed>|null
  • lastMoveResult

ProcessAllNeededRelevance()

Check the relevance status of all questions on or before the current group.

public ProcessAllNeededRelevance([string|null $onlyThisQseq = null ][, mixed $groupSeq = null ]) : void

This generates needed JavaScript for dynamic relevance, and sets flags about which questions and groups are relevant

Parameters
$onlyThisQseq : string|null = null
$groupSeq : mixed = null

ProcessCurrentResponses()

Cleanse the $_POSTed data and update $_SESSION variables accordingly

public static ProcessCurrentResponses() : mixed

ProcessRelevance()

Compute Relevance, processing $eqn to get a boolean value. If there are syntax errors, return false.

public static ProcessRelevance(string $eqn[, string $questionNum = null ][, string $jsResultVar = null ][, string $type = null ][, int $hidden = 0 ]) : bool
Parameters
$eqn : string
  • the relevance equation
$questionNum : string = null
  • needed to align question-level relevance and tailoring
$jsResultVar : string = null
  • this variable determines whether irrelevant questions are hidden
$type : string = null
  • question type
$hidden : int = 0
  • whether question should always be hidden
Return values
bool

ProcessStepString()

Translate all Expressions, Macros, registered variables, etc. in $string for current step

public static ProcessStepString(string|null $string[, array<string|int, mixed> $replacementFields = [] ][, int $numRecursionLevels = 3 ][, bool $static = false ]) : string
Parameters
$string : string|null
  • the string to be replaced
$replacementFields : array<string|int, mixed> = []
  • optional replacement values
$numRecursionLevels : int = 3
  • the number of times to recursively subtitute values in this string
$static : bool = false
  • return static string (without any javascript)
Return values
string
  • the original $string with all replacements done.

ProcessString()

Translate all Expressions, Macros, registered variables, etc. in $string

public static ProcessString(string|null $string[, int $questionNum = null ][, array<string|int, mixed>|null $replacementFields = [] ][, int $numRecursionLevels = 1 ][, int $whichPrettyPrintIteration = 1 ][, bool $noReplacements = false ][, bool $timeit = true ][, bool $staticReplacement = false ]) : string
Parameters
$string : string|null
  • the string to be replaced
$questionNum : int = null
  • the $qid of question being replaced - needed for properly alignment of question-level relevance and tailoring
$replacementFields : array<string|int, mixed>|null = []
  • optional replacement values
$numRecursionLevels : int = 1
  • the number of times to recursively subtitute values in this string
$whichPrettyPrintIteration : int = 1
  • if want to pretty-print the source string, which recursion level should be pretty-printed
$noReplacements : bool = false
  • true if we already know that no replacements are needed (e.g. there are no curly braces)
$timeit : bool = true
$staticReplacement : bool = false
  • return HTML string without the system to update by javascript
Return values
string
  • the original $string with all replacements done.

QuestionIsRelevant()

Return whether question $qid is relevanct

public static QuestionIsRelevant(int $qid) : bool
Parameters
$qid : int
Return values
bool

resetTempVars()

Reset the current temporary variable replacement Done automatically when page start or page finish ( @param array $vars

public static resetTempVars() : mixed
Tags
see

self::FinishProcessPublicPage, @see self::StartProcessingPage )

RevertUpgradeConditionsToRelevance()

This reverses UpgradeConditionsToRelevance(). It removes Relevance for questions that have Condition

public static RevertUpgradeConditionsToRelevance([int|null $surveyId = null ][, int|null $qid = null ]) : int
Parameters
$surveyId : int|null = null
$qid : int|null = null
Return values
int

setCurrentQset()

Set currentQset. Used by unit-tests.

public setCurrentQset(array<string|int, mixed> $val) : void
Parameters
$val : array<string|int, mixed>

SetDirtyFlag()

Tells ExpressionScript Engine that something has changed enough that needs to eliminate internal caching

public static SetDirtyFlag() : void

SetEMLanguage()

Sets the language for ExpressionScript Engine. If the language has changed, then EM cache must be invalidated and refreshed

public static SetEMLanguage([string|null $lang = null ]) : void
Parameters
$lang : string|null = null

setKnownVars()

Used for unit tests.

public setKnownVars(mixed $val) : void
Parameters
$val : mixed

setPageRelevanceInfo()

Used for unit tests.

public setPageRelevanceInfo(mixed $info) : void
Parameters
$info : mixed

SetPreviewMode()

Set the previewmode

public static SetPreviewMode([string|false $previewmode = false ]) : void
Parameters
$previewmode : string|false = false

'question', 'group', false

SetRelevanceTo()

Set the relevance status to the $step

public static SetRelevanceTo(int $seq) : void
Parameters
$seq : int
  • the sequential step

SetSurveyId()

Set the SurveyId - really checks whether the survey you're about to work with is new, and if so, clears the LEM cache

public static SetSurveyId([int|null $sid = null ]) : mixed
Parameters
$sid : int|null = null

setTempVars()

public static setTempVars(array<string|int, mixed> $vars) : mixed
Parameters
$vars : array<string|int, mixed>

SetThisAsAliasForSGQA()

Set the 'this' variable as an alias for SGQA within the code.

public static SetThisAsAliasForSGQA(string $sgqa) : void
Parameters
$sgqa : string

setValueToKnowVar()

Helper function to update a Read only value

public static setValueToKnowVar(string $var, string $value) : mixed
Parameters
$var : string
$value : string

setVariableAndTokenMappingsForExpressionManager()

Create the arrays needed by ExpressionManager to process LimeSurvey strings.

public setVariableAndTokenMappingsForExpressionManager(int $surveyid[, bool|null $forceRefresh = false ][, bool|null $anonymized = false ]) : bool|null

The long part of this function should only be called once per page display (e.g. only if $fieldMap changes)

Parameters
$surveyid : int
$forceRefresh : bool|null = false
$anonymized : bool|null = false
Tags
todo

Keep method as-is but factor out content to new class; add unit tests for class

Return values
bool|null
  • true if $fieldmap had been re-created, so ExpressionManager variables need to be re-set

SetVariableValue()

public static SetVariableValue(string $op, string $name, float $value) : int
Parameters
$op : string
$name : string
$value : float
Return values
int

ShowStackTrace()

public static ShowStackTrace([mixed $msg = null ][, mixed &$args = null ]) : mixed
Parameters
$msg : mixed = null
$args : mixed = null

ShowSurveyLogicFile()

Create HTML view of the survey, showing everything that uses EM

public static ShowSurveyLogicFile(int $sid[, int|null $gid = null ][, mixed $qid = null ][, int|null $LEMdebugLevel = 0 ][, bool|null $assessments = null ]) : array<string|int, mixed>
Parameters
$sid : int
$gid : int|null = null
$qid : mixed = null
$LEMdebugLevel : int|null = 0
$assessments : bool|null = null
Return values
array<string|int, mixed>

SplitStringOnExpressions()

Returns an array of string parts, splitting out expressions

public static SplitStringOnExpressions(string $src) : array<string|int, mixed>
Parameters
$src : string
Return values
array<string|int, mixed>

StartProcessingGroup()

This should be called each time a new group is started, whether on same or different pages. Sets/Clears needed internal parameters.

public static StartProcessingGroup([int|null $gseq = null ][, bool|null $anonymized = false ][, int|null $surveyid = null ][, bool|null $forceRefresh = false ]) : void
Parameters
$gseq : int|null = null
  • the group sequence
$anonymized : bool|null = false
  • whether anonymized
$surveyid : int|null = null
  • the surveyId
$forceRefresh : bool|null = false
  • whether to force refresh of setting variable and token mappings (should be done rarely)

StartProcessingPage()

Should be first function called on each page - sets/clears internally needed variables

public static StartProcessingPage([bool $allOnOnePage = false ][, bool $initializeVars = false ]) : void
Parameters
$allOnOnePage : bool = false
  • true if StartProcessingGroup will be called multiple times on this page - does some optimizatinos
$initializeVars : bool = false
  • if true, initializes the replacement variables to enable syntax highlighting on admin pages

StartSurvey()

Initialize a survey so can use EM to manage navigation

public static StartSurvey(int $surveyid[, string $surveyMode = 'group' ][, array<string|int, mixed> $aSurveyOptions = null ][, bool $forceRefresh = false ][, int $debugLevel = 0 ]) : array<string|int, mixed>
Parameters
$surveyid : int
$surveyMode : string = 'group'
$aSurveyOptions : array<string|int, mixed> = null
$forceRefresh : bool = false
$debugLevel : int = 0
Return values
array<string|int, mixed>

SubQuestionIsRelevant()

Return whether a subquestion is relevant

public static SubQuestionIsRelevant(string $sgqa) : bool
Parameters
$sgqa : string
Return values
bool

UnitTestConvertConditionsToRelevance()

Return list of relevance equations generated from conditions

public static UnitTestConvertConditionsToRelevance([int|null $surveyId = null ][, int|null $qid = null ]) : array<string|int, mixed>
Parameters
$surveyId : int|null = null
$qid : int|null = null
Return values
array<string|int, mixed>

of relevance equations, indexed by $qid

UnitTestProcessStringContainingExpressions()

Unit test strings containing expressions

public static UnitTestProcessStringContainingExpressions() : mixed

UnitTestRelevance()

Unit test Relevance using a simplified syntax to represent questions.

public static UnitTestRelevance() : mixed

updateReplacementFields()

Add or replace fixed variable replacement for current page (or until self::resetTempVars was called)

public static updateReplacementFields(mixed $replacementFields) : mixed
Parameters
$replacementFields : mixed

UpgradeConditionsToRelevance()

Do bulk-update/save of Condition to Relevance

public static UpgradeConditionsToRelevance([int|null $surveyId = null ][, int|null $qid = null ]) : array<string|int, mixed>
Parameters
$surveyId : int|null = null
  • if NULL, processes the entire database, otherwise just the specified survey
$qid : int|null = null
  • if specified, just updates that one question
Return values
array<string|int, mixed>

of query strings

UpgradeQuestionAttributes()

Deprecate obsolete question attributes.

public static UpgradeQuestionAttributes([bool|null $changeDB = false ][, int|null $iSurveyID = null ][, int|null $onlythisqid = null ]) : mixed
Parameters
$changeDB : bool|null = false
  • if true, updates parameters and deletes old ones
$iSurveyID : int|null = null
  • if set, then only for that survey
$onlythisqid : int|null = null
  • if set, then only for this question ID

usingCommaAsRadix()

Returns true if the survey is using comma as the radix

public static usingCommaAsRadix() : bool
Return values
bool

__construct()

A private constructor; prevents direct creation of object

private __construct() : mixed

_GetVarAttribute()

private _GetVarAttribute(mixed $name, mixed $attr, mixed $default, int $gseq, int $qseq) : mixed
Parameters
$name : mixed
$attr : mixed
$default : mixed
$gseq : int
$qseq : int

_ProcessGroupRelevance()

private _ProcessGroupRelevance(int $groupSeq) : void
Parameters
$groupSeq : int

_ProcessRelevance()

Compute Relevance, processing $eqn to get a boolean value. If there are syntax errors, return false.

private _ProcessRelevance(string $eqn[, string $questionNum = null ][, mixed $gseq = null ][, string $jsResultVar = null ][, string $type = null ][, int $hidden = 0 ]) : bool
Parameters
$eqn : string
  • the relevance equation
$questionNum : string = null
  • needed to align question-level relevance and tailoring
$gseq : mixed = null
$jsResultVar : string = null
  • this variable determines whether irrelevant questions are hidden
$type : string = null
  • question type
$hidden : int = 0
  • whether question should always be hidden
Return values
bool

_ProcessSubQRelevance()

Create JavaScript needed to process subquestion-level relevance (e.g. for array_filter and _exclude)

private _ProcessSubQRelevance(string $eqn[, string $questionNum = null ][, string $rowdivid = null ][, string $type = null ][, string $qtype = null ][, string $sgqa = null ][, string $isExclusive = '' ][, string $irrelevantAndExclusive = '' ]) : bool
Parameters
$eqn : string
  • the equation to parse
$questionNum : string = null
  • the question number - needed to align relavance and tailoring blocks
$rowdivid : string = null
  • the javascript ID that needs to be shown/hidden in order to control array_filter visibility
$type : string = null
  • the type of subquestion relevance (e.g. 'array_filter', 'array_filter_exclude')
$qtype : string = null
$sgqa : string = null
$isExclusive : string = ''
$irrelevantAndExclusive : string = ''
Return values
bool

_recursivelyFindAntecdentArrayFilters()

Recursively find all questions that logically preceded the current array_filter or array_filter_exclude request Note, must support: (a) semicolon-separated list of $qroot codes for either array_filter or array_filter_exclude (b) mixed history of array_filter and array_filter_exclude values

private _recursivelyFindAntecdentArrayFilters(string $qroot, array<string|int, mixed> $aflist, array<string|int, mixed> $afelist) : array<string|int, mixed>
Parameters
$qroot : string
  • the question root variable name
$aflist : array<string|int, mixed>
  • the list of array_filter $qroot codes
$afelist : array<string|int, mixed>
  • the list of array_filter_exclude $qroot codes
Return values
array<string|int, mixed>

_UpdateValuesInDatabase()

Write values to database.

private _UpdateValuesInDatabase([bool $finished = false ]) : string
Parameters
$finished : bool = false
  • true if the survey needs to be finalized
Return values
string

_ValidateSurvey()

Check the entire survey

private _ValidateSurvey([bool $force = false ]) : array<string|int, mixed>
Parameters
$force : bool = false

: force validation to true, even if there are error, used at survey start to fill EM

Return values
array<string|int, mixed>

with information on validated question

checkValidityAnswer()

Check a validity of an answer, Put the string to show to user $this->invalidAnswerString See mantis #10827, #11611 and #14649

private static checkValidityAnswer(string $type, string $value, string $sgq, array<string|int, mixed> $qinfo[, bool $set = true ]) : bool
Parameters
$type : string

: question type

$value : string

: the value

$sgq : string

: the sgqa

$qinfo : array<string|int, mixed>

: an array with information from question with mandatory ['qid'=>$qid] , optional (but must be 'other'=>$other)

$set : bool = true

: update the invalid string or not. Used for #14649 (invalid default value)

Tags
throws
Exception
Return values
bool

true : if question is OK to be put in session, false if must be set to null

getConditionsForEM()

private static getConditionsForEM(mixed $surveyid[, mixed $qid = null ]) : mixed
Parameters
$surveyid : mixed
$qid : mixed = null

getQuestionAttributesForEM()

Return array of language-specific answer codes

private getQuestionAttributesForEM([int|null $surveyid = 0 ][, int|null $qid = 0 ][, string|null $lang = '' ]) : array<string|int, mixed>
Parameters
$surveyid : int|null = 0
$qid : int|null = 0
$lang : string|null = ''
Return values
array<string|int, mixed>

getValidityString()

return the actual validity string , and reset the variable used ($_SESSION)

private static getValidityString(string $sgqa) : string|null
Parameters
$sgqa : string

: the SGQ (answer name)

Return values
string|null

gT()

private gT(string $string[, mixed $escapemode = 'html' ]) : mixed
Parameters
$string : string
$escapemode : mixed = 'html'

ngT()

private ngT(string $sTextToTranslate, int $number[, mixed $escapemode = 'html' ]) : mixed
Parameters
$sTextToTranslate : string
$number : int
$escapemode : mixed = 'html'

throwFatalError()

Kills the survey session and throws an exception with the specified message.

private throwFatalError([string $message = null ]) : mixed
Parameters
$message : string = null

If empty, a default message is used.

Tags
throws
Exception

        
On this page

Search results