1<?php
2/*
3* LimeSurvey
4* Copyright (C) 2007-2011 The LimeSurvey Project Team / Carsten Schmitz
5* All rights reserved.
6* License: GNU/GPL License v2 or later, see LICENSE.php
7* LimeSurvey is free software. This version may have been modified pursuant
8* to the GNU General Public License, and as distributed it includes or
9* is derivative of works licensed under the GNU General Public License or
10* other free or open source software licenses.
11* See COPYRIGHT.php for copyright notices and details.
12*/
13
14// Security Checked: POST, GET, SESSION, REQUEST, returnGlobal, DB
15
16//if (!isset($homedir) || isset($_REQUEST['$homedir'])) {die("Cannot run this script directly");}
17
18/*
19* Let's explain what this strange $ia var means
20*
21* The $ia string comes from the $_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['insertarray'] variable which is built at the commencement of the survey.
22* See index.php, function "buildsurveysession()"
23* One $ia array zexists for every question in the survey. The $_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['insertarray']
24* string is an array of $ia arrays.
25*
26* $ia[0] => question id
27* $ia[1] => fieldname
28* $ia[2] => title
29* $ia[3] => question text
30* $ia[4] => type --  text, radio, select, array, etc
31* $ia[5] => group id
32* $ia[6] => mandatory Y || N
33* $ia[7] => conditions exist for this question
34* $ia[8] => other questions have conditions which rely on this question (including array_filter and array_filter_exclude attributes)
35* $ia[9] => incremental question count (used by {QUESTION_NUMBER})
36*
37* $conditions element structure
38* $condition[n][0] => qid = question id
39* $condition[n][1] => cqid = question id of the target question, or 0 for TokenAttr leftOperand
40* $condition[n][2] => field name of element [1] (Except for type M or P)
41* $condition[n][3] => value to be evaluated on answers labeled.
42* $condition[n][4] => type of question
43* $condition[n][5] => SGQ code of element [1] (sub-part of [2])
44* $condition[n][6] => method used to evaluate
45* $condition[n][7] => scenario *NEW BY R.L.J. van den Burg*
46*/
47
48// ==================================================================
49// setting constants for 'checked' and 'selected' inputs
50define('CHECKED', ' checked="checked"');
51define('SELECTED', ' selected="selected"');
52
53/**
54* setNoAnswerMode
55*/
56function setNoAnswerMode($thissurvey)
57{
58    if (getGlobalSetting('shownoanswer') == 1) {
59        define('SHOW_NO_ANSWER', 1);
60    } elseif (getGlobalSetting('shownoanswer') == 0) {
61        define('SHOW_NO_ANSWER', 0);
62    } elseif ($thissurvey['shownoanswer'] == 'N') {
63        define('SHOW_NO_ANSWER', 0);
64    } else {
65        define('SHOW_NO_ANSWER', 1);
66    }
67}
68
69/**
70* This function returns an array containing the "question/answer" html display
71* and a list of the question/answer fieldnames associated. It is called from
72* question.php, group.php, survey.php or preview.php
73*
74* @param array $ia Details of $ia can be found at top of this file
75* @return array Array like [array $qanda, array $inputnames] where
76*               $qanda has elements [
77*                 $qtitle (question_text) : array [
78                        all : string; complete HTML?; all has been added for backwards compatibility with templates that use question_start.pstpl (now redundant)
79                        'text'               => $qtitle, question?? $ia[3]?
80                        'code'               => $ia[2] or title??
81                        'number'             => $number
82                        'help'               => ''
83                        'mandatory'          => ''
84                        man_message : string; message when mandatory is not answered
85                        'valid_message'      => ''
86                        file_valid_message : string; only relevant for file upload
87                        'class'              => ''
88                        'man_class'          => ''
89                        'input_error_class'  => ''              // provides a class.
90                        'essentials'         => ''
91*                 ]
92*                 $answer ?
93*                 'help' : string
94*                 $display : ?
95*                 $qid  : integer
96*                 $ia[2] = title;
97*                 $ia[5] = group id : int
98*                 $ia[1] = fieldname : string
99*               ]
100*               and $inputnames is ? used for hiddenfieldnames and upload file?
101*
102*/
103function retrieveAnswers($ia)
104{
105    //globalise required config variables
106    global $thissurvey; //These are set by index.php
107
108    $display    = $ia[7]; //DISPLAY
109    $qid        = $ia[0]; // Question ID
110    $qtitle     = $ia[3];
111    $inputnames = array();
112    $answer     = ""; //Create the question/answer html
113    $number     = isset($ia[9]) ? $ia[9] : ''; // Previously in limesurvey, it was virtually impossible to control how the start of questions were formatted. // this is an attempt to allow users (or rather system admins) some control over how the starting text is formatted.
114    $lang       = $_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang'];
115    $aQuestionAttributes = QuestionAttribute::model()->getQuestionAttributes($ia[0]);
116
117    $question_text = array(
118        'all'                 => ''              // All has been added for backwards compatibility with templates that use question_start.pstpl (now redundant)
119        ,'text'               => $qtitle
120        ,'code'               => $ia[2]
121        ,'number'             => $number
122        ,'help'               => ''
123        ,'mandatory'          => ''
124        ,'man_message'        => ''
125        ,'valid_message'      => ''
126        ,'file_valid_message' => ''
127        ,'class'              => ''
128        ,'man_class'          => ''
129        ,'input_error_class'  => ''              // provides a class.
130        ,'essentials'         => ''
131    );
132
133    $oQuestion = Question::model()->findByPk(array('qid'=>$ia[0], 'language'=>$lang));
134    $oQuestionTemplate = QuestionTemplate::getNewInstance($oQuestion);
135    $oQuestionTemplate->registerAssets(); // Register the custom assets of the question template, if needed
136
137    switch ($ia[4]) {
138        case 'X': //BOILERPLATE QUESTION
139            $values = do_boilerplate($ia);
140            break;
141
142        case '5': //5 POINT CHOICE radio-buttons
143            $values = do_5pointchoice($ia);
144            break;
145
146        case 'D': //DATE
147            $values = do_date($ia);
148            // if a drop box style date was answered incompletely (dropbox), print an error/help message
149            if (($_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['step'] != $_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['maxstep']) ||
150            ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['step'] == $_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['prevstep'])) {
151                if (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['qattribute_answer'.$ia[1]])) {
152                    $message = $_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['qattribute_answer'.$ia[1]];
153                    $question_text['help'] = doRender('/survey/questions/question_help/error', array('message'=>$message, 'classes'=>''), true);
154                }
155            }
156            break;
157
158        case 'L': //LIST drop-down/radio-button list
159            $values = do_list_radio($ia);
160            break;
161
162        case '!': //List - dropdown
163            $values = do_list_dropdown($ia);
164            break;
165
166        case 'O': //LIST WITH COMMENT drop-down/radio-button list + textarea
167            $values = do_listwithcomment($ia);
168            break;
169
170        case 'R': //RANKING STYLE
171            $values = do_ranking($ia);
172            break;
173
174        case 'M': //Multiple choice checkbox
175            $values = do_multiplechoice($ia);
176            break;
177
178        case 'I': //Language Question
179            $values = do_language($ia);
180            break;
181
182        case 'P': //Multiple choice with comments checkbox + text
183            $values = do_multiplechoice_withcomments($ia);
184            break;
185
186        case '|': //File Upload
187            $values = do_file_upload($ia);
188            break;
189
190        case 'Q': //MULTIPLE SHORT TEXT
191            $values = do_multipleshorttext($ia);
192            break;
193
194        case 'K': //MULTIPLE NUMERICAL QUESTION
195            $values = do_multiplenumeric($ia);
196            break;
197
198        case 'N': //NUMERICAL QUESTION TYPE
199            $values = do_numerical($ia);
200            break;
201
202        case 'S': //SHORT FREE TEXT
203            $values = do_shortfreetext($ia);
204            break;
205
206        case 'T': //LONG FREE TEXT
207            $values = do_longfreetext($ia);
208            break;
209
210        case 'U': //HUGE FREE TEXT
211            $values = do_hugefreetext($ia);
212            break;
213
214        case 'Y': //YES/NO radio-buttons
215            $values = do_yesno($ia);
216            break;
217
218        case 'G': //GENDER drop-down list
219            $values = do_gender($ia);
220            break;
221
222        case 'A': //ARRAY (5 POINT CHOICE) radio-buttons
223            $values = do_array_5point($ia);
224            break;
225
226        case 'B': //ARRAY (10 POINT CHOICE) radio-buttons
227            $values = do_array_10point($ia);
228            break;
229
230        case 'C': //ARRAY (YES/UNCERTAIN/NO) radio-buttons
231            $values = do_array_yesnouncertain($ia);
232            break;
233
234        case 'E': //ARRAY (Increase/Same/Decrease) radio-buttons
235            $values = do_array_increasesamedecrease($ia);
236            break;
237
238        case 'F': //ARRAY (Flexible) - Row Format
239            $values = do_array($ia);
240            break;
241
242        case 'H': //ARRAY (Flexible) - Column Format
243            $values = do_arraycolumns($ia);
244            break;
245
246        case ':': //ARRAY (Multi Flexi) 1 to 10
247            $values = do_array_multiflexi($ia);
248            break;
249
250        case ';': //ARRAY (Multi Flexi) Text
251            $values = do_array_texts($ia); //It's like the "5th element" movie, come to life
252            break;
253
254        case '1': //Array (Flexible Labels) dual scale
255            $values = do_array_dual($ia);
256            break;
257
258        case '*': // Equation
259            $values = do_equation($ia);
260            break;
261    }
262
263
264    if (isset($values)) {
265        //Break apart $values array returned from switch
266        //$answer is the html code to be printed
267        //$inputnames is an array containing the names of each input field
268        list($answer, $inputnames) = $values;
269    }
270
271    if ($ia[6] == 'Y') {
272
273        //$qtitle .= doRender('/survey/questions/question_help/asterisk', array(), true);
274        //$qtitle .= $qtitle;
275        //$question_text['mandatory'] = gT('*');
276        $question_text['mandatory'] = doRender('/survey/questions/question_help/asterisk', array(), true);
277    }
278
279    //If this question is mandatory but wasn't answered in the last page
280    //add a message HIGHLIGHTING the question
281    $mandatory_msg = (($_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['step'] != $_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['maxstep']) || ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['step'] == $_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['prevstep'])) ?mandatory_message($ia) : '';
282    $qtitle .= $mandatory_msg;
283    $question_text['man_message'] = $mandatory_msg;
284
285    $_vshow = (!isset($aQuestionAttributes['hide_tip']) || $aQuestionAttributes['hide_tip'] == 0) ?true:false; // whether should initially be visible - TODO should also depend upon 'hidetip'?
286
287    list($validation_msg, $isValid) = validation_message($ia, $_vshow);
288
289    $qtitle .= $validation_msg;
290    $question_text['valid_message'] = $validation_msg;
291
292    if (($_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['step'] != $_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['maxstep']) || ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['step'] == $_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['prevstep'])) {
293        $file_validation_msg = file_validation_message($ia);
294    } else {
295        $file_validation_msg = '';
296        $isValid = true; // don't want to show any validation messages.
297    }
298
299    $qtitle .= $ia[4] == "|" ? $file_validation_msg : "";
300    $question_text['file_valid_message'] = $ia[4] == "|" ? $file_validation_msg : "";
301
302    if (!empty($question_text['man_message']) || !$isValid || !empty($question_text['file_valid_message'])) {
303        $question_text['input_error_class'] = ' input-error'; // provides a class to style question wrapper differently if there is some kind of user input error;
304    }
305
306    // =====================================================
307    // START: legacy question_start.pstpl code
308    // The following section adds to the templating system by allowing
309    // templaters to control where the various parts of the question text
310    // are put.
311
312    $sTemplate = isset($thissurvey['template']) ? $thissurvey['template'] : null;
313    if (is_file('templates/'.$sTemplate.'/question_start.pstpl')) {
314        $replace = array();
315        $find    = array();
316        foreach ($question_text as $key => $value) {
317            $find[] = '{QUESTION_'.strtoupper($key).'}'; // Match key words from template
318            $replace[] = $value; // substitue text
319        };
320
321        if (!defined('QUESTION_START')) {
322            define('QUESTION_START', file_get_contents(getTemplatePath($thissurvey['template']).'/question_start.pstpl', true));
323        };
324
325        $qtitle_custom = str_replace($find, $replace, QUESTION_START);
326
327        $c = 1;
328        // START: <EMBED> work-around step 1
329        $qtitle_custom = preg_replace('/(<embed[^>]+>)(<\/embed>)/i', '\1NOT_EMPTY\2', $qtitle_custom);
330        // END <EMBED> work-around step 1
331        while ($c > 0) {
332            // This recursively strips any empty tags to minimise rendering bugs.
333            $oldtitle = $qtitle_custom;
334            $qtitle_custom = preg_replace('/<([^ >]+)[^>]*>[\r\n\t ]*<\/\1>[\r\n\t ]*/isU', '', $qtitle_custom, -1); // I removed the $count param because it is PHP 5.1 only.
335
336            $c = ($qtitle_custom != $oldtitle) ? 1 : 0;
337        };
338        // START <EMBED> work-around step 2
339        $qtitle_custom = preg_replace('/(<embed[^>]+>)NOT_EMPTY(<\/embed>)/i', '\1\2', $qtitle_custom);
340        // END <EMBED> work-around step 2
341        while ($c > 0) {
342            // This recursively strips any empty tags to minimise rendering bugs.
343            $oldtitle = $qtitle_custom;
344            $qtitle_custom = preg_replace('/(<br(?: ?\/)?>(?:&nbsp;|\r\n|\n\r|\r|\n| )*)+$/i', '', $qtitle_custom, -1); // I removed the $count param because it is PHP 5.1 only.
345            $c = ($qtitle_custom != $oldtitle) ? 1 : 0;
346        };
347
348        $question_text['all'] = $qtitle_custom;
349    } else {
350        $question_text['all'] = $qtitle;
351    };
352    // END: legacy question_start.pstpl code
353    //===================================================================
354    $qtitle = $question_text;
355    // =====================================================
356
357    $qanda = array($qtitle, $answer, 'help', $display, $qid, $ia[2], $ia[5], $ia[1]);
358    //New Return
359    return array($qanda, $inputnames);
360}
361
362function mandatory_message($ia)
363{
364    $qinfo = LimeExpressionManager::GetQuestionStatus($ia[0]);
365    $qinfoValue = ($qinfo['mandViolation']) ? $qinfo['mandTip'] : "";
366    return $qinfoValue;
367}
368
369/**
370*
371* @param array $ia
372* @param boolean $show - true if should initially be visible
373* @return array
374*/
375function validation_message($ia, $show)
376{
377    $qinfo      = LimeExpressionManager::GetQuestionStatus($ia[0]);
378    $class      = (!$show) ? ' hide-tip' : '';
379    $id         = "vmsg_".$ia[0];
380    $message    = $qinfo['validTip'];
381    if ($message != "") {
382        $tip = doRender('/survey/questions/question_help/help', array('message'=>$message, 'classes'=>$class, 'id'=>$id), true);
383    } else {
384        $tip = "";
385    }
386
387    $isValid = $qinfo['valid'];
388    return array($tip, $isValid);
389}
390
391// TMSW Validation -> EM
392function file_validation_message($ia)
393{
394    global $filenotvalidated;
395    $qtitle = "";
396    if (isset($filenotvalidated) && is_array($filenotvalidated) && $ia[4] == "|") {
397        foreach ($filenotvalidated as $k => $v) {
398            if ($ia[1] == $k || strpos($k, "_") && $ia[1] == substr(0, strpos($k, "_") - 1)) {
399                $message = gT($filenotvalidated[$k]);
400                $qtitle .= doRender('/survey/questions/question_help/error', array('message'=>$message, 'classes'=>''), true);
401            }
402        }
403    }
404    return $qtitle;
405}
406
407// TMSW Validation -> EM
408function mandatory_popup($ia, $notanswered = null)
409{
410    //This sets the mandatory popup message to show if required
411    //Called from question.php, group.php or survey.php
412    if ($notanswered === null) {
413        unset($notanswered);
414    }
415    if (isset($notanswered) && is_array($notanswered)) {
416        //ADD WARNINGS TO QUESTIONS IF THEY WERE MANDATORY BUT NOT ANSWERED
417        global $mandatorypopup, $popup;
418        //POPUP WARNING
419        if (!isset($mandatorypopup) && ($ia[4] == 'T' || $ia[4] == 'S' || $ia[4] == 'U')) {
420            $popup = gT("You cannot proceed until you enter some text for one or more questions.");
421            $mandatorypopup = "Y";
422        } else {
423            $popup = gT("One or more mandatory questions have not been answered. You cannot proceed until these have been completed.");
424            $mandatorypopup = "Y";
425        }
426        return array($mandatorypopup, $popup);
427    } else {
428        return false;
429    }
430}
431
432// TMSW Validation -> EM
433function validation_popup($ia, $notvalidated = null)
434{
435    //This sets the validation popup message to show if required
436    //Called from question.php, group.php or survey.php
437    if ($notvalidated === null) {
438        unset($notvalidated);
439    }
440    if (isset($notvalidated) && is_array($notvalidated)) {
441        //ADD WARNINGS TO QUESTIONS IF THEY ARE NOT VALID
442        global $validationpopup, $vpopup;
443        //POPUP WARNING
444        if (!isset($validationpopup)) {
445            $vpopup = gT("One or more questions have not been answered in a valid manner. You cannot proceed until these answers are valid.");
446            $validationpopup = "Y";
447        }
448        return array($validationpopup, $vpopup);
449    } else {
450        return false;
451    }
452}
453
454// TMSW Validation -> EM
455/**
456* @param boolean $filenotvalidated
457*/
458function file_validation_popup($ia, $filenotvalidated = null)
459{
460    if ($filenotvalidated === null) {
461        unset($filenotvalidated);
462    }
463    if (isset($filenotvalidated) && is_array($filenotvalidated)) {
464        global $filevalidationpopup, $fpopup;
465
466        if (!isset($filevalidationpopup)) {
467            $fpopup = gT("One or more file have either exceeded the filesize/are not in the right format or the minimum number of required files have not been uploaded. You cannot proceed until these have been completed");
468            $filevalidationpopup = "Y";
469        }
470        return array($filevalidationpopup, $fpopup);
471    } else {
472        return false;
473    }
474}
475
476/**
477* @param string $disable
478* @return string
479*/
480function return_timer_script($aQuestionAttributes, $ia, $disable = null)
481{
482    global $thissurvey;
483
484    Yii::app()->getClientScript()->registerScriptFile(Yii::app()->getConfig("generalscripts").'coookies.js', CClientScript::POS_BEGIN);
485    Yii::app()->getClientScript()->registerPackage('timer-addition');
486
487    $langTimer = array(
488        'hours'=>gT("hours"),
489        'mins'=>gT("mins"),
490        'seconds'=>gT("seconds"),
491    );
492    /* Registering script : don't go to EM : no need usage of ls_json_encode */
493    App()->getClientScript()->registerScript("LSVarLangTimer", "LSvar.lang.timer=".json_encode($langTimer).";", CClientScript::POS_BEGIN);
494    /**
495     * The following lines cover for previewing questions, because no $_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['fieldarray'] exists.
496     * This just stops error messages occuring
497     */
498    if (!isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['fieldarray'])) {
499        $_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['fieldarray'] = array();
500    }
501    /* End */
502
503    //Used to count how many timer questions in a page, and ensure scripts only load once
504    $thissurvey['timercount'] = (isset($thissurvey['timercount'])) ? $thissurvey['timercount']++ : 1;
505
506    /* Work in all mode system : why disable it ? */
507    //~ if ($thissurvey['format'] != "S")
508    //~ {
509    //~ if ($thissurvey['format'] != "G")
510    //~ {
511    //~ return "\n\n<!-- TIMER MODE DISABLED DUE TO INCORRECT SURVEY FORMAT -->\n\n";
512    //~ //We don't do the timer in any format other than question-by-question
513    //~ }
514    //~ }
515
516    $time_limit = $aQuestionAttributes['time_limit'];
517    $disable_next = trim($aQuestionAttributes['time_limit_disable_next']) != '' ? $aQuestionAttributes['time_limit_disable_next'] : 0;
518    $disable_prev = trim($aQuestionAttributes['time_limit_disable_prev']) != '' ? $aQuestionAttributes['time_limit_disable_prev'] : 0;
519    $time_limit_action = trim($aQuestionAttributes['time_limit_action']) != '' ? $aQuestionAttributes['time_limit_action'] : 1;
520    $time_limit_message = trim($aQuestionAttributes['time_limit_message'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']]) != '' ? htmlspecialchars($aQuestionAttributes['time_limit_message'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']], ENT_QUOTES) : gT("Your time to answer this question has expired");
521    $time_limit_warning = trim($aQuestionAttributes['time_limit_warning']) != '' ? $aQuestionAttributes['time_limit_warning'] : 0;
522    $time_limit_warning_2 = trim($aQuestionAttributes['time_limit_warning_2']) != '' ? $aQuestionAttributes['time_limit_warning_2'] : 0;
523    $time_limit_countdown_message = trim($aQuestionAttributes['time_limit_countdown_message'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']]) != '' ? htmlspecialchars($aQuestionAttributes['time_limit_countdown_message'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']], ENT_QUOTES) : gT("Time remaining");
524    $time_limit_warning_message = trim($aQuestionAttributes['time_limit_warning_message'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']]) != '' ? htmlspecialchars($aQuestionAttributes['time_limit_warning_message'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']], ENT_QUOTES) : gT("Your time to answer this question has nearly expired. You have {TIME} remaining.");
525
526    //Render timer
527    $timer_html = doRender('/survey/questions/question_timer/timer', array('iQid'=>$ia[0], 'sWarnId'=>''), true);
528    $time_limit_warning_message = str_replace("{TIME}", $timer_html, $time_limit_warning_message);
529    $time_limit_warning_display_time = trim($aQuestionAttributes['time_limit_warning_display_time']) != '' ? $aQuestionAttributes['time_limit_warning_display_time'] + 1 : 0;
530    $time_limit_warning_2_message = trim($aQuestionAttributes['time_limit_warning_2_message'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']]) != '' ? htmlspecialchars($aQuestionAttributes['time_limit_warning_2_message'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']], ENT_QUOTES) : gT("Your time to answer this question has nearly expired. You have {TIME} remaining.");
531
532    //Render timer 2
533    $timer_html = doRender('/survey/questions/question_timer/timer', array('iQid'=>$ia[0], 'sWarnId'=>'_Warning_2'), true);
534    $time_limit_message_delay = trim($aQuestionAttributes['time_limit_message_delay']) != '' ? $aQuestionAttributes['time_limit_message_delay'] * 1000 : 1000;
535    $time_limit_warning_2_message = str_replace("{TIME}", $timer_html, $time_limit_warning_2_message);
536    $time_limit_warning_2_display_time = trim($aQuestionAttributes['time_limit_warning_2_display_time']) != '' ? $aQuestionAttributes['time_limit_warning_2_display_time'] + 1 : 0;
537    $time_limit_message_style = trim($aQuestionAttributes['time_limit_message_style']) != '' ? $aQuestionAttributes['time_limit_message_style'] : "";
538    $time_limit_message_class = "hidden ls-timer-content ls-timer-message ls-no-js-hidden";
539    $time_limit_warning_style = trim($aQuestionAttributes['time_limit_warning_style']) != '' ? $aQuestionAttributes['time_limit_warning_style'] : "";
540    $time_limit_warning_class = "hidden ls-timer-content ls-timer-warning ls-no-js-hidden";
541    $time_limit_warning_2_style = trim($aQuestionAttributes['time_limit_warning_2_style']) != '' ? $aQuestionAttributes['time_limit_warning_2_style'] : "";
542    $time_limit_warning_2_class = "hidden ls-timer-content ls-timer-warning2 ls-no-js-hidden";
543    $time_limit_timer_style = trim($aQuestionAttributes['time_limit_timer_style']) != '' ? $aQuestionAttributes['time_limit_timer_style'] : "position: relative;";
544    $time_limit_timer_class = "ls-timer-content ls-timer-countdown ls-no-js-hidden";
545
546    $timersessionname = "timer_question_".$ia[0];
547    if (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$timersessionname])) {
548        $time_limit = $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$timersessionname];
549    }
550
551    $output = doRender('/survey/questions/question_timer/timer_header', array('timersessionname'=>$timersessionname, 'time_limit'=>$time_limit), true);
552
553    if ($thissurvey['timercount'] < 2) {
554        $iAction = '';
555        if (isset($thissurvey['format']) && $thissurvey['format'] == "G") {
556            global $gid;
557            $qcount = 0;
558            foreach ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['fieldarray'] as $ib) {
559                if ($ib[5] == $gid) {
560                    $qcount++;
561                }
562            }
563            // Override all other options and just allow freezing, survey is presented in group by group mode
564            // Why don't allow submit in Group by group mode, this surely broke 'mandatory' question, but this remove a great system for user (Denis 140224)
565            if ($qcount > 1) {
566                $iAction = '3';
567            }
568        }
569
570        /* If this is a preview, don't allow the page to submit/reload */
571        $thisaction = returnglobal('action');
572        if ($thisaction == "previewquestion" || $thisaction == "previewgroup") {
573            $iAction = '3';
574        }
575
576        $output .= doRender('/survey/questions/question_timer/timer_javascript', array(
577            'timersessionname'=>$timersessionname,
578            'time_limit'=>$time_limit,
579            'iAction'=>$iAction,
580            'disable_next'=>$disable_next,
581            'disable_prev'=>$disable_prev,
582            'time_limit_countdown_message' =>$time_limit_countdown_message,
583            'time_limit_message_delay' => $time_limit_message_delay
584            ), true);
585    }
586
587    $output .= doRender(
588        '/survey/questions/question_timer/timer_content',
589        array(
590            'iQid'=>$ia[0],
591            'time_limit_message_style'=>$time_limit_message_style,
592            'time_limit_message_class'=>$time_limit_message_class,
593            'time_limit_message'=>$time_limit_message,
594            'time_limit_warning_style'=>$time_limit_warning_style,
595            'time_limit_warning_class'=>$time_limit_warning_class,
596            'time_limit_warning_message'=>$time_limit_warning_message,
597            'time_limit_warning_2_style'=>$time_limit_warning_2_style,
598            'time_limit_warning_2_class'=>$time_limit_warning_2_class,
599            'time_limit_warning_2_message'=>$time_limit_warning_2_message,
600            'time_limit_timer_style'=>$time_limit_timer_style,
601            'time_limit_timer_class'=>$time_limit_timer_class,
602        ),
603        true
604    );
605
606    $output .= doRender(
607        '/survey/questions/question_timer/timer_footer',
608        array(
609            'iQid'=>$ia[0],
610            'iSid'=>Yii::app()->getConfig('surveyID'),
611            'time_limit'=>$time_limit,
612            'time_limit_action'=>$time_limit_action,
613            'time_limit_warning'=>$time_limit_warning,
614            'time_limit_warning_2'=>$time_limit_warning_2,
615            'time_limit_warning_display_time'=>$time_limit_warning_display_time,
616            'time_limit_warning_2_display_time'=>$time_limit_warning_2_display_time,
617            'disable'=>$disable,
618        ),
619        true
620    );
621    return $output;
622}
623
624/**
625* Return class of a specific row (hidden by relevance)
626* @param int $surveyId actual survey id
627* @param string $baseName the base name of the question
628* @param string $name The name of the question/row to test
629* @param array $aQuestionAttributes the question attributes
630* @return string
631*/
632
633function currentRelevecanceClass($surveyId, $baseName, $name, $aQuestionAttributes)
634{
635    $relevanceStatus = !isset($_SESSION["survey_{$surveyId}"]['relevanceStatus'][$name]) || $_SESSION["survey_{$surveyId}"]['relevanceStatus'][$name];
636    if ($relevanceStatus) {
637        return "";
638    }
639    $sExcludeAllOther = isset($aQuestionAttributes['exclude_all_others']) ? trim($aQuestionAttributes['exclude_all_others']) : '';
640    /* EM don't set difference between relevance in session, if exclude_all_others is set , just ls-disabled */
641    if ($sExcludeAllOther) {
642        foreach (explode(';', $sExcludeAllOther) as $sExclude) {
643            $sExclude = $baseName.$sExclude;
644            if ((!isset($_SESSION["survey_{$surveyId}"]['relevanceStatus'][$sExclude]) || $_SESSION["survey_{$surveyId}"]['relevanceStatus'][$sExclude])
645            && (isset($_SESSION["survey_{$surveyId}"][$sExclude]) && $_SESSION["survey_{$surveyId}"][$sExclude] == "Y")
646            ) {
647                return "ls-irrelevant ls-disabled";
648            }
649        }
650    }
651
652    $filterStyle = !empty($aQuestionAttributes['array_filter_style']); // Currently null/0/false=> hidden , 1 : disabled
653    if ($filterStyle) {
654        return "ls-irrelevant ls-disabled";
655    }
656    return "ls-irrelevant ls-hidden";
657}
658/**
659* @param string $rowname
660*/
661function return_display_style($ia, $aQuestionAttributes, $thissurvey, $rowname)
662{
663    /* Disabled actually : no inline style */
664    return "";
665    //~ $htmltbody2 = '';
666    //~ $surveyid=$thissurvey['sid'];
667    //~ if (isset($_SESSION["survey_{$surveyid}"]['relevanceStatus'][$rowname]) && !$_SESSION["survey_{$surveyid}"]['relevanceStatus'][$rowname])
668    //~ {
669    //~ // If using exclude_all_others, then need to know whether irrelevant rows should be hidden or disabled
670
671    //~ }
672
673    //~ return $htmltbody2;
674}
675
676/**
677* @param string $rowname
678* @param string $valuename
679*/
680function return_array_filter_strings($ia, $aQuestionAttributes, $thissurvey, $ansrow, $rowname, $trbc = '', $valuename, $method = "tbody", $class = null)
681{
682    $htmltbody2 = "\n\n\t<$method id='javatbd$rowname'";
683    $htmltbody2 .= ($class !== null) ? " class='$class'" : "";
684    $surveyid = $thissurvey['sid'];
685    if (isset($_SESSION["survey_{$surveyid}"]['relevanceStatus'][$rowname]) && !$_SESSION["survey_{$surveyid}"]['relevanceStatus'][$rowname]) {
686        // If using exclude_all_others, then need to know whether irrelevant rows should be hidden or disabled
687        if (isset($aQuestionAttributes['exclude_all_others'])) {
688            $disableit = false;
689            foreach (explode(';', trim($aQuestionAttributes['exclude_all_others'])) as $eo) {
690                $eorow = $ia[1].$eo;
691                if ((!isset($_SESSION["survey_{$surveyid}"]['relevanceStatus'][$eorow]) || $_SESSION["survey_{$surveyid}"]['relevanceStatus'][$eorow])
692                && (isset($_SESSION[$eorow]) && $_SESSION[$eorow] == "Y")) {
693                    $disableit = true;
694                }
695            }
696            if ($disableit) {
697                $htmltbody2 .= " disabled='disabled'";
698            } else {
699                if (!isset($aQuestionAttributes['array_filter_style']) || $aQuestionAttributes['array_filter_style'] == '0') {
700                    $htmltbody2 .= " style='display: none'";
701                } else {
702                    $htmltbody2 .= " disabled='disabled'";
703                }
704            }
705        } else {
706            if (!isset($aQuestionAttributes['array_filter_style']) || $aQuestionAttributes['array_filter_style'] == '0') {
707                $htmltbody2 .= " style='display: none'";
708            } else {
709                $htmltbody2 .= " disabled='disabled'";
710            }
711        }
712    }
713    $htmltbody2 .= ">\n";
714    return array($htmltbody2, "");
715}
716
717/**
718* @param string $sUseKeyPad
719* @return string
720*/
721function testKeypad($sUseKeyPad)
722{
723    if ($sUseKeyPad == 'Y') {
724        includeKeypad();
725        $kpclass = "text-keypad";
726    } else {
727        $kpclass = "";
728    }
729    return $kpclass;
730}
731
732
733
734// ==================================================================
735// QUESTION METHODS =================================================
736
737function do_boilerplate($ia)
738{
739    //$aQuestionAttributes = QuestionAttribute::model()->getQuestionAttributes($ia[0]);
740    $aQuestionAttributes = QuestionAttribute::model()->getQuestionAttributes($ia[0]);
741    $answer = '';
742    $inputnames = array();
743    $sTimer              = (trim($aQuestionAttributes['time_limit']) != '') ? return_timer_script($aQuestionAttributes, $ia) : ''; //Time Limit
744
745    $answer .= doRender('/survey/questions/answer/boilerplate/answer', array(
746        'sTimer'=>$sTimer,
747        'ia'=>$ia,
748        'name'=>$ia[1],
749        'basename'=>$ia[1], /* is this needed ? */
750        'coreClass'=>'ls-answers hidden',
751        ), true);
752    $inputnames[] = $ia[1];
753
754    return array($answer, $inputnames);
755}
756
757function do_equation($ia)
758{
759    $aQuestionAttributes = QuestionAttribute::model()->getQuestionAttributes($ia[0]);
760    $sEquation           = (trim($aQuestionAttributes['equation'])) ? $aQuestionAttributes['equation'] : $ia[3];
761    $sValue              = htmlspecialchars($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]], ENT_QUOTES);
762    $inputnames = array();
763
764    $answer = doRender('/survey/questions/answer/equation/answer', array(
765        'name'      => $ia[1],
766        'basename'  => $ia[1],
767        'sValue'    => $sValue,
768        'sEquation' => $sEquation,
769        'coreClass' => 'ls-answers em_equation hidden'
770        ), true);
771
772    $inputnames[] = $ia[1];
773    return array($answer, $inputnames);
774}
775
776// ---------------------------------------------------------------
777function do_5pointchoice($ia)
778{
779    $checkconditionFunction = "checkconditions";
780    //$aQuestionAttributes=  QuestionAttribute::model()->getQuestionAttributes($ia[0]);
781    $aQuestionAttributes = QuestionAttribute::model()->getQuestionAttributes($ia[0]);
782    $inputnames = array();
783
784    $aRows = array();
785    ;
786    for ($fp = 1; $fp <= 5; $fp++) {
787        $checkedState = '';
788        if ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] == $fp) {
789            //$answer .= CHECKED;
790            $checkedState = ' CHECKED ';
791        }
792
793        $aRows[] = array(
794            'name'                   => $ia[1],
795            'value'                  => $fp,
796            'id'                     => $ia[1].$fp,
797            'labelText'              => $fp,
798            'itemExtraClass'         => '',
799            'checkedState'           => $checkedState,
800            'checkconditionFunction' => $checkconditionFunction,
801            );
802    }
803
804    if ($ia[6] != "Y" && SHOW_NO_ANSWER == 1) {
805        // Add "No Answer" option if question is not mandatory
806        $checkedState = '';
807        if (!$_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]]) {
808            $checkedState = ' CHECKED ';
809        }
810        $aRows[] = array(
811            'name'                   => $ia[1],
812            'value'                  => "",
813            'id'                     => $ia[1],
814            'labelText'              => gT('No answer'),
815            'itemExtraClass'         => 'noanswer-item',
816            'checkedState'           => $checkedState,
817            'checkconditionFunction' => $checkconditionFunction,
818        );
819    }
820    $sessionValue = $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]];
821
822    $inputnames[] = $ia[1];
823
824    $slider_rating = 0;
825
826    if ($aQuestionAttributes['slider_rating'] == 1) {
827        $slider_rating = 1;
828        Yii::app()->getClientScript()->registerPackage('question-5pointchoice-star');
829        Yii::app()->getClientScript()->registerScript('doRatingStar_'.$ia[0], "doRatingStar('".$ia[0]."'); ", LSYii_ClientScript::POS_POSTSCRIPT);
830    }
831
832    if ($aQuestionAttributes['slider_rating'] == 2) {
833        $slider_rating = 2;
834        Yii::app()->getClientScript()->registerPackage('question-5pointchoice-slider');
835        Yii::app()->getClientScript()->registerScript('doRatingSlider_'.$ia[0], "
836            var doRatingSlider_".$ia[1]."= new getRatingSlider('".$ia[0]."');
837            doRatingSlider_".$ia[1]."();
838        ", LSYii_ClientScript::POS_POSTSCRIPT);
839    }
840
841
842    $answer = doRender('/survey/questions/answer/5pointchoice/answer', array(
843        'coreClass'     => "ls-answers answers-list radio-list",
844        'sliderId'      => $ia[0],
845        'name'          => $ia[1],
846        'basename'      => $ia[1],
847        'sessionValue'  => $sessionValue,
848        'aRows'         => $aRows,
849        'slider_rating' => $slider_rating,
850
851        ), true);
852
853    return array($answer, $inputnames);
854}
855
856// ---------------------------------------------------------------
857function do_date($ia)
858{
859    global $thissurvey;
860    $aQuestionAttributes    = QuestionAttribute::model()->getQuestionAttributes($ia[0]);
861    $checkconditionFunction = "checkconditions";
862    $dateformatdetails      = getDateFormatDataForQID($aQuestionAttributes, $thissurvey);
863    $inputnames = array();
864    $coreClass = "ls-answers answer-item date-item";
865
866    $sDateLangvarJS = " translt = {
867    alertInvalidDate: '" . gT('Date entered is invalid!', 'js')."',
868    };";
869
870    $dateparts = [
871        'year' => gT('Year'),
872        'month' => gT('Month'),
873        'day' => gT('Day'),
874        'hour' => gT('Hour'),
875        'minute' => gT('Minute'),
876        'second' => gT('Second'),
877        'millisecond' => gT('Millisecond')
878    ];
879
880    App()->getClientScript()->registerScript("sDateLangvarJS", $sDateLangvarJS, CClientScript::POS_BEGIN);
881    App()->getClientScript()->registerPackage('moment');
882    App()->getClientScript()->registerPackage('bootstrap-datetimepicker');
883    App()->getClientScript()->registerScriptFile(Yii::app()->getConfig("generalscripts").'date.js', CClientScript::POS_END);
884
885    // date_min: Determine whether we have an expression, a full date (YYYY-MM-DD) or only a year(YYYY)
886    if (trim($aQuestionAttributes['date_min']) != '') {
887        $date_min      = trim($aQuestionAttributes['date_min']);
888        $date_time_em  = strtotime(LimeExpressionManager::ProcessString("{".$date_min."}", $ia[0]));
889
890        if (ctype_digit($date_min) && (strlen($date_min) == 4) && ($date_min >= 1900) && ($date_min <= 2099)) {
891            $mindate = $date_min.'-01-01'; // backward compatibility: if only a year is given, add month and day
892        } elseif (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])/", $date_min)) {
893            // it's a YYYY-MM-DD date (use http://www.yiiframework.com/doc/api/1.1/CDateValidator ?)
894            $mindate = $date_min;
895        } elseif ($date_time_em !== false) {
896            $mindate = (string) date("Y-m-d", $date_time_em);
897        } else {
898            $mindate = '{'.$aQuestionAttributes['date_min'].'}';
899        }
900    } else {
901        $mindate = '1900-01-01'; // Why 1900 ?
902    }
903
904    // date_max: Determine whether we have an expression, a full date (YYYY-MM-DD) or only a year(YYYY)
905    if (trim($aQuestionAttributes['date_max']) != '') {
906        $date_max     = trim($aQuestionAttributes['date_max']);
907        $date_time_em = strtotime(LimeExpressionManager::ProcessString("{".$date_max."}", $ia[0]));
908
909        if (ctype_digit($date_max) && (strlen($date_max) == 4) && ($date_max >= 1900) && ($date_max <= 2099)) {
910            $maxdate = $date_max.'-12-31'; // backward compatibility: if only a year is given, add month and day
911        } elseif (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])/", $date_max)) {
912            // it's a YYYY-MM-DD date (use http://www.yiiframework.com/doc/api/1.1/CDateValidator ?)
913            $maxdate = $date_max;
914        } elseif ($date_time_em !== false) {
915            $maxdate = (string) date("Y-m-d", $date_time_em);
916        } else {
917            $maxdate = '{'.$aQuestionAttributes['date_max'].'}';
918        }
919    } else {
920        $maxdate = '2037-12-31'; // Why 2037 ?
921    }
922
923    $dateoutput = trim($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]]);
924    if (!empty($dateoutput)) {
925        $dateoutput = fillDate($dateoutput);
926    }
927    if (trim($aQuestionAttributes['dropdown_dates']) == 1) {
928        $coreClass .= " dropdown-item"; // items ?
929        if (!empty($dateoutput)) {
930            $datetimeobj   = new Date_Time_Converter($dateoutput, "Y-m-d H:i");
931            $currentyear   = $datetimeobj->years;
932            $currentmonth  = $datetimeobj->months;
933            $currentday   = $datetimeobj->days;
934            $currenthour   = $datetimeobj->hours;
935            $currentminute = $datetimeobj->minutes;
936        } else {
937            // If date is invalid get the POSTED value
938            $currentday   = App()->request->getPost("day{$ia[1]}", '');
939            $currentmonth  = App()->request->getPost("month{$ia[1]}", '');
940            $currentyear   = App()->request->getPost("year{$ia[1]}", '');
941            $currenthour   = App()->request->getPost("hour{$ia[1]}", '');
942            $currentminute = App()->request->getPost("minute{$ia[1]}", '');
943        }
944        $dateorder = preg_split('/([-\.\/ :])/', $dateformatdetails['phpdate'], -1, PREG_SPLIT_DELIM_CAPTURE);
945
946        $sRows = '';
947        $montharray = array();
948        foreach ($dateorder as $datepart) {
949            switch ($datepart) {
950                // Show day select box
951                case 'j':
952                case 'd':
953                    $sRows .= doRender('/survey/questions/answer/date/dropdown/rows/day', array('dayId'=>$ia[1], 'currentday'=>$currentday), true);
954                    break;
955                    // Show month select box
956                case 'n':
957                case 'm':
958                switch ((int) trim($aQuestionAttributes['dropdown_dates_month_style'])) {
959                    case 0:
960                        $montharray = array(
961                            gT('Jan'),
962                            gT('Feb'),
963                            gT('Mar'),
964                            gT('Apr'),
965                            gT('May'),
966                            gT('Jun'),
967                            gT('Jul'),
968                            gT('Aug'),
969                            gT('Sep'),
970                            gT('Oct'),
971                            gT('Nov'),
972                            gT('Dec'));
973                        break;
974                    case 1:
975                        $montharray = array(
976                            gT('January'),
977                            gT('February'),
978                            gT('March'),
979                            gT('April'),
980                            gT('May'),
981                            gT('June'),
982                            gT('July'),
983                            gT('August'),
984                            gT('September'),
985                            gT('October'),
986                            gT('November'),
987                            gT('December'));
988                        break;
989                    case 2:
990                        $montharray = array('01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12');
991                        break;
992                }
993
994                $sRows .= doRender('/survey/questions/answer/date/dropdown/rows/month', array('monthId'=>$ia[1], 'currentmonth'=>$currentmonth, 'montharray'=>$montharray), true);
995                break;
996                // Show year select box
997                case 'y':
998                case 'Y':
999                    /*
1000                    * yearmin = Minimum year value for dropdown list, if not set default is 1900
1001                    * yearmax = Maximum year value for dropdown list, if not set default is 2037
1002                    * if full dates (format: YYYY-MM-DD) are given, only the year is used
1003                    * expressions are not supported because contents of dropbox cannot be easily updated dynamically
1004                    */
1005                    $yearmin = (int) substr($mindate, 0, 4);
1006                    if (!isset($yearmin) || $yearmin < 1900 || $yearmin > 2037) {
1007                        $yearmin = 1900;
1008                    }
1009
1010                    $yearmax = (int) substr($maxdate, 0, 4);
1011                    if (!isset($yearmax) || $yearmax < 1900 || $yearmax > 2037) {
1012                        $yearmax = 2037;
1013                    }
1014
1015                    if ($yearmin > $yearmax) {
1016                        $yearmin = 1900;
1017                        $yearmax = 2037;
1018                    }
1019
1020                    if ($aQuestionAttributes['reverse'] == 1) {
1021                        $tmp = $yearmin;
1022                        $yearmin = $yearmax;
1023                        $yearmax = $tmp;
1024                        $step = 1;
1025                        $reverse = true;
1026                    } else {
1027                        $step = -1;
1028                        $reverse = false;
1029                    }
1030                    $sRows .= doRender('/survey/questions/answer/date/dropdown/rows/year', array('yearId'=>$ia[1], 'currentyear'=>$currentyear, 'yearmax'=>$yearmax, 'reverse'=>$reverse, 'yearmin'=>$yearmin, 'step'=>$step), true);
1031                    break;
1032                case 'H':
1033                case 'h':
1034                case 'g':
1035                case 'G':
1036                    $sRows .= doRender('/survey/questions/answer/date/dropdown/rows/hour', array('hourId'=>$ia[1], 'currenthour'=>$currenthour, 'datepart'=>$datepart), true);
1037                    break;
1038                case 'i':
1039                    $sRows .= doRender('/survey/questions/answer/date/dropdown/rows/minute', array('minuteId'=>$ia[1], 'currentminute'=>$currentminute, 'dropdown_dates_minute_step'=>$aQuestionAttributes['dropdown_dates_minute_step'], 'datepart'=>$datepart), true);
1040                    break;
1041                default:
1042                    $sRows .= doRender('/survey/questions/answer/date/dropdown/rows/datepart', array('datepart'=>$datepart), true);
1043
1044            }
1045        }
1046        // Format the date  for output
1047        if ($dateoutput != '') {
1048            $datetimeobj = DateTime::createFromFormat('!Y-m-d H:i', $dateoutput);
1049            if ($datetimeobj) {
1050                $dateoutput = $datetimeobj->format($dateformatdetails['phpdate']);
1051            } else {
1052                $dateoutput = '';
1053            }
1054        }
1055
1056
1057        // ==> answer
1058        $answer = doRender('/survey/questions/answer/date/dropdown/answer', array(
1059            'sRows'                  => $sRows,
1060            'coreClass'              => $coreClass,
1061            'name'                   => $ia[1],
1062            'basename'               => $ia[1],
1063            'dateoutput'             => htmlspecialchars($dateoutput, ENT_QUOTES, 'utf-8'),
1064            'checkconditionFunction' => $checkconditionFunction.'(this.value, this.name, this.type)',
1065            'dateformatdetails'      => $dateformatdetails['jsdate'],
1066            'dateformat'             => $dateformatdetails['jsdate'],
1067            ), true);
1068
1069        App()->getClientScript()->registerScript('doDropDownDate'.$ia[0], "doDropDownDate({$ia[0]});", LSYii_ClientScript::POS_POSTSCRIPT);
1070    } else {
1071        $coreClass .= " text-item";
1072        // Format the date  for output
1073        if ($dateoutput != '') {
1074            $datetimeobj = DateTime::createFromFormat('!Y-m-d H:i', $dateoutput);
1075            if ($datetimeobj) {
1076                $dateoutput = $datetimeobj->format($dateformatdetails['phpdate']);
1077            } else {
1078                $dateoutput = '';
1079            }
1080        }
1081
1082        // Max length of date : Get the date of 1999-12-30 at 32:59:59 to be sure to have space with non leading 0 format
1083        // "+1" makes room for a trailing space in date/time values
1084        $iLength = strlen(date($dateformatdetails['phpdate'], mktime(23, 59, 59, 12, 30, 1999))) + 1;
1085
1086        // Hide calendar (but show hour/minute) if there's no year, month or day in format
1087        $hideCalendar = strpos($dateformatdetails['jsdate'], 'Y') === false
1088        && strpos($dateformatdetails['jsdate'], 'D') === false
1089        && strpos($dateformatdetails['jsdate'], 'M') === false;
1090        /* Global datepicker configuration, muts be done before view (and twig from template can extend it then :) */
1091        if (!App()->getClientScript()->isScriptRegistered("setDatePickerGlobalOption", LSYii_ClientScript::POS_POSTSCRIPT)) {
1092            App()->getClientScript()->registerPackage('bootstrap-datetimepicker');
1093
1094            $aDefaultDatePicker = array(
1095                'locale'=>convertLStoDateTimePickerLocale(App()->language),
1096                'tooltips' => array(
1097                    'clear'=> gT('Clear selection'),
1098                    'prevMonth'=> gT('Previous month'),
1099                    'nextMonth'=> gT('Next month'),
1100                    'selectYear'=> gT('Select year'),
1101                    'prevYear'=> gT('Previous year'),
1102                    'nextYear'=> gT('Next year'),
1103                    'selectDecade'=> gT('Select decade'),
1104                    'prevDecade'=> gT('Previous decade'),
1105                    'nextDecade'=> gT('Next decade'),
1106                    'prevCentury'=> gT('Previous century'),
1107                    'nextCentury'=> gT('Next century'),
1108                    'selectTime'=> gT('Select time')
1109                ),
1110                'icons' => array(
1111                    'time'=> 'fa fa-clock-o',
1112                    'date'=> 'fa fa-calendar',
1113                    'up'=> 'fa fa-chevron-up',
1114                    'down'=> 'fa fa-chevron-down',
1115                    'previous'=> 'fa fa-chevron-left',
1116                    'next'=> 'fa fa-chevron-right',
1117                    'today'=> 'fa fa-calendar-check-o',
1118                    'clear'=> 'fa fa-trash-o',
1119                    'close'=> 'fa fa-closee'
1120                ),
1121                'allowInputToggle' =>true,
1122                'showClear' => true,
1123                'sideBySide' => true,
1124                //~ 'debug'=>true
1125            );
1126            App()->getClientScript()->registerScript("setDatePickerGlobalOption", "$.extend( $.fn.datetimepicker.defaults, ".json_encode($aDefaultDatePicker)." )", LSYii_ClientScript::POS_POSTSCRIPT);
1127        }
1128        // HTML for date question using datepicker
1129        $answer = doRender('/survey/questions/answer/date/selector/answer', array(
1130            'name'                   => $ia[1],
1131            'basename'               => $ia[1],
1132            'coreClass'              => $coreClass,
1133            'iLength'                => $iLength,
1134            'mindate'                => $mindate,
1135            'maxdate'                => $maxdate,
1136            'dateformatdetails'      => $dateformatdetails['dateformat'],
1137            'dateformatdetailsjs'    => $dateformatdetails['jsdate'],
1138            'dateformatdetailsphp'   => $dateformatdetails['phpdate'],
1139            'minuteStep'             => $aQuestionAttributes['dropdown_dates_minute_step'],
1140            'goodchars'              => "", // "return window.LS.goodchars(event,'".$goodchars."')", //  This won't work with non-latin keyboards
1141            'checkconditionFunction' => $checkconditionFunction.'(this.value, this.name, this.type)',
1142            'language'               => App()->language,
1143            'hidetip'                => trim($aQuestionAttributes['hide_tip']) == 0,
1144            'dateoutput'             => $dateoutput,
1145            'qid'                    => $ia[0],
1146            'hideCalendar'           => $hideCalendar
1147            ), true);
1148        App()->getClientScript()->registerScript('doPopupDate'.$ia[0], "doPopupDate({$ia[0]});", LSYii_ClientScript::POS_POSTSCRIPT);
1149    }
1150    $inputnames[] = $ia[1];
1151
1152    return array($answer, $inputnames);
1153}
1154
1155// ---------------------------------------------------------------
1156function do_language($ia)
1157{
1158    $checkconditionFunction = "checkconditions";
1159    $answerlangs            = Survey::model()->findByPk(Yii::app()->getConfig('surveyID'))->additionalLanguages;
1160    $answerlangs[]          = Survey::model()->findByPk(Yii::app()->getConfig('surveyID'))->language;
1161    $sLang                  = $_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang'];
1162    $coreClass              = "ls-answers answer-item dropdow-item langage-item";
1163    $inputnames = array();
1164
1165    if (!in_array($sLang, $answerlangs)) {
1166        $sLang = Survey::model()->findByPk(Yii::app()->getConfig('surveyID'))->language;
1167    }
1168
1169    $inputnames[] = $ia[1];
1170
1171    $languageData = array(
1172        'name'=>$ia[1],
1173        'basename'=> $ia[1],
1174        'checkconditionFunction'=>$checkconditionFunction.'(this.value, this.name, this.type)',
1175        'answerlangs'=>$answerlangs,
1176        'sLang'=>$sLang,
1177        'coreClass'=>$coreClass,
1178    );
1179
1180    $answer = doRender('/survey/questions/answer/language/answer', $languageData, true);
1181    return array($answer, $inputnames);
1182}
1183
1184// ---------------------------------------------------------------
1185// TMSW TODO - Can remove DB query by passing in answer list from EM
1186function do_list_dropdown($ia)
1187{
1188    //// Init variables
1189    $inputnames = array();
1190
1191    // General variables
1192    $checkconditionFunction = "checkconditions";
1193
1194    // Question attribute variables
1195    $aQuestionAttributes = QuestionAttribute::model()->getQuestionAttributes($ia[0]);
1196    $iSurveyId              = Yii::app()->getConfig('surveyID'); // survey id
1197    $sSurveyLang            = $_SESSION['survey_'.$iSurveyId]['s_lang']; // survey language
1198    $othertext              = (trim($aQuestionAttributes['other_replace_text'][$sSurveyLang]) != '') ? $aQuestionAttributes['other_replace_text'][$sSurveyLang] : gT('Other:'); // text for 'other'
1199    $optCategorySeparator   = (trim($aQuestionAttributes['category_separator']) != '') ? $aQuestionAttributes['category_separator'] : '';
1200    $coreClass              = "ls-answers answer-item dropdown-item";
1201
1202    if ($optCategorySeparator == '') {
1203        unset($optCategorySeparator);
1204    }
1205
1206    //// Retrieving datas
1207
1208    // Getting question
1209    $oQuestion = Question::model()->findByPk(array('qid'=>$ia[0], 'language'=>$sSurveyLang));
1210    $other     = $oQuestion->other;
1211
1212    // Getting answers
1213    $ansresult = $oQuestion->getOrderedAnswers($aQuestionAttributes['random_order'], $aQuestionAttributes['alphasort']);
1214
1215    $dropdownSize = null;
1216
1217    if (isset($aQuestionAttributes['dropdown_size']) && $aQuestionAttributes['dropdown_size'] > 0) {
1218        $_height    = sanitize_int($aQuestionAttributes['dropdown_size']);
1219        $_maxHeight = count($ansresult);
1220
1221        if ((!is_null($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]]) || $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] === '') && $ia[6] != 'Y' && $ia[6] != 'Y' && SHOW_NO_ANSWER == 1) {
1222            ++$_maxHeight; // for No Answer
1223        }
1224
1225        if (isset($other) && $other == 'Y') {
1226            ++$_maxHeight; // for Other
1227        }
1228
1229        if (is_null($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]])) {
1230            ++$_maxHeight; // for 'Please choose:'
1231        }
1232
1233        if ($_height > $_maxHeight) {
1234            $_height = $_maxHeight;
1235        }
1236        $dropdownSize = $_height;
1237    }
1238
1239    $prefixStyle = 0;
1240
1241    if (isset($aQuestionAttributes['dropdown_prefix'])) {
1242        $prefixStyle = sanitize_int($aQuestionAttributes['dropdown_prefix']);
1243    }
1244
1245    $_rowNum = 0;
1246    $_prefix = '';
1247
1248    $value            = $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]];
1249    $sOptions         = '';
1250
1251    // If no answer previously selected
1252    if (is_null($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]]) || $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] === '') {
1253        $sOptions .= doRender('/survey/questions/answer/list_dropdown/rows/option', array(
1254            'name'=> $ia[1],
1255            'value'=>'',
1256            'opt_select'=> ($dropdownSize) ? SELECTED : "", /* needed width size, not for single first one */
1257            'answer'=>gT('Please choose...')
1258            ), true);
1259    }
1260
1261    if (!isset($optCategorySeparator)) {
1262        foreach ($ansresult as $ansrow) {
1263            $opt_select = '';
1264            if ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] == $ansrow['code']) {
1265                $opt_select = SELECTED;
1266            }
1267            if ($prefixStyle == 1) {
1268                $_prefix = ++$_rowNum.') ';
1269            }
1270            // ==> rows
1271            $sOptions .= doRender('/survey/questions/answer/list_dropdown/rows/option', array(
1272                'name'=> $ia[1],
1273                'value'=>$ansrow['code'],
1274                'opt_select'=>$opt_select,
1275                'answer'=>$_prefix.$ansrow['answer'],
1276                ), true);
1277        }
1278    } else {
1279        $defaultopts = array();
1280        $optgroups = array();
1281        foreach ($ansresult as $ansrow) {
1282            // Let's sort answers in an array indexed by subcategories
1283            @list($categorytext, $answertext) = explode($optCategorySeparator, $ansrow['answer']);
1284            // The blank category is left at the end outside optgroups
1285            if ($categorytext == '') {
1286                $defaultopts[] = array('code' => $ansrow['code'], 'answer' => $answertext);
1287            } else {
1288                $optgroups[$categorytext][] = array('code' => $ansrow['code'], 'answer' => $answertext);
1289            }
1290        }
1291
1292        foreach ($optgroups as $categoryname => $optionlistarray) {
1293            $sOptGroupOptions = '';
1294            foreach ($optionlistarray as $optionarray) {
1295                if ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] == $optionarray['code']) {
1296                    $opt_select = SELECTED;
1297                } else {
1298                    $opt_select = '';
1299                }
1300
1301                // ==> rows
1302                $sOptGroupOptions .= doRender('/survey/questions/answer/list_dropdown/rows/option', array(
1303                    'name'=> $ia[1],
1304                    'value'=>$optionarray['code'],
1305                    'opt_select'=>$opt_select,
1306                    'answer'=>flattenText($optionarray['answer'])
1307                    ), true);
1308            }
1309
1310
1311            $sOptions .= doRender('/survey/questions/answer/list_dropdown/rows/optgroup', array(
1312                'categoryname'      => flattenText($categoryname),
1313                'sOptGroupOptions'  => $sOptGroupOptions,
1314                ), true);
1315        }
1316        foreach ($defaultopts as $optionarray) {
1317            if ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] == $optionarray['code']) {
1318                $opt_select = SELECTED;
1319            } else {
1320                $opt_select = '';
1321            }
1322
1323            // ==> rows
1324            $sOptions .= doRender('/survey/questions/answer/list_dropdown/rows/option', array(
1325                'name'=> $ia[1],
1326                'value'=>$optionarray['code'],
1327                'opt_select'=>$opt_select,
1328                'answer'=>flattenText($optionarray['answer'])
1329                ), true);
1330        }
1331    }
1332
1333    if (isset($other) && $other == 'Y') {
1334        if ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] == '-oth-') {
1335            $opt_select = SELECTED;
1336        } else {
1337            $opt_select = '';
1338        }
1339        if ($prefixStyle == 1) {
1340            $_prefix = ++$_rowNum.') ';
1341        }
1342
1343        $sOptions .= doRender('/survey/questions/answer/list_dropdown/rows/option', array(
1344            'name'=> $ia[1],
1345            'classes'=>'other-item',
1346            'value'=>'-oth-',
1347            'opt_select'=>$opt_select,
1348            'answer'=>flattenText($_prefix.$othertext)
1349            ), true);
1350    }
1351
1352    if (!(is_null($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]]) || $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] === "") && $ia[6] != 'Y' && SHOW_NO_ANSWER == 1) {
1353        if ($prefixStyle == 1) {
1354            $_prefix = ++$_rowNum.') ';
1355        }
1356
1357        $optionData = array(
1358            'name'=> $ia[1],
1359            'classes'=>'noanswer-item',
1360            'value'=>'',
1361            'opt_select'=> '', // Never selected
1362            'answer'=>$_prefix.gT('No answer')
1363        );
1364        // ==> rows
1365        $sOptions .= doRender('/survey/questions/answer/list_dropdown/rows/option', $optionData, true);
1366    }
1367
1368    $sOther = '';
1369    if (isset($other) && $other == 'Y') {
1370        $aData = array();
1371        $aData['name'] = $ia[1];
1372        $aData['checkconditionFunction'] = $checkconditionFunction;
1373        $aData['display'] = ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] != '-oth-') ? 'display: none;' : '';
1374        $aData['label'] = $othertext;
1375        $thisfieldname = "$ia[1]other";
1376        $aData['value'] = (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$thisfieldname])) ?htmlspecialchars($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$thisfieldname], ENT_QUOTES) : '';
1377
1378        // ==> other
1379        $sOther .= doRender('/survey/questions/answer/list_dropdown/rows/othertext', $aData, true);
1380
1381        $inputnames[] = $ia[1].'other';
1382    }
1383
1384    // ==> answer
1385    $answer = doRender('/survey/questions/answer/list_dropdown/answer', array(
1386        'sOptions'               => $sOptions,
1387        'sOther'                 => $sOther,
1388        'name'                   => $ia[1],
1389        'basename'               => $ia[1],
1390        'dropdownSize'           => $dropdownSize,
1391        'checkconditionFunction' => $checkconditionFunction,
1392        'value'                  => $value,
1393        'coreClass'              => $coreClass
1394        ), true);
1395
1396
1397    $inputnames[] = $ia[1];
1398
1399    //Time Limit Code
1400    if (trim($aQuestionAttributes['time_limit']) != '') {
1401        $answer .= return_timer_script($aQuestionAttributes, $ia);
1402    }
1403    //End Time Limit Code
1404
1405    return array($answer, $inputnames);
1406}
1407
1408// ---------------------------------------------------------------
1409// TMSW TODO - Can remove DB query by passing in answer list from EM
1410
1411function do_list_radio($ia)
1412{
1413    //// Init variables
1414
1415    // General variables
1416    global $thissurvey;
1417    $kpclass                = testKeypad($thissurvey['nokeyboard']); // Virtual keyboard (probably obsolete today)
1418    $checkconditionFunction = "checkconditions"; // name of the function to check condition TODO : check is used more than once
1419    $iSurveyId              = Yii::app()->getConfig('surveyID'); // survey id
1420    $sSurveyLang            = $_SESSION['survey_'.$iSurveyId]['s_lang']; // survey language
1421    $inputnames = array();
1422    $coreClass = "ls-answers answers-list radio-list";
1423    // Question attribute variables
1424
1425    $aQuestionAttributes = QuestionAttribute::model()->getQuestionAttributes($ia[0]);
1426    $othertext           = (trim($aQuestionAttributes['other_replace_text'][$sSurveyLang]) != '') ? $aQuestionAttributes['other_replace_text'][$sSurveyLang] : gT('Other:'); // text for 'other'
1427    $iNbCols             = (trim($aQuestionAttributes['display_columns']) != '') ? $aQuestionAttributes['display_columns'] : 1; // number of columns
1428    $sTimer              = (trim($aQuestionAttributes['time_limit']) != '') ?return_timer_script($aQuestionAttributes, $ia) : ''; //Time Limit
1429    //// Retrieving datas
1430
1431    // Getting question
1432    $oQuestion = Question::model()->findByPk(array('qid'=>$ia[0], 'language'=>$sSurveyLang));
1433    $other     = $oQuestion->other;
1434
1435    // Getting answers
1436    $ansresult = $oQuestion->getOrderedAnswers($aQuestionAttributes['random_order'], $aQuestionAttributes['alphasort']);
1437    $anscount  = count($ansresult);
1438    $anscount  = ($other == 'Y') ? $anscount + 1 : $anscount; //COUNT OTHER AS AN ANSWER FOR MANDATORY CHECKING!
1439    $anscount  = ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1) ? $anscount + 1 : $anscount; //Count up if "No answer" is showing
1440
1441    //// Columns containing answer rows, set by user in question attribute
1442    /// TODO : move to a dedicated function
1443
1444    // setting variables
1445    $iRowCount        = 0;
1446    $isOpen           = false; // Is a column opened
1447
1448    if ($iNbCols > 1) {
1449        // Add a class on the wrapper
1450        $coreClass .= " multiple-list nbcol-{$iNbCols}";
1451        // First we calculate the width of each column
1452        // Max number of column is 12 http://getbootstrap.com/css/#grid
1453        $iColumnWidth = round(12 / $iNbCols);
1454        $iColumnWidth = ($iColumnWidth >= 1) ? $iColumnWidth : 1;
1455        $iColumnWidth = ($iColumnWidth <= 12) ? $iColumnWidth : 12;
1456
1457        // Then, we calculate how many answer rows in each column
1458        $iMaxRowsByColumn = ceil($anscount / $iNbCols);
1459    } else {
1460        $iColumnWidth = 12;
1461        $iMaxRowsByColumn = $anscount + 3; // No max : anscount + no answer + other + 1 by security
1462    }
1463
1464    // Get array_filter stuff
1465
1466    $i = 0;
1467
1468    $sRows = '';
1469    foreach ($ansresult as $key=>$ansrow) {
1470        $i++; // general count of loop, to check if the item is the last one for column process. Never reset.
1471        $iRowCount++; // counter of number of row by column. Is reset to zero each time a column is full.
1472        $myfname = $ia[1].$ansrow['code'];
1473
1474        $checkedState = '';
1475        if ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] == $ansrow['code']) {
1476            $checkedState = 'CHECKED';
1477        }
1478
1479        //list($htmltbody2, $hiddenfield)=return_array_filter_strings($ia, $aQuestionAttributes, $thissurvey, $ansrow, $myfname, '', $myfname, "div","form-group answer-item radio-item");
1480        /* Check for array_filter */
1481        $sDisplayStyle = return_display_style($ia, $aQuestionAttributes, $thissurvey, $myfname);
1482
1483        ////
1484        // Open Column
1485        // The column is opened if user set more than one column in question attribute
1486        // and if this is the first answer row, or if the column has been closed and the row count reset before.
1487        if ($iRowCount == 1) {
1488            $sRows  .= doRender('/survey/questions/answer/listradio/columns/column_header', array('iColumnWidth' => $iColumnWidth), true);
1489            $isOpen  = true; // If a column is not closed, it will be closed at the end of the process
1490        }
1491
1492
1493        ////
1494        // Insert row
1495        // Display the answer row
1496        $sRows .= doRender('/survey/questions/answer/listradio/rows/answer_row', array(
1497            'sDisplayStyle' => $sDisplayStyle,
1498            'name'          => $ia[1],
1499            'code'          => $ansrow['code'],
1500            'answer'        => $ansrow['answer'],
1501            'checkedState'  => $checkedState,
1502            'myfname'       => $myfname,
1503            'i'             => $i,
1504            ), true);
1505
1506        ////
1507        // Close column
1508        // The column is closed if the user set more than one column in question attribute
1509        // and if the max answer rows by column is reached.
1510        // If max answer rows by column is not reached while there is no more answer,
1511        // the column will remain opened, and it will be closed by 'other' answer row if set or at the end of the process
1512        if ($iRowCount == $iMaxRowsByColumn) {
1513            $last      = ($i == $anscount) ?true:false; // If this loop count equal to the number of answers, then this answer is the last one.
1514            $sRows    .= doRender('/survey/questions/answer/listradio/columns/column_footer', array('last'=>$last), true);
1515            $iRowCount = 0;
1516            $isOpen    = false;
1517        }
1518    }
1519
1520    if (isset($other) && $other == 'Y') {
1521        $iRowCount++;
1522        $i++;
1523        $sSeparator = getRadixPointData($thissurvey['surveyls_numberformat']);
1524        $sSeparator = $sSeparator['separator'];
1525
1526        if ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] == '-oth-') {
1527            $checkedState = CHECKED;
1528        } else {
1529            $checkedState = '';
1530        }
1531
1532        $myfname = $thisfieldname = $ia[1].'other';
1533
1534        if (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$thisfieldname])) {
1535            $dispVal = $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$thisfieldname];
1536            if ($aQuestionAttributes['other_numbers_only'] == 1) {
1537                $dispVal = str_replace('.', $sSeparator, $dispVal);
1538            }
1539            $answer_other = ' value="'.htmlspecialchars($dispVal, ENT_QUOTES).'"';
1540        } else {
1541            $answer_other = ' value=""';
1542        }
1543
1544        ////
1545        // Open Column
1546        // The column is opened if user set more than one column in question attribute
1547        // and if this is the first answer row (should never happen for 'other'),
1548        // or if the column has been closed and the row count reset before.
1549        if ($iRowCount == 1) {
1550            $sRows .= doRender('/survey/questions/answer/listradio/columns/column_header', array('iColumnWidth' => $iColumnWidth, 'first'=>false), true);
1551        }
1552        $sDisplayStyle = return_display_style($ia, $aQuestionAttributes, $thissurvey, $myfname);
1553
1554        ////
1555        // Insert row
1556        // Display the answer row
1557        $sRows .= doRender('/survey/questions/answer/listradio/rows/answer_row_other', array(
1558            'name' => $ia[1],
1559            'answer_other'=>$answer_other,
1560            'myfname'=>$myfname,
1561            'sDisplayStyle' => $sDisplayStyle,
1562            'othertext'=>$othertext,
1563            'checkedState'=>$checkedState,
1564            'kpclass'=>$kpclass,
1565            'checkconditionFunction'=>$checkconditionFunction,
1566            'numbers_only' => ($aQuestionAttributes['other_numbers_only'] == 1),
1567            ), true);
1568
1569        $inputnames[] = $thisfieldname;
1570
1571        ////
1572        // Close column
1573        // The column is closed if the user set more than one column in question attribute
1574        // We can't be sure it's the last one because of 'no answer' item
1575        if ($iRowCount == $iMaxRowsByColumn) {
1576            $sRows .= doRender('/survey/questions/answer/listradio/columns/column_footer', array(), true);
1577            $iRowCount = 0;
1578            $isOpen = false;
1579        }
1580    }
1581
1582    if ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1) {
1583        $iRowCount++;
1584
1585        if ((!isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]]) || $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] == '') || ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] == ' ')) {
1586            $check_ans = CHECKED; //Check the "no answer" radio button if there is no answer in session.
1587        } else {
1588            $check_ans = '';
1589        }
1590
1591        if ($iRowCount == 1) {
1592            $sRows .= doRender('/survey/questions/answer/listradio/columns/column_header', array('iColumnWidth' => $iColumnWidth), true);
1593        }
1594
1595        $sRows .= doRender('/survey/questions/answer/listradio/rows/answer_row_noanswer', array(
1596            'name'=>$ia[1],
1597            'check_ans'=>$check_ans,
1598            'checkconditionFunction'=>$checkconditionFunction,
1599            ), true);
1600
1601
1602        ////
1603        // Close column
1604        // 'No answer' is always the last answer, so it's always closing the col and the bootstrap row containing the columns
1605        $sRows .= doRender('/survey/questions/answer/listradio/columns/column_footer', array('last'=>true), true);
1606        $isOpen = false;
1607    }
1608
1609    ////
1610    // Close column
1611    // if on column has been opened and not closed
1612    // That can happen only when no 'other' option is set, and the maximum answer rows has not been reached in the last question
1613    if ($isOpen) {
1614        $sRows .= doRender('/survey/questions/answer/listradio/columns/column_footer', array('last'=>true), true);
1615    }
1616
1617    //END OF ITEMS
1618
1619    // ==> answer
1620    $answer = doRender('/survey/questions/answer/listradio/answer', array(
1621        'sTimer'=>$sTimer,
1622        'sRows' => $sRows,
1623        'name'  => $ia[1],
1624        'basename' => $ia[1],
1625        'value' => $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]],
1626        'coreClass'=>$coreClass,
1627        ), true);
1628
1629    $inputnames[] = $ia[1];
1630    return array($answer, $inputnames);
1631}
1632
1633// ---------------------------------------------------------------
1634// TMSW TODO - Can remove DB query by passing in answer list from EM
1635function do_listwithcomment($ia)
1636{
1637    //// Init variables
1638
1639    // General variables
1640    global $thissurvey;
1641    $kpclass                = testKeypad($thissurvey['nokeyboard']); // Virtual keyboard (probably obsolete today)
1642    $checkconditionFunction = "checkconditions";
1643    $iSurveyId              = Yii::app()->getConfig('surveyID'); // survey id
1644    $sSurveyLang            = $_SESSION['survey_'.$iSurveyId]['s_lang']; // survey language
1645    $maxoptionsize          = 35;
1646    $coreClass              = "ls-answers";
1647    $inputnames = array();
1648
1649    $aQuestionAttributes = QuestionAttribute::model()->getQuestionAttributes($ia[0]); // Question attribute variables
1650    $oQuestion           = Question::model()->findByPk(array('qid'=>$ia[0], 'language'=>$sSurveyLang)); // Getting question
1651
1652    // Getting answers
1653    $ansresult    = $oQuestion->getOrderedAnswers($aQuestionAttributes['random_order'], $aQuestionAttributes['alphasort']);
1654    $anscount     = count($ansresult);
1655    $hint_comment = gT('Please enter your comment here');
1656
1657    if ($aQuestionAttributes['use_dropdown'] != 1) {
1658        $sRows = '';
1659        $li_classes = 'answer-item radio-item';
1660        foreach ($ansresult as $ansrow) {
1661            $check_ans = '';
1662
1663            if ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] == $ansrow['code']) {
1664                $check_ans = CHECKED;
1665            }
1666
1667            $itemData = array(
1668                'li_classes'=>$li_classes,
1669                'name'                   => $ia[1],
1670                'id'                     => 'answer'.$ia[1].$ansrow['code'],
1671                'value'                  => $ansrow['code'],
1672                'check_ans'              => $check_ans,
1673                'checkconditionFunction' => $checkconditionFunction.'(this.value, this.name, this.type);',
1674                'labeltext'              => $ansrow['answer'],
1675            );
1676            $sRows .= doRender('/survey/questions/answer/list_with_comment/list/rows/answer_row', $itemData, true);
1677        }
1678
1679        // ==> rows
1680        $check_ans = '';
1681        if ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1) {
1682            if ((!isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]]) || $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] == '') || ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] == ' ')) {
1683                $check_ans = CHECKED;
1684            } elseif (($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] || $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] != '')) {
1685                $check_ans = '';
1686            }
1687
1688            $itemData = array(
1689                'li_classes'=>$li_classes.' noanswer-item',
1690                'name'=>$ia[1],
1691                'id'=>'answer'.$ia[1],
1692                'value'=>'',
1693                'check_ans'=>$check_ans,
1694                'checkconditionFunction'=>$checkconditionFunction.'(this.value, this.name, this.type)',
1695                'labeltext'=>gT('No answer'),
1696            );
1697
1698            $sRows .= doRender('/survey/questions/answer/list_with_comment/list/rows/answer_row', $itemData, true);
1699        }
1700
1701        $fname2 = $ia[1].'comment';
1702        $tarows = ($anscount > 8) ? $anscount / 1.2 : 4;
1703
1704
1705        $answer = doRender('/survey/questions/answer/list_with_comment/list/answer', array(
1706            'sRows'             => $sRows,
1707            'id'                => 'answer'.$ia[1].'comment',
1708            'basename'          => $ia[1],
1709            'coreClass'         => $coreClass,
1710            'hint_comment'      => $hint_comment,
1711            'kpclass'           => $kpclass,
1712            'name'              => $ia[1].'comment',
1713            'tarows'            => floor($tarows),
1714            'has_comment_saved' => isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$fname2]) && $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$fname2],
1715            'comment_saved'     => htmlspecialchars($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$fname2]),
1716            'java_name'         => 'java'.$ia[1],
1717            'java_id'           => 'java'.$ia[1],
1718            'java_value'        => $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]]
1719            ), true);
1720
1721
1722        $inputnames[] = $ia[1];
1723        $inputnames[] = $ia[1].'comment';
1724    } else {
1725        //Dropdown list
1726        $sOptions = '';
1727        foreach ($ansresult as $ansrow) {
1728            $check_ans = '';
1729            if ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] == $ansrow['code']) {
1730                $check_ans = SELECTED;
1731            }
1732
1733            $itemData = array(
1734                'value' => $ansrow['code'],
1735                'check_ans' => $check_ans,
1736                'option_text' => $ansrow['answer'],
1737            );
1738            $sOptions .= doRender('/survey/questions/answer/list_with_comment/dropdown/rows/option', $itemData, true);
1739
1740            if (strlen($ansrow['answer']) > $maxoptionsize) {
1741                $maxoptionsize = strlen($ansrow['answer']);
1742            }
1743        }
1744        if ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1 && !is_null($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]])) {
1745            $check_ans = "";
1746            if (trim($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]]) == '') {
1747                $check_ans = SELECTED;
1748            }
1749            $itemData = array(
1750                'classes' => ' noanswer-item ',
1751                'value' => '',
1752                'check_ans' => $check_ans,
1753                'option_text' => gT('No answer'),
1754            );
1755            $sOptions .= doRender('/survey/questions/answer/list_with_comment/dropdown/rows/option', $itemData, true);
1756        }
1757        $fname2 = $ia[1].'comment';
1758
1759        if ($anscount > 8) {
1760            $tarows = $anscount / 1.2;
1761        } else {
1762            $tarows = 4;
1763        }
1764
1765        if ($tarows > 15) {
1766            $tarows = 15;
1767        }
1768        $maxoptionsize = $maxoptionsize * 0.72;
1769
1770        if ($maxoptionsize < 33) {
1771            $maxoptionsize = 33;
1772        }
1773        if ($maxoptionsize > 70) {
1774            $maxoptionsize = 70;
1775        }
1776
1777
1778        $answer = doRender('/survey/questions/answer/list_with_comment/dropdown/answer', array(
1779            'sOptions'               => $sOptions,
1780            'name'                   => $ia[1],
1781            'coreClass'              => $coreClass,
1782            'id'                     => 'answer'.$ia[1],
1783            'basename'               => $ia[1],
1784            'show_noanswer'          => is_null($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]]),
1785            'label_text'             => $hint_comment,
1786            'kpclass'                => $kpclass,
1787            'tarows'                 => $tarows,
1788            'maxoptionsize'          => $maxoptionsize,
1789            'comment_saved'          => htmlspecialchars($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$fname2]), /* htmlspecialchars(null)=="" right ? */
1790            'value'                  => $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]],
1791            ), true);
1792
1793        $inputnames[] = $ia[1];
1794        $inputnames[] = $ia[1].'comment';
1795    }
1796    return array($answer, $inputnames);
1797}
1798
1799function do_ranking($ia)
1800{
1801    $aQuestionAttributes    = QuestionAttribute::model()->getQuestionAttributes($ia[0]);
1802    $coreClass              = "ls-answers answers-lists select-sortable-lists";
1803    if ($aQuestionAttributes['random_order'] == 1) {
1804        $ansquery = "SELECT * FROM {{answers}} WHERE qid=$ia[0] AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' and scale_id=0 ORDER BY ".dbRandom();
1805    } else {
1806        $ansquery = "SELECT * FROM {{answers}} WHERE qid=$ia[0] AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' and scale_id=0 ORDER BY sortorder, answer";
1807    }
1808
1809    $ansresult = Yii::app()->db->createCommand($ansquery)->query()->readAll();
1810    $anscount  = count($ansresult);
1811    $max_subquestions = intval($aQuestionAttributes['max_subquestions']) > 0 ? intval($aQuestionAttributes['max_subquestions']) : $anscount;
1812    $max_subquestions = min($max_subquestions,$anscount); // Can not be upper than current answers #14899
1813    if (trim($aQuestionAttributes["max_answers"]) != '') {
1814        $max_answers = "min(".trim($aQuestionAttributes["max_answers"]).",".$max_subquestions.")";
1815    } else {
1816        $max_answers = $max_subquestions;
1817    }
1818    $max_answers = LimeExpressionManager::ProcessString("{{$max_answers}}", $ia[0]);
1819    // Get the max number of line needed
1820    if (ctype_digit($max_answers) && intval($max_answers) < $max_subquestions) {
1821        $iMaxLine = $max_answers;
1822    } else {
1823        $iMaxLine = $max_subquestions;
1824    }
1825    if (trim($aQuestionAttributes["min_answers"]) != '') {
1826        $min_answers = trim($aQuestionAttributes["min_answers"]);
1827    } else {
1828        $min_answers = 0;
1829    }
1830    $min_answers = LimeExpressionManager::ProcessString("{{$min_answers}}", $ia[0]);
1831
1832    $answer = '';
1833    // First start by a ranking without javascript : just a list of select box
1834    // construction select box
1835    $answers = array();
1836
1837    foreach ($ansresult as $ansrow) {
1838        $answers[] = $ansrow;
1839    }
1840
1841    $inputnames = array();
1842    $sSelects   = '';
1843    $myfname    = '';
1844
1845    $thisvalue = "";
1846    for ($i = 1; $i <= $iMaxLine; $i++) {
1847        $myfname = $ia[1].$i;
1848        $labeltext = ($i == 1) ?gT('First choice') : sprintf(gT('Choice of rank %s'), $i);
1849        $itemDatas = array();
1850
1851        if (!$_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname]) {
1852            $itemDatas[] = array(
1853                'value'      => '',
1854                'selected'   => 'SELECTED',
1855                'classes'    => '',
1856                'id'         => '',
1857                'optiontext' => gT('Please choose...'),
1858            );
1859        }
1860
1861        foreach ($answers as $ansrow) {
1862            if (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname]) && $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] == $ansrow['code']) {
1863                $selected = SELECTED;
1864                $thisvalue = $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname];
1865            } else {
1866                $selected = '';
1867            }
1868
1869            $itemDatas[] = array(
1870                'value' => $ansrow['code'],
1871                'selected'=>$selected,
1872                'classes'=>'',
1873                'optiontext'=>flattenText($ansrow['answer'])
1874            );
1875        }
1876
1877        $sSelects .= doRender(
1878            '/survey/questions/answer/ranking/rows/answer_row',
1879            array(
1880                'myfname' => $myfname,
1881                'labeltext' => $labeltext,
1882                'options' => $itemDatas,
1883                'thisvalue' => $thisvalue
1884            ),
1885            true
1886        );
1887
1888        $inputnames[] = $myfname;
1889    }
1890
1891    $rankingTranslation = 'LSvar.lang.rankhelp="'.gT("Double-click or drag-and-drop items in the left list to move them to the right - your highest ranking item should be on the top right, moving through to your lowest ranking item.", 'js').'";';
1892    App()->getClientScript()->registerScript("rankingTranslation", $rankingTranslation, CClientScript::POS_BEGIN);
1893
1894    if (trim($aQuestionAttributes['choice_title'][App()->language]) != '') {
1895        $choice_title = htmlspecialchars(trim($aQuestionAttributes['choice_title'][App()->language]), ENT_QUOTES);
1896    } else {
1897        $choice_title = gT("Your Choices", 'html');
1898    }
1899    if (trim($aQuestionAttributes['rank_title'][App()->language]) != '') {
1900        $rank_title = htmlspecialchars(trim($aQuestionAttributes['rank_title'][App()->language]), ENT_QUOTES);
1901    } else {
1902        $rank_title = gT("Your Ranking", 'html');
1903    }
1904
1905    $answer .= doRender('/survey/questions/answer/ranking/answer', array(
1906        'coreClass'         => $coreClass,
1907        'sSelects'          => $sSelects,
1908        'thisvalue'         => $thisvalue,
1909        'answers'           => $answers,
1910        'myfname'           => $myfname,
1911        'labeltext'         => (isset($labeltext)) ? $labeltext : '',
1912        'qId'               => $ia[0],
1913        'rankingName'       => $ia[1],
1914        'basename'          => $ia[1],
1915        'max_answers'       => $max_answers,
1916        'min_answers'       => $min_answers,
1917        'choice_title'      => $choice_title,
1918        'rank_title'        => $rank_title,
1919        'showpopups'        => $aQuestionAttributes["showpopups"],
1920        'samechoiceheight'  => $aQuestionAttributes["samechoiceheight"],
1921        'samelistheight'    => $aQuestionAttributes["samelistheight"],
1922        ), true);
1923    return array($answer, $inputnames);
1924}
1925
1926// ---------------------------------------------------------------
1927function do_multiplechoice($ia)
1928{
1929    //// Init variables
1930
1931    // General variables
1932    global $thissurvey;
1933    $kpclass                = testKeypad($thissurvey['nokeyboard']); // Virtual keyboard (probably obsolete today)
1934    $inputnames             = array(); // It is used!
1935    $checkconditionFunction = "checkconditions"; // name of the function to check condition TODO : check is used more than once
1936    $iSurveyId              = Yii::app()->getConfig('surveyID'); // survey id
1937    $sSurveyLang            = $_SESSION['survey_'.$iSurveyId]['s_lang']; // survey language
1938    $coreClass = "ls-answers checkbox-list answers-list";
1939    // Question attribute variables
1940    $aQuestionAttributes    = (array) QuestionAttribute::model()->getQuestionAttributes($ia[0]); // Question attributes
1941    $othertext              = (trim($aQuestionAttributes['other_replace_text'][$sSurveyLang]) != '') ? $aQuestionAttributes['other_replace_text'][$sSurveyLang] : gT('Other:'); // text for 'other'
1942    $iNbCols                = (trim($aQuestionAttributes['display_columns']) != '') ? $aQuestionAttributes['display_columns'] : 1; // number of columns
1943    $aSeparator             = getRadixPointData($thissurvey['surveyls_numberformat']);
1944    $sSeparator             = $aSeparator['separator'];
1945
1946    $oth_checkconditionFunction = ($aQuestionAttributes['other_numbers_only'] == 1) ? "fixnum_checkconditions" : "checkconditions";
1947
1948    //// Retrieving datas
1949
1950    // Getting question
1951    $oQuestion = Question::model()->findByPk(array('qid'=>$ia[0], 'language'=>$sSurveyLang));
1952    $other     = $oQuestion->other;
1953
1954    // Getting answers
1955    $ansresult = $oQuestion->getOrderedSubQuestions($aQuestionAttributes['random_order'], $aQuestionAttributes['exclude_all_others']);
1956    $anscount  = count($ansresult);
1957    $anscount  = ($other == 'Y') ? $anscount + 1 : $anscount; //COUNT OTHER AS AN ANSWER FOR MANDATORY CHECKING!
1958
1959    // First we calculate the width of each column
1960    // Max number of column is 12 http://getbootstrap.com/css/#grid
1961    $iColumnWidth = round(12 / $iNbCols);
1962    $iColumnWidth = ($iColumnWidth >= 1) ? $iColumnWidth : 1;
1963    $iColumnWidth = ($iColumnWidth <= 12) ? $iColumnWidth : 12;
1964    $iMaxRowsByColumn = ceil($anscount / $iNbCols);
1965
1966    if ($iNbCols > 1) {
1967        $coreClass .= " multiple-list nbcol-{$iNbCols}";
1968    }
1969
1970    $aRows = [];
1971    foreach ($ansresult as $ansrow) {
1972        $myfname = $ia[1].$ansrow['title'];
1973
1974        $relevanceClass = currentRelevecanceClass($iSurveyId, $ia[1], $myfname, $aQuestionAttributes);
1975        $checkedState = '';
1976        /* If the question has already been ticked, check the checkbox */
1977        if (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname])) {
1978            if ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] == 'Y') {
1979                $checkedState = 'CHECKED';
1980            }
1981        }
1982
1983        $sCheckconditionFunction = $checkconditionFunction.'(this.value, this.name, this.type)';
1984        $sValue                  = (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname])) ? $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] : '';
1985        $inputnames[]            = $myfname;
1986
1987
1988        ////
1989        // Insert row
1990        // Display the answer row
1991        $aRows[] = array(
1992            'name'                    => $ia[1], // field name
1993            'title'                   => $ansrow['title'],
1994            'question'                => $ansrow['question'],
1995            'ansrow'                  => $ansrow,
1996            'checkedState'            => $checkedState,
1997            'sCheckconditionFunction' => $sCheckconditionFunction,
1998            'myfname'                 => $myfname,
1999            'sValue'                  => $sValue,
2000            'relevanceClass'          => $relevanceClass,
2001            );
2002    }
2003
2004    //==>  rows
2005    if ($other == 'Y') {
2006        $myfname = $ia[1].'other';
2007        $relevanceClass = currentRelevecanceClass($iSurveyId, $ia[1], $myfname, $aQuestionAttributes);
2008        $checkedState = '';
2009        // othercbox can be not display, because only input text goes to database
2010        if (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname]) && trim($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname]) != '') {
2011            $checkedState = 'CHECKED';
2012        }
2013
2014        $sValue = '';
2015        if (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname])) {
2016            $dispVal = $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname];
2017            if ($aQuestionAttributes['other_numbers_only'] == 1) {
2018                $dispVal = str_replace('.', $sSeparator, $dispVal);
2019            }
2020            $sValue .= htmlspecialchars($dispVal, ENT_QUOTES);
2021        }
2022
2023        // TODO : check if $sValueHidden === $sValue
2024        $sValueHidden = '';
2025        if (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname])) {
2026            $dispVal = $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname];
2027            if ($aQuestionAttributes['other_numbers_only'] == 1) {
2028                $dispVal = str_replace('.', $sSeparator, $dispVal);
2029            }
2030            $sValueHidden = htmlspecialchars($dispVal, ENT_QUOTES);
2031            ;
2032        }
2033
2034        $inputnames[] = $myfname;
2035        ++$anscount;
2036
2037        ////
2038        // Insert row
2039        // Display the answer row
2040        $aRows[] = array(
2041            'myfname'                    => $myfname,
2042            'othertext'                  => $othertext,
2043            'checkedState'               => $checkedState,
2044            'kpclass'                    => $kpclass,
2045            'sValue'                     => $sValue,
2046            'oth_checkconditionFunction' => $oth_checkconditionFunction,
2047            'checkconditionFunction'     => $checkconditionFunction,
2048            'sValueHidden'               => $sValueHidden,
2049            'relevanceClass'             => $relevanceClass,
2050            'other'                      => true
2051            );
2052    }
2053
2054
2055
2056    // ==> answer
2057    $answer = doRender('/survey/questions/answer/multiplechoice/answer', array(
2058        'aRows'            => $aRows,
2059        'name'             => $ia[1],
2060        'basename'         => $ia[1],
2061        'anscount'         => $anscount,
2062        'iColumnWidth'     => $iColumnWidth,
2063        'iMaxRowsByColumn' => $iMaxRowsByColumn,
2064        'iNbCols'          => $iNbCols,
2065        'coreClass'        => $coreClass,
2066        ), true);
2067
2068    return array($answer, $inputnames);
2069}
2070
2071function do_multiplechoice_withcomments($ia)
2072{
2073    global $thissurvey;
2074    $kpclass    = testKeypad($thissurvey['nokeyboard']); // Virtual keyboard (probably obsolete today)
2075    $inputnames = array();
2076    $coreClass = "ls-answers answers-list checkbox-text-list";
2077    $aQuestionAttributes = QuestionAttribute::model()->getQuestionAttributes($ia[0]);
2078
2079    if ($aQuestionAttributes['other_numbers_only'] == 1) {
2080        $sSeparator                 = getRadixPointData($thissurvey['surveyls_numberformat']);
2081        $sSeparator                 = $sSeparator['separator'];
2082        $otherNumber = 1;
2083    } else {
2084        $otherNumber = 0;
2085        $sSeparator = '.';
2086    }
2087
2088    if (trim($aQuestionAttributes['other_replace_text'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']]) != '') {
2089        $othertext = $aQuestionAttributes['other_replace_text'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']];
2090    } else {
2091        $othertext = gT('Other:');
2092    }
2093
2094    $qquery = "SELECT other FROM {{questions}} WHERE qid=".$ia[0]." AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' and parent_qid=0";
2095    $other  = Yii::app()->db->createCommand($qquery)->queryScalar(); //Checked
2096    if ($aQuestionAttributes['random_order'] == 1) {
2097        $ansquery = "SELECT * FROM {{questions}} WHERE parent_qid=$ia[0]  AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' ORDER BY ".dbRandom();
2098    } else {
2099        $ansquery = "SELECT * FROM {{questions}} WHERE parent_qid=$ia[0]  AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' ORDER BY question_order";
2100    }
2101
2102    $ansresult = Yii::app()->db->createCommand($ansquery)->query(); //Checked
2103    $anscount  = count($ansresult) * 2;
2104
2105    $fn = 1;
2106    if (!isset($other)) {
2107        $other = 'N';
2108    }
2109    if ($other == 'Y') {
2110        $label_width = 25;
2111    } else {
2112        $label_width = 0;
2113    }
2114
2115    /* Find the col-sm width : if none is set : default, if one is set, set another one to be 12, if two is set : no change*/
2116    $attributeInputContainerWidth = intval(trim($aQuestionAttributes['text_input_columns']));
2117    if ($attributeInputContainerWidth < 1 || $attributeInputContainerWidth > 12) {
2118        $attributeInputContainerWidth = null;
2119    }
2120    $attributeLabelWidth = intval(trim($aQuestionAttributes['choice_input_columns']));
2121    if ($attributeLabelWidth < 1 || $attributeLabelWidth > 12) {
2122        /* old system or imported */
2123        $attributeLabelWidth = null;
2124    }
2125    if ($attributeInputContainerWidth === null && $attributeLabelWidth === null) {
2126        $sInputContainerWidth = 8;
2127        $sLabelWidth = 4;
2128    } else {
2129        if ($attributeInputContainerWidth !== null) {
2130            $sInputContainerWidth = $attributeInputContainerWidth;
2131        } elseif ($attributeLabelWidth == 12) {
2132            $sInputContainerWidth = 12;
2133        } else {
2134            $sInputContainerWidth = 12 - $attributeLabelWidth;
2135        }
2136        if ($attributeLabelWidth !== null) {
2137            $sLabelWidth = $attributeLabelWidth;
2138        } elseif ($attributeInputContainerWidth == 12) {
2139            $sLabelWidth = 12;
2140        } else {
2141            $sLabelWidth = 12 - $attributeInputContainerWidth;
2142        }
2143    }
2144
2145    // Size of elements depends on longest text item
2146    $toIterate = $ansresult->readAll();
2147    $longest_question = 0;
2148    foreach ($toIterate as $ansrow) {
2149        $current_length = round((strlen($ansrow['question']) / 10) + 1);
2150        $longest_question = ($longest_question > $current_length) ? $longest_question : $current_length;
2151    }
2152
2153    $sRows = "";
2154    $inputCOmmentValue = '';
2155    $checked = '';
2156    foreach ($toIterate as $ansrow) {
2157        $myfname = $ia[1].$ansrow['title'];
2158
2159        if ($label_width < strlen(trim(strip_tags($ansrow['question'])))) {
2160            $label_width = strlen(trim(strip_tags($ansrow['question'])));
2161        }
2162
2163        $myfname2 = $myfname."comment";
2164
2165        /* If the question has already been ticked, check the checkbox */
2166        $checked = '';
2167        if (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname])) {
2168            if ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] == 'Y') {
2169                $checked = CHECKED;
2170            }
2171        }
2172
2173        $javavalue = (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname])) ? $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] : '';
2174
2175        $fn++;
2176        $fn++;
2177        $inputnames[] = $myfname;
2178        $inputnames[] = $myfname2;
2179
2180        $inputCOmmentValue = htmlspecialchars($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname2], ENT_QUOTES);
2181        $sRows .= doRender('/survey/questions/answer/multiplechoice_with_comments/rows/answer_row', array(
2182            'kpclass'                       => $kpclass,
2183            'title'                         => '',
2184            'liclasses'                     => 'responsive-content question-item answer-item checkbox-text-item',
2185            'name'                          => $myfname,
2186            'id'                            => 'answer'.$myfname,
2187            'value'                         => 'Y', // TODO : check if it should be the same than javavalue
2188            'classes'                       => '',
2189            'otherNumber'                   => $otherNumber,
2190            'labeltext'                     => $ansrow['question'],
2191            'javainput'                     => true,
2192            'javaname'                      => 'java'.$myfname,
2193            'javavalue'                     => $javavalue,
2194            'checked'                       => $checked,
2195            'inputCommentId'                => 'answer'.$myfname2,
2196            'commentLabelText'              => gT('Make a comment on your choice here:'),
2197            'inputCommentName'              => $myfname2,
2198            'inputCOmmentValue'             => (isset($inputCOmmentValue)) ? $inputCOmmentValue : '',
2199            'sInputContainerWidth'          => $sInputContainerWidth,
2200            'sLabelWidth'                   => $sLabelWidth,
2201            ), true);
2202    }
2203    if ($other == 'Y') {
2204        $myfname = $ia[1].'other';
2205        $myfname2 = $myfname.'comment';
2206        $anscount = $anscount + 2;
2207        // SPAN LABEL OPTION //////////////////////////
2208        if (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname]) && $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname]) {
2209            $dispVal = $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname];
2210            if ($aQuestionAttributes['other_numbers_only'] == 1) {
2211                $dispVal = str_replace('.', $sSeparator, $dispVal);
2212            }
2213            $value = htmlspecialchars($dispVal, ENT_QUOTES);
2214        }
2215
2216        if (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname2])) {
2217            $inputCOmmentValue = htmlspecialchars($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname2], ENT_QUOTES);
2218        }
2219
2220        // TODO: $value is not defined for some execution paths.
2221        if (!isset($value)) {
2222            $value = '';
2223        }
2224
2225        $sRows .= doRender('/survey/questions/answer/multiplechoice_with_comments/rows/answer_row_other', array(
2226            'liclasses'                     => 'other question-item answer-item checkbox-text-item other-item',
2227            'liid'                          => 'javatbd'.$myfname,
2228            'kpclass'                       => $kpclass,
2229            'title'                         => gT('Other'),
2230            'name'                          => $myfname,
2231            'id'                            => 'answer'.$myfname,
2232            'value'                         => $value, // TODO : check if it should be the same than javavalue
2233            'classes'                       => '',
2234            'otherNumber'                   => $otherNumber,
2235            'labeltext'                     => $othertext,
2236            'inputCommentId'                => 'answer'.$myfname2,
2237            'commentLabelText'              => gT('Make a comment on your choice here:'),
2238            'inputCommentName'              => $myfname2,
2239            'inputCOmmentValue'             => $inputCOmmentValue,
2240            'checked'                       => $checked,
2241            'javainput'                     => false,
2242            'javaname'                      => '',
2243            'javavalue'                     => '',
2244            'sInputContainerWidth'          => $sInputContainerWidth,
2245            'sLabelWidth'                   => $sLabelWidth
2246            ), true);
2247        $inputnames[] = $myfname;
2248        $inputnames[] = $myfname2;
2249    }
2250
2251    $answer = doRender('/survey/questions/answer/multiplechoice_with_comments/answer', array(
2252        'sRows' => $sRows,
2253        'coreClass'=>$coreClass,
2254        'name'=>'MULTI'.$ia[1], /* ? name is not $ia[1] */
2255        'basename'=> $ia[1],
2256        'value'=> $anscount
2257        ), true);
2258
2259
2260    if ($aQuestionAttributes['commented_checkbox'] != "allways" && $aQuestionAttributes['commented_checkbox_auto']) {
2261        Yii::app()->getClientScript()->registerScriptFile(Yii::app()->getConfig('generalscripts')."multiplechoice_withcomments.js", LSYii_ClientScript::POS_BEGIN);
2262        Yii::app()->getClientScript()->registerScript(
2263            'doMultipleChoiceWithComments'.$ia[0],
2264        "doMultipleChoiceWithComments({$ia[0]},'{$aQuestionAttributes["commented_checkbox"]}');",
2265        LSYii_ClientScript::POS_POSTSCRIPT
2266        );
2267    }
2268
2269    return array($answer, $inputnames);
2270}
2271
2272// ---------------------------------------------------------------
2273function do_file_upload($ia)
2274{
2275    global $thissurvey;
2276    $aQuestionAttributes = QuestionAttribute::model()->getQuestionAttributes($ia[0]);
2277    $coreClass = "ls-answers upload-item";
2278    // Fetch question attributes
2279    $_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['fieldname'] = $ia[1];
2280    $scriptloc = Yii::app()->getController()->createUrl('uploader/index');
2281    $bPreview = Yii::app()->request->getParam('action') == "previewgroup" || Yii::app()->request->getParam('action') == "previewquestion" || $thissurvey['active'] != "Y";
2282    if ($bPreview) {
2283        $_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['preview'] = 1;
2284        $questgrppreview = 1; // Preview is launched from Question or group level
2285    } elseif ($thissurvey['active'] != "Y") {
2286        $_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['preview'] = 1;
2287        $questgrppreview = 0;
2288    } else {
2289        $_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['preview'] = 0;
2290        $questgrppreview = 0;
2291    }
2292    $answer = "<script type='text/javascript'>
2293        function upload_$ia[1]() {
2294            var uploadurl = '{$scriptloc}?sid=".Yii::app()->getConfig('surveyID')."&fieldname={$ia[1]}&qid={$ia[0]}';
2295            uploadurl += '&preview={$questgrppreview}&show_title={$aQuestionAttributes['show_title']}';
2296            uploadurl += '&show_comment={$aQuestionAttributes['show_comment']}';
2297            uploadurl += '&minfiles=' + LEMval('{$aQuestionAttributes['min_num_of_files']}');
2298            uploadurl += '&maxfiles=' + LEMval('{$aQuestionAttributes['max_num_of_files']}');
2299            $('#upload_$ia[1]').attr('href',uploadurl);
2300        }
2301        var uploadLang = {
2302             title: '".gT('Upload your files', 'js')."',
2303             returnTxt: '" . gT('Return to survey', 'js')."',
2304             headTitle: '" . gT('Title', 'js')."',
2305             headComment: '" . gT('Comment', 'js')."',
2306             headFileName: '" . gT('File name', 'js')."',
2307             deleteFile : '".gT('Delete')."',
2308             editFile : '".gT('Edit')."'
2309            };
2310        var imageurl =  '".Yii::app()->getConfig('imageurl')."';
2311        var uploadurl =  '".$scriptloc."';
2312    </script>\n";
2313    Yii::app()->getClientScript()->registerScriptFile(Yii::app()->getConfig('generalscripts')."modaldialog.js", LSYii_ClientScript::POS_BEGIN);
2314    Yii::app()->getClientScript()->registerCssFile(Yii::app()->getConfig('publicstyleurl')."uploader-files.css");
2315    // Modal dialog
2316    //$answer .= $uploadbutton;
2317    $filecountvalue = '0';
2318    if (array_key_exists($ia[1]."_filecount", $_SESSION['survey_'.Yii::app()->getConfig('surveyID')])) {
2319        $tempval = $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]."_filecount"];
2320        if (is_numeric($tempval)) {
2321            $filecountvalue = $tempval;
2322        }
2323    }
2324    $fileuploadData = array(
2325        'fileid' => $ia[1],
2326        'value' => $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]],
2327        'filecountvalue'=>$filecountvalue,
2328        'coreClass'=>$coreClass,
2329        'basename' => $ia[1],
2330    );
2331    $answer .= doRender('/survey/questions/answer/file_upload/answer', $fileuploadData, true);
2332    $answer .= '<script type="text/javascript">
2333    var surveyid = '.Yii::app()->getConfig('surveyID').';
2334    $(document).on("ready pjax:scriptcomplete", function(){
2335    var fieldname = "'.$ia[1].'";
2336    var filecount = $("#"+fieldname+"_filecount").val();
2337    var json = $("#"+fieldname).val();
2338    var show_title = "'.$aQuestionAttributes["show_title"].'";
2339    var show_comment = "'.$aQuestionAttributes["show_comment"].'";
2340    displayUploadedFiles(json, filecount, fieldname, show_title, show_comment);
2341    });
2342    </script>';
2343    $answer .= '<script type="text/javascript">
2344    $(".basic_'.$ia[1].'").change(function() {
2345    var i;
2346    var jsonstring = "[";
2347    for (i = 1, filecount = 0; i <= LEMval("'.$aQuestionAttributes['max_num_of_files'].'"); i++)
2348    {
2349    if ($("#'.$ia[1].'_"+i).val() == "")
2350    continue;
2351    filecount++;
2352    if (i != 1)
2353    jsonstring += ", ";
2354    if ($("#answer'.$ia[1].'_"+i).val() != "")
2355    jsonstring += "{ ';
2356    if (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['show_title'])) {
2357        $answer .= '\"title\":\""+$("#'.$ia[1].'_title_"+i).val()+"\",';
2358    } else {
2359        $answer .= '\"title\":\"\",';
2360    }
2361    if (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['show_comment'])) {
2362        $answer .= '\"comment\":\""+$("#'.$ia[1].'_comment_"+i).val()+"\",';
2363    } else {
2364        $answer .= '\"comment\":\"\",';
2365    }
2366    $answer .= '\"size\":\"\",\"name\":\"\",\"ext\":\"\"}";
2367    }
2368    jsonstring += "]";
2369    $("#'.$ia[1].'").val(jsonstring);
2370    $("#'.$ia[1].'_filecount").val(filecount);
2371    });
2372    </script>';
2373    $uploadurl  = $scriptloc."?sid=".Yii::app()->getConfig('surveyID')."&fieldname=".$ia[1]."&qid=".$ia[0];
2374    $uploadurl .= "&preview=".$questgrppreview."&show_title=".$aQuestionAttributes['show_title'];
2375    $uploadurl .= "&show_comment=".$aQuestionAttributes['show_comment'];
2376    $uploadurl .= "&minfiles=".$aQuestionAttributes['min_num_of_files']; // TODO: Regression here? Should use LEMval(minfiles) like above
2377    $uploadurl .= "&maxfiles=".$aQuestionAttributes['max_num_of_files']; // Same here.
2378    $answer .= '
2379    <!-- Trigger the modal with a button -->
2380        <!-- Modal -->
2381        <div id="file-upload-modal-' . $ia[1].'" class="modal fade file-upload-modal" role="dialog">
2382            <div class="modal-dialog">
2383                <!-- Modal content-->
2384                <div class="modal-content">
2385                    <div class="modal-header file-upload-modal-header">
2386                        <button type="button" class="close" data-dismiss="modal">&times;</button>
2387                        <div class="h4 modal-title">' . ngT("Upload file|Upload files", $aQuestionAttributes['max_num_of_files']).'</div>
2388                    </div>
2389                    <div class="modal-body file-upload-modal-body">
2390                        <iframe id="uploader' . $ia[1].'" name="uploader'.$ia[1].'" class="uploader-frame" src="'.$uploadurl.'" title="'.gT("Upload").'"></iframe>
2391                    </div>
2392                    <div class="modal-footer file-upload-modal-footer">
2393                        <button type="button" class="btn btn-success" data-dismiss="modal">' . gT("Save changes").'</button>
2394                    </div>
2395                </div>
2396            </div>
2397        </div>
2398    ';
2399    $inputnames = array();
2400    $inputnames[] = $ia[1];
2401    $inputnames[] = $ia[1]."_filecount";
2402    return array($answer, $inputnames);
2403}
2404
2405// ---------------------------------------------------------------
2406// TMSW TODO - Can remove DB query by passing in answer list from EM
2407function do_multipleshorttext($ia)
2408{
2409    global $thissurvey;
2410    $extraclass          = "";
2411    $aQuestionAttributes = QuestionAttribute::model()->getQuestionAttributes($ia[0]);
2412    $coreClass = "ls-answers subquestion-list questions-list text-list";
2413    if ($aQuestionAttributes['numbers_only'] == 1) {
2414        $sSeparator             = getRadixPointData($thissurvey['surveyls_numberformat']);
2415        $sSeparator             = $sSeparator['separator'];
2416        $extraclass            .= " numberonly";
2417        $coreClass             .= " number-list";
2418    } else {
2419        $sSeparator = '';
2420    }
2421
2422    if (intval(trim($aQuestionAttributes['maximum_chars'])) > 0) {
2423        // Only maxlength attribute, use textarea[maxlength] jquery selector for textarea
2424        $maxlength = intval(trim($aQuestionAttributes['maximum_chars']));
2425        $extraclass .= " ls-input-maxchars";
2426    } else {
2427        $maxlength = "";
2428    }
2429    if (ctype_digit(trim($aQuestionAttributes['input_size']))) {
2430        $inputsize = trim($aQuestionAttributes['input_size']);
2431        $extraclass .= " ls-input-sized";
2432    } else {
2433        $inputsize = null;
2434    }
2435
2436    /* Find the col-sm width : if non is set : default, if one is set, set another one to be 12, if two is set : no change*/
2437    /* Find the col-sm width : if none is set : default, if one is set, set another one to be 12, if two is set : no change*/
2438    list($sLabelWidth, $sInputContainerWidth, $defaultWidth) = getLabelInputWidth($aQuestionAttributes['label_input_columns'], $aQuestionAttributes['text_input_columns']);
2439
2440
2441    if (trim($aQuestionAttributes['prefix'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']]) != '') {
2442        $prefix      = $aQuestionAttributes['prefix'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']];
2443        $extraclass .= " withprefix";
2444    } else {
2445        $prefix = '';
2446    }
2447
2448    if (trim($aQuestionAttributes['suffix'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']]) != '') {
2449        $suffix      = $aQuestionAttributes['suffix'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']];
2450        $extraclass .= " withsuffix";
2451    } else {
2452        $suffix = '';
2453    }
2454    $kpclass = testKeypad($thissurvey['nokeyboard']); // Virtual keyboard (probably obsolete today)
2455
2456    if ($aQuestionAttributes['random_order'] == 1) {
2457        $ansquery = "SELECT * FROM {{questions}} WHERE parent_qid=$ia[0]  AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' ORDER BY ".dbRandom();
2458    } else {
2459        $ansquery = "SELECT * FROM {{questions}} WHERE parent_qid=$ia[0]  AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' ORDER BY question_order";
2460    }
2461
2462    $ansresult     = dbExecuteAssoc($ansquery); //Checked
2463    $aSubquestions = $ansresult->readAll();
2464    $anscount      = count($aSubquestions) * 2;
2465    $fn            = 1;
2466    $sRows         = '';
2467    $inputnames = array();
2468
2469    if ($anscount != 0) {
2470        $alert = false;
2471        foreach ($aSubquestions as $ansrow) {
2472            $myfname = $ia[1].$ansrow['title'];
2473            $ansrow['question'] = ($ansrow['question'] == "") ? "&nbsp;" : $ansrow['question'];
2474
2475            // color code missing mandatory questions red
2476            if (($_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['step'] != $_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['maxstep']) || ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['step'] == $_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['prevstep'])) {
2477                if ($ia[6] == 'Y' && $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] === '') {
2478                    $alert = true;
2479                }
2480            }
2481
2482            $sDisplayStyle = return_display_style($ia, $aQuestionAttributes, $thissurvey, $myfname);
2483            $dispVal       = '';
2484
2485            if (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname])) {
2486                $dispVal = $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname];
2487                if ($aQuestionAttributes['numbers_only'] == 1) {
2488                    $dispVal = str_replace('.', $sSeparator, $dispVal);
2489                }
2490                $dispVal = htmlspecialchars($dispVal, ENT_QUOTES, 'UTF-8');
2491            }
2492            $numbersonly = ($aQuestionAttributes['numbers_only'] == 1);
2493            if (trim($aQuestionAttributes['display_rows']) != '') {
2494                $sRows .= doRender('/survey/questions/answer/multipleshorttext/rows/answer_row_textarea', array(
2495                    'alert'                  => $alert,
2496                    'labelname'              => 'answer'.$myfname,
2497                    'maxlength'              => $maxlength,
2498                    'rows'                   => $aQuestionAttributes['display_rows'],
2499                    'numbersonly'            => $numbersonly,
2500                    'sInputContainerWidth'   => $sInputContainerWidth,
2501                    'sLabelWidth'            => $sLabelWidth,
2502                    'inputsize'              => $inputsize,
2503                    'extraclass'             => $extraclass,
2504                    'sDisplayStyle'          => $sDisplayStyle,
2505                    'prefix'                 => $prefix,
2506                    'myfname'                => $myfname,
2507                    'question'               => $ansrow['question'],
2508                    'kpclass'                => $kpclass,
2509                    'dispVal'                => $dispVal,
2510                    'suffix'                 => $suffix,
2511                    ), true);
2512            } else {
2513                $sRows .= doRender('/survey/questions/answer/multipleshorttext/rows/answer_row_inputtext', array(
2514                    'alert'                  => $alert,
2515                    'labelname'              => 'answer'.$myfname,
2516                    'maxlength'              => $maxlength,
2517                    'numbersonly'            => $numbersonly,
2518                    'sInputContainerWidth'   => $sInputContainerWidth,
2519                    'sLabelWidth'            => $sLabelWidth,
2520                    'inputsize'              => $inputsize,
2521                    'extraclass'             => $extraclass,
2522                    'sDisplayStyle'          => $sDisplayStyle,
2523                    'prefix'                 => $prefix,
2524                    'myfname'                => $myfname,
2525                    'question'               => $ansrow['question'],
2526                    'kpclass'                => $kpclass,
2527                    'dispVal'                => $dispVal,
2528                    'suffix'                 => $suffix,
2529                    ), true);
2530            }
2531            $fn++;
2532            $inputnames[] = $myfname;
2533        }
2534
2535        $answer = doRender('/survey/questions/answer/multipleshorttext/answer', array(
2536            'sRows' => $sRows,
2537            'coreClass'=>$coreClass,
2538            'basename'=>$ia[1],
2539            ), true);
2540    } else {
2541        $inputnames   = array();
2542        $answer       = doRender('/survey/questions/answer/multipleshorttext/empty', array(), true);
2543    }
2544
2545    return array($answer, $inputnames);
2546}
2547
2548// -----------------------------------------------------------------
2549// @todo: Can remove DB query by passing in answer list from EM
2550function do_multiplenumeric($ia)
2551{
2552    global $thissurvey;
2553    $extraclass             = "";
2554    $aQuestionAttributes    = QuestionAttribute::model()->getQuestionAttributes($ia[0]);
2555    $sSeparator             = getRadixPointData($thissurvey['surveyls_numberformat']);
2556    $sSeparator             = $sSeparator['separator'];
2557    $extraclass            .= " numberonly"; //Must turn on the "numbers only javascript"
2558    $coreClass              = "ls-answers subquestion-list questions-list ";
2559    if (intval(trim($aQuestionAttributes['maximum_chars'])) > 0) {
2560        $maxlength = intval(trim($aQuestionAttributes['maximum_chars'])); /* must be limited to 32 : -(10 number)dot(20 numbers) ! DECIMAL sql */
2561        $extraclass .= " ls-input-maxchars";
2562    } else {
2563        $maxlength = 20;
2564    }
2565    if (ctype_digit(trim($aQuestionAttributes['input_size']))) {
2566        $inputsize = trim($aQuestionAttributes['input_size']);
2567        $extraclass .= " ls-input-sized";
2568    } else {
2569        $inputsize = null;
2570    }
2571
2572    if ($aQuestionAttributes['prefix'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']] != '') {
2573        $prefix      = $aQuestionAttributes['prefix'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']];
2574        $extraclass .= " withprefix";
2575    } else {
2576        $prefix = ''; /* slider js need it */
2577    }
2578
2579    if ($aQuestionAttributes['suffix'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']] != '') {
2580        $suffix      = $aQuestionAttributes['suffix'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']];
2581        $extraclass .= " withsuffix";
2582    } else {
2583        $suffix = ''; /* slider js need it */
2584    }
2585
2586    $kpclass = testKeypad($thissurvey['nokeyboard']); // Virtual keyboard (probably obsolete today)
2587
2588    /* Find the col-sm width : if none is set : default, if one is set, set another one to be 12, if two is set : no change*/
2589    list($sLabelWidth, $sInputContainerWidth, $defaultWidth) = getLabelInputWidth($aQuestionAttributes['label_input_columns'], $aQuestionAttributes['text_input_width']);
2590
2591    $prefixclass = "numeric";
2592    $sliders = 0;
2593    $slider_position = '';
2594    $slider_default_set = false;
2595
2596    if ($aQuestionAttributes['slider_layout'] == 1) {
2597        $coreClass           .= " slider-list";
2598        $slider_layout        = true;
2599        $extraclass          .= " withslider";
2600        $slider_step          = trim(LimeExpressionManager::ProcessString("{{$aQuestionAttributes['slider_accuracy']}}", $ia[0], array(), 1, 1, false, false, true));
2601        $slider_step          = (is_numeric($slider_step)) ? $slider_step : 1;
2602        $slider_min           = trim(LimeExpressionManager::ProcessString("{{$aQuestionAttributes['slider_min']}}", $ia[0], array(), 1, 1, false, false, true));
2603        $slider_mintext       = $slider_min = (is_numeric($slider_min)) ? $slider_min : 0;
2604        $slider_max           = trim(LimeExpressionManager::ProcessString("{{$aQuestionAttributes['slider_max']}}", $ia[0], array(), 1, 1, false, false, true));
2605        $slider_maxtext       = $slider_max = (is_numeric($slider_max)) ? $slider_max : 100;
2606        $slider_default       = trim(LimeExpressionManager::ProcessString("{{$aQuestionAttributes['slider_default']}}", $ia[0], array(), 1, 1, false, false, true));
2607        $slider_default       = (is_numeric($slider_default)) ? $slider_default : "";
2608        $slider_default_set   = (bool) ($aQuestionAttributes['slider_default_set'] && $slider_default !== '');
2609        $slider_orientation   = (trim($aQuestionAttributes['slider_orientation']) == 0) ? 'horizontal' : 'vertical';
2610        $slider_custom_handle = (trim($aQuestionAttributes['slider_custom_handle']));
2611
2612        switch (trim($aQuestionAttributes['slider_handle'])) {
2613            case 0:
2614                $slider_handle = 'round';
2615                break;
2616
2617            case 1:
2618                $slider_handle = 'square';
2619                break;
2620
2621            case 2:
2622                $slider_handle = 'triangle';
2623                break;
2624
2625            case 3:
2626                $slider_handle = 'custom';
2627                break;
2628        }
2629
2630        /* Put the slider init to initial state (when no click is set or when 'reset') */
2631        if ($slider_default !== '') {
2632            /* can be 0 */
2633            $slider_position = $slider_default;
2634        } elseif ($aQuestionAttributes['slider_middlestart'] == 1) {
2635            $slider_position = intval(($slider_max + $slider_min) / 2);
2636        }
2637        $slider_separator = (trim($aQuestionAttributes['slider_separator']) != '') ? $aQuestionAttributes['slider_separator'] : "";
2638        $slider_reset = ($aQuestionAttributes['slider_reset']) ? 1 : 0;
2639
2640        /* Slider reversed value */
2641        if ($aQuestionAttributes['slider_reversed'] == 1) {
2642            $slider_reversed = 'true';
2643        } else {
2644            $slider_reversed = 'false';
2645        }
2646    } else {
2647        $coreClass .= " text-list number-list";
2648        $slider_layout  = false;
2649        $slider_step    = '';
2650        $slider_min     = '';
2651        $slider_mintext = '';
2652        $slider_max     = '';
2653        $slider_maxtext = '';
2654        $slider_default = null;
2655        $slider_orientation = '';
2656        $slider_handle = '';
2657        $slider_custom_handle = '';
2658        $slider_separator = '';
2659        $slider_reset = 0;
2660        $slider_reversed = 'false';
2661    }
2662
2663    if ($aQuestionAttributes['random_order'] == 1) {
2664        $ansquery = "SELECT * FROM {{questions}} WHERE parent_qid=$ia[0]  AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' ORDER BY ".dbRandom();
2665    } else {
2666        $ansquery = "SELECT * FROM {{questions}} WHERE parent_qid=$ia[0]  AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' ORDER BY question_order";
2667    }
2668
2669    $ansresult     = dbExecuteAssoc($ansquery); //Checked
2670    $aSubquestions = $ansresult->readAll();
2671    $anscount      = count($aSubquestions) * 2;
2672    $fn            = 1;
2673    $sRows         = "";
2674
2675    $inputnames = array();
2676
2677    if ($anscount == 0) {
2678        $answer = doRender('/survey/questions/answer/multiplenumeric/empty', array(), true);
2679    } else {
2680        foreach ($aSubquestions as $ansrow) {
2681            $sliderWidth = 12; /* reset sliderWidth for each row : left and right can be different for each #14127 */
2682            $labelText = $ansrow['question'];
2683            $myfname   = $ia[1].$ansrow['title'];
2684
2685            if ($ansrow['question'] == "") {
2686                $ansrow['question'] = "&nbsp;";
2687            }
2688
2689            if ($slider_layout) {
2690                if ($slider_separator != '') {
2691                    $aAnswer     = explode($slider_separator, $ansrow['question']);
2692                    $theanswer   = (isset($aAnswer[0])) ? $aAnswer[0] : "";
2693                    $labelText   = $theanswer;
2694                    $sliderleft  = (isset($aAnswer[1])) ? $aAnswer[1] : null;
2695                    $sliderright = (isset($aAnswer[2])) ? $aAnswer[2] : null;
2696
2697                    /* sliderleft and sliderright is in input, but is part of answers then take label width */
2698                    if (!empty($sliderleft)) {
2699                        $sliderWidth = 10;
2700                    }
2701                    if (!empty($sliderright)) {
2702                        $sliderWidth = $sliderWidth==10 ? 8 : 10 ;
2703                    }
2704                    $sliders   = true; // What is the usage ?
2705                } else {
2706                    $theanswer = $ansrow['question'];
2707                    $sliders   = false;
2708                }
2709            } else {
2710                $theanswer = $ansrow['question'];
2711                $sliders   = false;
2712            }
2713
2714            $aAnswer     = (isset($aAnswer)) ? $aAnswer : '';
2715            $sliderleft  = (isset($sliderleft)) ? $sliderleft : null;
2716            $sliderright = (isset($sliderright)) ? $sliderright : null;
2717
2718            // color code missing mandatory questions red
2719            $alert = '';
2720
2721            if (($_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['step'] != $_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['maxstep']) || ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['step'] == $_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['prevstep'])) {
2722                if ($ia[6] == 'Y' && $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] === '') {
2723                    $alert = true;
2724                }
2725            }
2726
2727            //list($htmltbody2, $hiddenfield)=return_array_filter_strings($ia, $aQuestionAttributes, $thissurvey, $ansrow, $myfname, '', $myfname, "div","form-group question-item answer-item text-item numeric-item".$extraclass);
2728            $sDisplayStyle = return_display_style($ia, $aQuestionAttributes, $thissurvey, $myfname);
2729
2730            // The value of the slider depends on many possible different parameters, by order of priority :
2731            // 1. The value stored in the session
2732            // 2. Else the default Answer   (set by EM and stored in session, so same case than 1)
2733            // 3. Else the slider_default value : if slider_default_set set the value here
2734            // 4. Else the middle start or slider_default or nothing : leave the value to "" for the input, show slider pos at this position
2735            if (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname])) {
2736                $sValue                = $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname];
2737            } elseif ($slider_layout && $slider_default !== "" && $slider_default_set) {
2738                $sValue                = $slider_default;
2739            } else {
2740                $sValue                = null;
2741            }
2742
2743            // Fix the display value : Value is stored as decimal in SQL. Issue when reloading survey
2744            if($sValue && $sValue[0] == ".") {
2745                // issue #15684 mssql SAVE 0.01 AS .0100000000, set it at 0.0100000000
2746                $sValue = "0" . $sValue;
2747            }
2748            if (strpos($sValue, ".")) {
2749                $sValue = rtrim(rtrim($sValue, "0"), ".");
2750            }
2751            // End of DECIMAL fix : get the nulber value
2752            $sUnformatedValue = $sValue ? $sValue : '';
2753            if (strpos($sValue, ".")) {
2754                $sValue = str_replace('.', $sSeparator, $sValue);
2755            }
2756
2757            if (trim($aQuestionAttributes['num_value_int_only']) == 1) {
2758                $extraclass .= " integeronly";
2759                $answertypeclass = " integeronly";
2760                $integeronly = 1;
2761            } else {
2762                $answertypeclass = "";
2763                $integeronly = 0;
2764            }
2765
2766            if (!$slider_layout) {
2767                $sRows .= doRender('/survey/questions/answer/multiplenumeric/rows/input/answer_row', array(
2768                    'qid'                    => $ia[0],
2769                    'extraclass'             => $extraclass,
2770                    'answertypeclass'        => $answertypeclass,
2771                    'sDisplayStyle'          => $sDisplayStyle,
2772                    'kpclass'                => $kpclass,
2773                    'alert'                  => $alert,
2774                    'theanswer'              => $theanswer,
2775                    'labelname'              => 'answer'.$myfname,
2776                    'prefixclass'            => $prefixclass,
2777                    'prefix'                 => $prefix,
2778                    'suffix'                 => $suffix,
2779                    'sInputContainerWidth'   => $sInputContainerWidth,
2780                    'sLabelWidth'            => $sLabelWidth,
2781                    'inputsize'              => $inputsize,
2782                    'myfname'                => $myfname,
2783                    'dispVal'                => $sValue,
2784                    'maxlength'              => $maxlength,
2785                    'labelText'              => $labelText,
2786                    'integeronly'=> $integeronly,
2787                    ), true);
2788            } else {
2789                $sRows .= doRender('/survey/questions/answer/multiplenumeric/rows/sliders/answer_row', array(
2790                    'qid'                    => $ia[0],
2791                    'basename'               => $ia[1],
2792                    'extraclass'             => $extraclass,
2793                    'sDisplayStyle'          => $sDisplayStyle,
2794                    'kpclass'                => $kpclass,
2795                    'alert'                  => $alert,
2796                    'theanswer'              => $theanswer,
2797                    'labelname'              => 'answer'.$myfname,
2798                    'prefixclass'            => $prefixclass,
2799                    'sliders'                => $sliders,
2800                    'sliderleft'             => $sliderleft,
2801                    'sliderright'            => $sliderright,
2802                    'prefix'                 => $prefix,
2803                    'suffix'                 => $suffix,
2804                    'sInputContainerWidth'   => $sInputContainerWidth,
2805                    'sLabelWidth'            => $sLabelWidth,
2806                    'sliderWidth'            => $sliderWidth,
2807                    'inputsize'              => $inputsize,
2808                    'myfname'                => $myfname,
2809                    'dispVal'                => $sValue,
2810                    'maxlength'              => $maxlength,
2811                    'labelText'              => $labelText,
2812                    'slider_orientation'     => $slider_orientation,
2813                    'slider_value'           => $slider_position !== '' ?  $slider_position : $sUnformatedValue,
2814                    'slider_step'            => $slider_step,
2815                    'slider_min'             => $slider_min,
2816                    'slider_mintext'         => $slider_mintext,
2817                    'slider_max'             => $slider_max,
2818                    'slider_maxtext'         => $slider_maxtext,
2819                    'slider_position'        => $slider_position,
2820                    'slider_reset_set'       => $slider_default_set,
2821                    'slider_handle'          => (isset($slider_handle)) ? $slider_handle : '',
2822                    'slider_reset'           => $slider_reset,
2823                    'slider_reversed'        => $slider_reversed,
2824                    'slider_custom_handle'   => $slider_custom_handle,
2825                    'slider_showminmax'      => $aQuestionAttributes['slider_showminmax'],
2826                    'sSeparator'             => $sSeparator,
2827                    'sUnformatedValue'       => $sUnformatedValue,
2828                    'integeronly'=> $integeronly,
2829                    ), true);
2830            }
2831            $fn++;
2832            $inputnames[] = $myfname;
2833
2834            //~ $aJsData=array(
2835            //~ 'slider_custom_handle'=>$slider_custom_handle
2836            //~ );
2837        }
2838        $displaytotal     = false;
2839        $equals_num_value = false;
2840
2841        if (trim($aQuestionAttributes['equals_num_value']) != ''
2842        || trim($aQuestionAttributes['min_num_value']) != ''
2843        || trim($aQuestionAttributes['max_num_value']) != ''
2844        ) {
2845            $qinfo = LimeExpressionManager::GetQuestionStatus($ia[0]);
2846
2847            if (trim($aQuestionAttributes['equals_num_value']) != '') {
2848                $equals_num_value = true;
2849            }
2850            $displaytotal = true;
2851        }
2852
2853        // TODO: Slider and multiple-numeric input should really be two different question types
2854        $templateFile = $sliders ? 'answer' : 'answer_input';
2855        $answer = doRender('/survey/questions/answer/multiplenumeric/'.$templateFile, array(
2856            'sRows'            => $sRows,
2857            'coreClass'        => $coreClass,
2858            'prefixclass'      => $prefixclass,
2859            'equals_num_value' => $equals_num_value,
2860            'id'               => $ia[0],
2861            'basename'         => $ia[1],
2862            'suffix'           => $suffix,
2863            'sumRemainingEqn'  => (isset($qinfo)) ? $qinfo['sumRemainingEqn'] : '',
2864            'displaytotal'     => $displaytotal,
2865            'sumEqn'           => (isset($qinfo)) ? $qinfo['sumEqn'] : '',
2866            'prefix'           => $prefix, // Need to know this to place sum/remaining correctly
2867            'sInputContainerWidth'   => $sInputContainerWidth,
2868            'sLabelWidth'            => $sLabelWidth,
2869            ), true);
2870    }
2871
2872    if ($aQuestionAttributes['slider_layout'] == 1) {
2873        /* Add some data for javascript */
2874        $sliderTranslation = array(
2875            'help'=>gT('Please click and drag the slider handles to enter your answer.')
2876        );
2877        App()->getClientScript()->registerScript("sliderTranslation", "var sliderTranslation=".json_encode($sliderTranslation).";\n", CClientScript::POS_BEGIN);
2878        App()->getClientScript()->registerPackage("question-numeric-slider");
2879    }
2880
2881    return array($answer, $inputnames);
2882}
2883
2884// ---------------------------------------------------------------
2885function do_numerical($ia)
2886{
2887    global $thissurvey;
2888    $extraclass             = "";
2889    $answertypeclass        = "numeric";
2890    $checkconditionFunction = "fixnum_checkconditions";
2891    $aQuestionAttributes    = QuestionAttribute::model()->getQuestionAttributes($ia[0]);
2892    $coreClass = "ls-answers answer-item text-item numeric-item";
2893
2894    if (trim($aQuestionAttributes['prefix'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']]) != '') {
2895        $prefix      = $aQuestionAttributes['prefix'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']];
2896        $extraclass .= " withprefix";
2897    } else {
2898        $prefix = '';
2899    }
2900
2901    if (trim($aQuestionAttributes['suffix'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']]) != '') {
2902        $suffix      = $aQuestionAttributes['suffix'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']];
2903        $extraclass .= " withsuffix";
2904    } else {
2905        $suffix = '';
2906    }
2907    if (intval(trim($aQuestionAttributes['maximum_chars'])) > 0 && intval(trim($aQuestionAttributes['maximum_chars'])) < 20) {
2908        // Only maxlength attribute, use textarea[maxlength] jquery selector for textarea
2909        $maxlength = intval(trim($aQuestionAttributes['maximum_chars']));
2910        $extraclass .= " ls-input-maxchars";
2911    } else {
2912        $maxlength = 20;
2913    }
2914    if (trim($aQuestionAttributes['text_input_width']) != '') {
2915        $col         = ($aQuestionAttributes['text_input_width'] <= 12) ? $aQuestionAttributes['text_input_width'] : 12;
2916        $extraclass .= " col-sm-".trim($col);
2917        $withColumn = true;
2918    } else {
2919        $withColumn = false;
2920    }
2921    if (ctype_digit(trim($aQuestionAttributes['input_size']))) {
2922        $inputsize = trim($aQuestionAttributes['input_size']);
2923        $extraclass .= " ls-input-sized";
2924    } else {
2925        $inputsize = null;
2926    }
2927    if (trim($aQuestionAttributes['num_value_int_only']) == 1) {
2928        $extraclass      .= " integeronly";
2929        $answertypeclass .= " integeronly";
2930        $integeronly      = 1;
2931    } else {
2932        $integeronly = 0;
2933    }
2934
2935    $fValue     = $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]];
2936    $sSeparator = getRadixPointData($thissurvey['surveyls_numberformat']);
2937    $sSeparator = $sSeparator['separator'];
2938
2939    // Fix the display value : Value is stored as decimal in SQL
2940    if($fValue && $fValue[0] == ".") {
2941        // issue #15684 mssql SAVE 0.01 AS .0100000000, set it at 0.0100000000
2942        $fValue = "0" . $fValue;
2943    }
2944    if (strpos($fValue, ".")) {
2945        $fValue = rtrim(rtrim($fValue, "0"), ".");
2946    }
2947    $fValue = str_replace('.', $sSeparator, $fValue);
2948
2949    if ($thissurvey['nokeyboard'] == 'Y') {
2950        includeKeypad();
2951        $extraclass      .= " inputkeypad";
2952        $answertypeclass .= " num-keypad";
2953    }
2954
2955    $answer = doRender('/survey/questions/answer/numerical/answer', array(
2956        'extraclass'             => $extraclass,
2957        'coreClass'              => $coreClass,
2958        'withColumn'             => $withColumn,
2959        'id'                     => $ia[1],
2960        'basename'               => $ia[1],
2961        'prefix'                 => $prefix,
2962        'answertypeclass'        => $answertypeclass,
2963        'inputsize'              => $inputsize,
2964        'fValue'                 => $fValue,
2965        'checkconditionFunction' => $checkconditionFunction,
2966        'integeronly'            => $integeronly,
2967        'maxlength'              => $maxlength,
2968        'suffix'                 => $suffix,
2969        ), true);
2970
2971    $inputnames = array();
2972    $inputnames[] = $ia[1];
2973    $mandatory = null;
2974    return array($answer, $inputnames, $mandatory);
2975}
2976
2977// ---------------------------------------------------------------
2978function do_shortfreetext($ia)
2979{
2980    global $thissurvey;
2981
2982    $sGoogleMapsAPIKey = trim(Yii::app()->getConfig("googleMapsAPIKey"));
2983    $coreClass = "ls-answers answer-item text-item";
2984    if ($sGoogleMapsAPIKey != '') {
2985        $sGoogleMapsAPIKey = '&key='.$sGoogleMapsAPIKey;
2986    }
2987
2988    $extraclass = "";
2989    $aQuestionAttributes = QuestionAttribute::model()->getQuestionAttributes($ia[0]);
2990
2991    if ($aQuestionAttributes['numbers_only'] == 1) {
2992        $sSeparator             = getRadixPointData($thissurvey['surveyls_numberformat']);
2993        $sSeparator             = $sSeparator['separator'];
2994        $extraclass            .= " numberonly";
2995        $coreClass             .= " numeric-item";
2996        $checkconditionFunction = "fixnum_checkconditions";
2997    } else {
2998        $sSeparator = '';
2999        $checkconditionFunction = "checkconditions";
3000    }
3001    if (intval(trim($aQuestionAttributes['maximum_chars'])) > 0) {
3002        // Only maxlength attribute, use textarea[maxlength] jquery selector for textarea
3003        $maxlength      = intval(trim($aQuestionAttributes['maximum_chars']));
3004        $extraclass    .= " ls-input-maxchars";
3005    } else {
3006        $maxlength = "";
3007    }
3008
3009    if (trim($aQuestionAttributes['text_input_width']) != '' && intval(trim($aQuestionAttributes['location_mapservice'])) == 0) {
3010        $col         = ($aQuestionAttributes['text_input_width'] <= 12) ? $aQuestionAttributes['text_input_width'] : 12;
3011        $extraclass .= " col-sm-".trim($col);
3012        $withColumn = true;
3013    } else {
3014        $withColumn = false;
3015    }
3016    if (ctype_digit(trim($aQuestionAttributes['input_size']))) {
3017        $inputsize = trim($aQuestionAttributes['input_size']);
3018        $extraclass .= " ls-input-sized";
3019    } else {
3020        $inputsize = null;
3021    }
3022    if (trim($aQuestionAttributes['prefix'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']]) != '') {
3023        $prefix      = $aQuestionAttributes['prefix'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']];
3024        $extraclass .= " withprefix";
3025    } else {
3026        $prefix = '';
3027    }
3028    if (trim($aQuestionAttributes['suffix'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']]) != '') {
3029        $suffix      = $aQuestionAttributes['suffix'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']];
3030        $extraclass .= " withsuffix";
3031    } else {
3032        $suffix = '';
3033    }
3034    if ($thissurvey['nokeyboard'] == 'Y') {
3035        includeKeypad();
3036        $kpclass     = "text-keypad";
3037        $extraclass .= " inputkeypad";
3038    } else {
3039        $kpclass = "";
3040    }
3041    $answer = "";
3042    $sQuestionHelpText = '';
3043
3044    if (trim($aQuestionAttributes['display_rows']) != '') {
3045        //question attribute "display_rows" is set -> we need a textarea to be able to show several rows
3046        $drows = $aQuestionAttributes['display_rows'];
3047
3048        $dispVal = "";
3049
3050        if ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]]) {
3051            $dispVal = str_replace("\\", "", $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]]);
3052
3053            if ($aQuestionAttributes['numbers_only'] == 1) {
3054                $dispVal = str_replace('.', $sSeparator, $dispVal);
3055            }
3056            $dispVal = htmlspecialchars($dispVal);
3057        }
3058
3059        $answer .= doRender('/survey/questions/answer/shortfreetext/textarea/item', array(
3060            'extraclass'             => $extraclass,
3061            'coreClass'              => $coreClass,
3062            'freeTextId'             => 'answer'.$ia[1],
3063            'name'                   => $ia[1],
3064            'basename'               => $ia[1],
3065            'drows'                  => $drows,
3066            'checkconditionFunction' => $checkconditionFunction.'(this.value, this.name, this.type)',
3067            'dispVal'                => $dispVal,
3068            'maxlength'              => $maxlength,
3069            'kpclass'                => $kpclass,
3070            'prefix'                 => $prefix,
3071            'suffix'                 => $suffix,
3072            'inputsize'              => $inputsize,
3073            'withColumn'             => $withColumn
3074            ), true);
3075    } elseif ((int) ($aQuestionAttributes['location_mapservice']) == 1) {
3076        $coreClass       = "ls-answers map-item geoloc-item";
3077        $currentLocation = $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]];
3078        $currentLatLong  = null;
3079        // Get the latitude/longtitude for the point that needs to be displayed by default
3080        if (strlen($currentLocation) > 2 && strpos($currentLocation, ";")) { // Quick check if current location is OK
3081            $currentLatLong = explode(';', $currentLocation);
3082            $currentLatLong = array($currentLatLong[0], $currentLatLong[1]);
3083        } else {
3084            if ((int) ($aQuestionAttributes['location_nodefaultfromip']) == 0) {
3085                $currentLatLong = getLatLongFromIp(getIPAddress());
3086            }
3087
3088            if (empty($currentLatLong)) {
3089                $floatLat = "";
3090                $floatLng = "";
3091                $sDefaultcoordinates=trim(LimeExpressionManager::ProcessString($aQuestionAttributes['location_defaultcoordinates'], $ia[0], array(), 3, 1, false, false, true));/* static var is the last one */
3092                if (strlen($sDefaultcoordinates) > 2 && strpos($sDefaultcoordinates, " ")) {
3093                    $LatLong = explode(" ", $sDefaultcoordinates);
3094                    if (isset($LatLong[0]) && isset($LatLong[1])) {
3095                        $floatLat = $LatLong[0];
3096                        $floatLng = $LatLong[1];
3097                    }
3098                }
3099                $currentLatLong = array($floatLat, $floatLng);
3100            }
3101        }
3102        // 2 - city; 3 - state; 4 - country; 5 - postal
3103        $strBuild = "";
3104        if ($aQuestionAttributes['location_city']) {
3105            $strBuild .= "2";
3106        }
3107        if ($aQuestionAttributes['location_state']) {
3108            $strBuild .= "3";
3109        }
3110        if ($aQuestionAttributes['location_country']) {
3111            $strBuild .= "4";
3112        }
3113        if ($aQuestionAttributes['location_postal']) {
3114            $strBuild .= "5";
3115        }
3116
3117        $currentLocation = $currentLatLong[0]." ".$currentLatLong[1];
3118
3119        Yii::app()->getClientScript()->registerScriptFile(Yii::app()->getConfig('generalscripts')."map.js", LSYii_ClientScript::POS_END);
3120        if ($aQuestionAttributes['location_mapservice'] == 1 && !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != "off") {
3121            Yii::app()->getClientScript()->registerScriptFile("https://maps.googleapis.com/maps/api/js?sensor=false$sGoogleMapsAPIKey", LSYii_ClientScript::POS_BEGIN);
3122        } elseif ($aQuestionAttributes['location_mapservice'] == 1) {
3123            Yii::app()->getClientScript()->registerScriptFile("http://maps.googleapis.com/maps/api/js?sensor=false$sGoogleMapsAPIKey", LSYii_ClientScript::POS_BEGIN);
3124        } elseif ($aQuestionAttributes['location_mapservice'] == 2) {
3125            /* 2019-04-01 : openlayers auto redirect to https (on firefox) , but always good to use automatic protocol */
3126            Yii::app()->getClientScript()->registerScriptFile("//www.openlayers.org/api/OpenLayers.js", LSYii_ClientScript::POS_BEGIN);
3127        }
3128
3129        $questionHelp = false;
3130        if (isset($aQuestionAttributes['hide_tip']) && $aQuestionAttributes['hide_tip'] == 0) {
3131            $questionHelp = true;
3132            $sQuestionHelpText = gT('Drag and drop the pin to the desired location. You may also right click on the map to move the pin.');
3133        }
3134        $answer = doRender('/survey/questions/answer/shortfreetext/location_mapservice/item', array(
3135            'extraclass'             => $extraclass,
3136            'coreClass'              => $coreClass,
3137            'freeTextId'             => 'answer'.$ia[1],
3138            'name'                   => $ia[1],
3139            'qid'                    => $ia[0],
3140            'basename'               => $ia[1],
3141            'checkconditionFunction' => $checkconditionFunction.'(this.value, this.name, this.type)',
3142            'value'                  => $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]],
3143            'kpclass'                => $kpclass,
3144            'currentLocation'        => $currentLocation,
3145            'strBuild'               => $strBuild,
3146            'location_mapservice'    => $aQuestionAttributes['location_mapservice'],
3147            'location_mapzoom'       => $aQuestionAttributes['location_mapzoom'],
3148            'location_mapheight'     => $aQuestionAttributes['location_mapheight'],
3149            'questionHelp'           => $questionHelp,
3150            'question_text_help'     => $sQuestionHelpText,
3151            'inputsize'              => $inputsize,
3152            'withColumn'             => $withColumn
3153            ), true);
3154    } elseif ((int) ($aQuestionAttributes['location_mapservice']) == 100) {
3155        $coreClass       = "ls-answers map-item geoloc-item";
3156        $currentLocation = $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]];
3157        $currentCenter   = $currentLatLong = null;
3158        // Get the latitude/longtitude for the point that needs to be displayed by default
3159        if (strlen($currentLocation) > 2 && strpos($currentLocation, ";")) {
3160            $currentLatLong = explode(';', $currentLocation);
3161            $currentCenter  = $currentLatLong = array($currentLatLong[0], $currentLatLong[1]);
3162        } elseif ((int) ($aQuestionAttributes['location_nodefaultfromip']) == 0) {
3163            $currentCenter = $currentLatLong = getLatLongFromIp(getIPAddress());
3164        }
3165
3166        // If it's not set : set the center to the default position, but don't set the marker
3167        if (!$currentLatLong) {
3168            $currentLatLong = array("", "");
3169            $sDefaultcoordinates=trim(LimeExpressionManager::ProcessString($aQuestionAttributes['location_defaultcoordinates'], $ia[0], array(), 3, 1, false, false, true));/* static var is the last one */
3170            $currentCenter = explode(" ", $sDefaultcoordinates);
3171            if (count($currentCenter) != 2) {
3172                $currentCenter = array("", "");
3173            }
3174        }
3175        $strBuild = "";
3176
3177        $aGlobalMapScriptVar = array(
3178            'geonameUser'=>getGlobalSetting('GeoNamesUsername'), // Did we need to urlencode ?
3179            'geonameLang'=>Yii::app()->language,
3180        );
3181        $aThisMapScriptVar = array(
3182            'zoomLevel'=>$aQuestionAttributes['location_mapzoom'],
3183            'latitude'=>$currentCenter[0],
3184            'longitude'=>$currentCenter[1],
3185
3186        );
3187        App()->getClientScript()->registerPackage('leaflet');
3188        App()->getClientScript()->registerPackage('devbridge-autocomplete'); /* for autocomplete */
3189        Yii::app()->getClientScript()->registerScript('sGlobalMapScriptVar', "LSmap=".ls_json_encode($aGlobalMapScriptVar).";\nLSmaps= new Array();", CClientScript::POS_BEGIN);
3190        Yii::app()->getClientScript()->registerScript('sThisMapScriptVar'.$ia[1], "LSmaps['{$ia[1]}']=".ls_json_encode($aThisMapScriptVar).";", CClientScript::POS_BEGIN);
3191        Yii::app()->getClientScript()->registerScriptFile(Yii::app()->getConfig('generalscripts')."map.js", CClientScript::POS_END);
3192        Yii::app()->getClientScript()->registerCssFile(Yii::app()->getConfig('publicstyleurl').'map.css');
3193
3194        if (isset($aQuestionAttributes['hide_tip']) && $aQuestionAttributes['hide_tip'] == 0) {
3195            $questionHelp = true;
3196            $sQuestionHelpText = gT('Click to set the location or drag and drop the pin. You may may also enter coordinates');
3197        }
3198
3199        $itemDatas = array(
3200            'extraclass'=>$extraclass,
3201            'coreClass'=> $coreClass,
3202            'name'=>$ia[1],
3203            'qid'=>$ia[0],
3204            'basename'               => $ia[1],
3205            'checkconditionFunction'=>$checkconditionFunction.'(this.value, this.name, this.type)',
3206            'value'=>$_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]],
3207            'strBuild'=>$strBuild,
3208            'location_mapservice'=>$aQuestionAttributes['location_mapservice'],
3209            'location_mapzoom'=>$aQuestionAttributes['location_mapzoom'],
3210            'location_mapheight'=>$aQuestionAttributes['location_mapheight'],
3211            'questionHelp'=>(isset($questionHelp)) ? $questionHelp : '',
3212            'question_text_help'=>$sQuestionHelpText,
3213            'location_value'=> $currentLatLong[0].' '.$currentLatLong[1],
3214            'currentLat'=>$currentLatLong[0],
3215            'currentLong'=>$currentLatLong[1],
3216            'inputsize'              => $inputsize,
3217            'withColumn'             => $withColumn
3218        );
3219        $answer = doRender('/survey/questions/answer/shortfreetext/location_mapservice/item_100', $itemDatas, true);
3220    } else {
3221        //no question attribute set, use common input text field
3222        $dispVal = $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]];
3223        if ($aQuestionAttributes['numbers_only'] == 1) {
3224            $dispVal = str_replace('.', $sSeparator, $dispVal);
3225        }
3226        $dispVal = htmlspecialchars($dispVal, ENT_QUOTES, 'UTF-8');
3227
3228        $itemDatas = array(
3229            'extraclass'=>$extraclass,
3230            'coreClass'=> $coreClass,
3231            'name'=>$ia[1],
3232            'basename'               => $ia[1],
3233            'prefix'=>$prefix,
3234            'suffix'=>$suffix,
3235            'kpclass'=>$kpclass,
3236            'dispVal'=>$dispVal,
3237            'maxlength'=>$maxlength,
3238            'inputsize'              => $inputsize,
3239            'withColumn'             => $withColumn
3240        );
3241        $answer = doRender('/survey/questions/answer/shortfreetext/text/item', $itemDatas, true);
3242    }
3243
3244    if (trim($aQuestionAttributes['time_limit']) != '') {
3245        $answer .= return_timer_script($aQuestionAttributes, $ia, "answer".$ia[1]);
3246    }
3247
3248    $inputnames = array();
3249    $inputnames[] = $ia[1];
3250    return array($answer, $inputnames);
3251}
3252
3253function getLatLongFromIp($sIPAddress)
3254{
3255    $ipInfoDbAPIKey = Yii::app()->getConfig("ipInfoDbAPIKey");
3256    if ($ipInfoDbAPIKey) {
3257        // ipinfodb.com needs a key
3258        $oXML = simplexml_load_file("http://api.ipinfodb.com/v3/ip-city/?key=$ipInfoDbAPIKey&ip=$sIPAddress&format=xml");
3259        if ($oXML->{'statusCode'} == "OK") {
3260            $lat = (float) $oXML->{'latitude'};
3261            $lng = (float) $oXML->{'longitude'};
3262
3263            return(array($lat, $lng));
3264        } else {
3265            return false;
3266        }
3267    }
3268}
3269
3270
3271
3272// ---------------------------------------------------------------
3273function do_longfreetext($ia)
3274{
3275    global $thissurvey;
3276    $extraclass = "";
3277    $coreClass = "ls-answers answer-item text-item";
3278    if ($thissurvey['nokeyboard'] == 'Y') {
3279        includeKeypad();
3280        $kpclass     = "text-keypad";
3281        $extraclass .= " inputkeypad";
3282    } else {
3283        $kpclass = "";
3284    }
3285
3286    $checkconditionFunction = "checkconditions";
3287    $aQuestionAttributes    = QuestionAttribute::model()->getQuestionAttributes($ia[0]);
3288
3289    if (intval(trim($aQuestionAttributes['maximum_chars'])) > 0) {
3290        // Only maxlength attribute, use textarea[maxlength] jquery selector for textarea
3291        $maxlength = intval(trim($aQuestionAttributes['maximum_chars']));
3292        $extraclass .= " ls-input-maxchars";
3293    } else {
3294        $maxlength = "";
3295    }
3296
3297    if (trim($aQuestionAttributes['display_rows']) != '') {
3298        $drows = $aQuestionAttributes['display_rows'];
3299    } else {
3300        $drows = 5;
3301    }
3302
3303    if (trim($aQuestionAttributes['text_input_width']) != '') {
3304        // text_input_width can not be empty, except with old survey (wher can be empty or up to 12 see bug #11743
3305        $col         = ($aQuestionAttributes['text_input_width'] <= 12) ? $aQuestionAttributes['text_input_width'] : 12;
3306        $extraclass .= " col-sm-".trim($col);
3307        $withColumn = true;
3308    } else {
3309        $withColumn = false;
3310    }
3311    if (ctype_digit(trim($aQuestionAttributes['input_size']))) {
3312        $inputsize = trim($aQuestionAttributes['input_size']);
3313        $extraclass .= " ls-input-sized";
3314    } else {
3315        $inputsize = null;
3316    }
3317
3318    $dispVal = ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]]) ?htmlspecialchars($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]]) : '';
3319
3320    $answer = doRender('/survey/questions/answer/longfreetext/answer', array(
3321        'extraclass'             => $extraclass,
3322        'coreClass'              =>$coreClass,
3323        'withColumn'             =>$withColumn,
3324        'kpclass'                => $kpclass,
3325        'name'                   => $ia[1],
3326        'basename'               => $ia[1],
3327        'drows'                  => $drows,
3328        'checkconditionFunction' => $checkconditionFunction.'(this.value, this.name, this.type)',
3329        'dispVal'                => $dispVal,
3330        'inputsize'              => $inputsize,
3331        'maxlength'              => $maxlength,
3332        ), true);
3333
3334
3335    if (trim($aQuestionAttributes['time_limit']) != '') {
3336        $answer .= return_timer_script($aQuestionAttributes, $ia, "answer".$ia[1]);
3337    }
3338
3339    $inputnames = array();
3340    $inputnames[] = $ia[1];
3341    return array($answer, $inputnames);
3342}
3343
3344// ---------------------------------------------------------------
3345function do_hugefreetext($ia)
3346{
3347    global $thissurvey;
3348    $extraclass = "";
3349    $coreClass = "ls-answers answer-item text-item";
3350    if ($thissurvey['nokeyboard'] == 'Y') {
3351        includeKeypad();
3352        $kpclass = "text-keypad";
3353        $extraclass .= " inputkeypad";
3354    } else {
3355        $kpclass = "";
3356    }
3357
3358    $checkconditionFunction = "checkconditions";
3359
3360    $aQuestionAttributes = QuestionAttribute::model()->getQuestionAttributes($ia[0]);
3361
3362    if (intval(trim($aQuestionAttributes['maximum_chars'])) > 0) {
3363        // Only maxlength attribute, use textarea[maxlength] jquery selector for textarea
3364        $maxlength = intval(trim($aQuestionAttributes['maximum_chars']));
3365        $extraclass .= " ls-input-maxchars";
3366    } else {
3367        $maxlength = "";
3368    }
3369
3370    if (trim($aQuestionAttributes['display_rows']) != '') {
3371        $drows = $aQuestionAttributes['display_rows'];
3372    } else {
3373        $drows = 30;
3374    }
3375    if (trim($aQuestionAttributes['text_input_width']) != '') {
3376        $col = ($aQuestionAttributes['text_input_width'] <= 12) ? $aQuestionAttributes['text_input_width'] : 12;
3377        $extraclass .= " col-sm-".trim($col);
3378        $withColumn = true;
3379    } else {
3380        $withColumn = false;
3381    }
3382    if (ctype_digit(trim($aQuestionAttributes['input_size']))) {
3383        $inputsize = trim($aQuestionAttributes['input_size']);
3384        $extraclass .= " ls-input-sized";
3385    } else {
3386        $inputsize = null;
3387    }
3388
3389    $dispVal = "";
3390    if ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]]) {
3391        $dispVal = htmlspecialchars($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]]);
3392    }
3393
3394    $itemDatas = array(
3395        'extraclass'=>$extraclass,
3396        'coreClass'=>$coreClass,
3397        'withColumn'=>$withColumn,
3398        'kpclass'=>$kpclass,
3399        'name'=>$ia[1],
3400        'basename'=> $ia[1],
3401        'drows'=>$drows,
3402        'checkconditionFunction'=>$checkconditionFunction.'(this.value, this.name, this.type)',
3403        'dispVal'=>$dispVal,
3404        'inputsize'=>$inputsize,
3405        'maxlength'=>$maxlength,
3406    );
3407    $answer = doRender('/survey/questions/answer/longfreetext/answer', $itemDatas, true);
3408
3409    if (trim($aQuestionAttributes['time_limit']) != '') {
3410        $answer .= return_timer_script($aQuestionAttributes, $ia, "answer".$ia[1]);
3411    }
3412
3413    $inputnames = array();
3414    $inputnames[] = $ia[1];
3415    return array($answer, $inputnames);
3416}
3417
3418// ---------------------------------------------------------------
3419function do_yesno($ia)
3420{
3421    $coreClass = "ls-answers answers-list";
3422    $yChecked = $nChecked = $naChecked = '';
3423    if ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] == 'Y') {
3424        $yChecked = CHECKED;
3425    }
3426
3427    if ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] == 'N') {
3428        $nChecked = CHECKED;
3429    }
3430
3431    $noAnswer = false;
3432    if ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1) {
3433        $noAnswer = true;
3434        if (empty($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]])) {
3435            $naChecked = CHECKED;
3436        }
3437    }
3438
3439    $aQuestionAttributes = QuestionAttribute::model()->getQuestionAttributes($ia[0]);
3440    $displayType = $aQuestionAttributes['display_type'];
3441    $noAnswer = (isset($noAnswer)) ? $noAnswer : false;
3442    $itemDatas = array(
3443        'name'=>$ia[1],
3444        'basename'=>$ia[1],
3445        'yChecked' => $yChecked,
3446        'nChecked' => $nChecked,
3447        'naChecked'=> $naChecked,
3448        'noAnswer' => $noAnswer,
3449        'value' => $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]],
3450        'displayType'=>$displayType,
3451    );
3452    if ($displayType === 0) {
3453        $itemDatas['coreClass'] = "{$coreClass} button-list yesno-button";
3454        $answer = doRender('/survey/questions/answer/yesno/buttons/item', $itemDatas, true);
3455    } else {
3456        $itemDatas['coreClass'] = "{$coreClass} radio-list yesno-radio-list";
3457        $answer = doRender('/survey/questions/answer/yesno/radio/item', $itemDatas, true);
3458    }
3459
3460    $inputnames = array();
3461    $inputnames[] = $ia[1];
3462    return array($answer, $inputnames);
3463}
3464
3465// ---------------------------------------------------------------
3466function do_gender($ia)
3467{
3468    $fChecked               = ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] == 'F') ? 'CHECKED' : '';
3469    $mChecked               = ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] == 'M') ? 'CHECKED' : '';
3470    $naChecked              = '';
3471    $aQuestionAttributes    = QuestionAttribute::model()->getQuestionAttributes($ia[0]);
3472    $displayType            = $aQuestionAttributes['display_type'];
3473    $coreClass              = "ls-answers answers-list radio-list";
3474    if ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1) {
3475        $noAnswer = true;
3476        if ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] == '') {
3477            $naChecked = CHECKED;
3478        }
3479    }
3480
3481    $noAnswer = (isset($noAnswer)) ? $noAnswer : false;
3482
3483    $itemDatas = array(
3484        'name'                   => $ia[1],
3485        'basename'               => $ia[1],
3486        'fChecked'               => $fChecked,
3487        'mChecked'               => $mChecked,
3488        'naChecked'              => $naChecked,
3489        'noAnswer'               => $noAnswer,
3490        'value'                  => $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]],
3491    );
3492
3493    if ($displayType === 0) {
3494        $itemDatas['coreClass'] = "{$coreClass} button-list gender-button";
3495        $answer = doRender('/survey/questions/answer/gender/buttons/answer', $itemDatas, true);
3496    } else {
3497        $itemDatas['coreClass'] = "{$coreClass} radio-list gender-radio-list";
3498        $answer = doRender('/survey/questions/answer/gender/radio/answer', $itemDatas, true);
3499    }
3500
3501    $inputnames   = array();
3502    $inputnames[] = $ia[1];
3503
3504    return array($answer, $inputnames);
3505}
3506
3507// ---------------------------------------------------------------
3508/**
3509* Construct answer part array_5point
3510* @param array $ia
3511* @return array
3512*/
3513function do_array_5point($ia)
3514{
3515    global $thissurvey;
3516    $aLastMoveResult         = LimeExpressionManager::GetLastMoveResult();
3517    $aMandatoryViolationSubQ = ($aLastMoveResult['mandViolation'] && $ia[6] == 'Y') ? explode("|", $aLastMoveResult['unansweredSQs']) : array();
3518    $coreClass               = "ls-answers subquestion-list questions-list radio-array";
3519    $checkconditionFunction  = "checkconditions";
3520    $aQuestionAttributes     = QuestionAttribute::model()->getQuestionAttributes($ia[0]);
3521    $inputnames              = array();
3522
3523    if (trim($aQuestionAttributes['answer_width']) != '') {
3524        $answerwidth = $aQuestionAttributes['answer_width'];
3525        $defaultWidth = false;
3526    } else {
3527        $answerwidth = 33;
3528        $defaultWidth = true;
3529    }
3530    $columnswidth = 100 - $answerwidth;
3531    $colCount = 5; // number of columns
3532
3533    if ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1) {
3534        //Question is not mandatory
3535        ++$colCount; // add another column
3536    }
3537
3538    if ($aQuestionAttributes['random_order'] == 1) {
3539        $ansquery = "SELECT * FROM {{questions}} WHERE parent_qid=$ia[0] AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' ORDER BY ".dbRandom();
3540    } else {
3541        $ansquery = "SELECT * FROM {{questions}} WHERE parent_qid=$ia[0] AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' ORDER BY question_order";
3542    }
3543
3544    $ansresult     = dbExecuteAssoc($ansquery); //Checked
3545    $aSubquestions = $ansresult->readAll();
3546    $fn            = 1;
3547    $sColumns      = $sHeaders = $sRows = $answer_tds = '';
3548
3549    // Check if any subquestion use suffix/prefix
3550    $right_exists  = false;
3551    foreach ($aSubquestions as $j => $ansrow) {
3552        $answertext2 = $ansrow['question'];
3553        if (strpos($answertext2, '|')) {
3554            $right_exists = true;
3555        }
3556    }
3557    if ($right_exists) {
3558        /* put the right answer to same width : take place in answer width only if it's not default */
3559        if ($defaultWidth) {
3560            $columnswidth -= $answerwidth;
3561        } else {
3562            $answerwidth = $answerwidth / 2;
3563        }
3564    }
3565    $cellwidth = $columnswidth / $colCount;
3566    for ($xc = 1; $xc <= 5; $xc++) {
3567        $sColumns .= doRender('/survey/questions/answer/arrays/5point/columns/col', array('cellwidth'=>$cellwidth), true);
3568    }
3569
3570    if ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1) {
3571        //Question is not mandatory
3572        $sColumns .= doRender('/survey/questions/answer/arrays/5point/columns/col', array('cellwidth'=>$cellwidth), true);
3573    }
3574
3575    // Column for suffix
3576    if ($right_exists) {
3577        $sColumns .= doRender('/survey/questions/answer/arrays/5point/columns/col', array('cellwidth'=>$answerwidth), true);
3578    }
3579
3580    $sHeaders .= doRender('/survey/questions/answer/arrays/5point/rows/cells/header_information', array(
3581        'class'=>'',
3582        'content'=>'',
3583        ), true);
3584    for ($xc = 1; $xc <= 5; $xc++) {
3585        $sHeaders .= doRender('/survey/questions/answer/arrays/5point/rows/cells/header_answer', array(
3586            'class'=>'answer-text',
3587            'content'=>$xc,
3588            ), true);
3589    }
3590
3591    // Header for suffix
3592    if ($right_exists) {
3593        $sHeaders .= doRender('/survey/questions/answer/arrays/5point/rows/cells/header_information', array(
3594            'class'=>'answertextright',
3595            'content'=>'',
3596            ), true);
3597    }
3598
3599    if ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1) {
3600        //Question is not mandatory
3601        $sHeaders .= doRender('/survey/questions/answer/arrays/5point/rows/cells/header_answer', array(
3602            'class'=>'answer-text noanswer-text',
3603            'content'=>gT('No answer'),
3604            ), true);
3605    }
3606
3607
3608    foreach ($aSubquestions as $j => $ansrow) {
3609        $myfname = $ia[1].$ansrow['title'];
3610        $answertext = $ansrow['question'];
3611        if (strpos($answertext, '|') !== false) {
3612            $answertext = substr($answertext, 0, strpos($answertext, '|'));
3613        }
3614
3615        /* Check if this item has not been answered */
3616        $error = ($ia[6] == 'Y' && in_array($myfname, $aMandatoryViolationSubQ)) ?true:false;
3617
3618        /* Check for array_filter  */
3619        $sDisplayStyle = return_display_style($ia, $aQuestionAttributes, $thissurvey, $myfname);
3620
3621        // Value
3622        $value = (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname])) ? $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] : '';
3623
3624        for ($i = 1; $i <= 5; $i++) {
3625            $CHECKED = (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname]) && $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] == $i) ? 'CHECKED' : '';
3626            $answer_tds .= doRender('/survey/questions/answer/arrays/5point/rows/cells/answer_td_input', array(
3627                'i'=>$i,
3628                'labelText'=>$i,
3629                'myfname'=>$myfname,
3630                'CHECKED'=>$CHECKED,
3631                'checkconditionFunction'=>$checkconditionFunction,
3632                'value'=>$i,
3633                ), true);
3634        }
3635
3636        // Suffix
3637        $answertext2 = $ansrow['question'];
3638        if (strpos($answertext2, '|')) {
3639            $answertext2 = substr($answertext2, strpos($answertext2, '|') + 1);
3640            $answer_tds .= doRender('/survey/questions/answer/arrays/5point/rows/cells/answer_td_answertext', array(
3641                'class'=>'answertextright',
3642                'style'=>'text-align:left',
3643                'answertext2'=>$answertext2,
3644                ), true);
3645        } elseif ($right_exists) {
3646            $answer_tds .= doRender('/survey/questions/answer/arrays/5point/rows/cells/answer_td_answertext', array(
3647                'answerwidth'=>$answerwidth,
3648                'answertext2'=>'',
3649                ), true);
3650        }
3651
3652        // ==>tds
3653        if ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1) {
3654            $CHECKED = (!isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname]) || $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] == '') ? 'CHECKED' : '';
3655            $answer_tds .= doRender('/survey/questions/answer/arrays/5point/rows/cells/answer_td_input', array(
3656                'i'=>"",
3657                'labelText'=>gT('No answer'),
3658                'myfname'=>$myfname,
3659                'CHECKED'=>$CHECKED,
3660                'checkconditionFunction'=>$checkconditionFunction,
3661                'value'=>'',
3662                ), true);
3663        }
3664
3665        $sRows .= doRender('/survey/questions/answer/arrays/5point/rows/answer_row', array(
3666            'answer_tds'    => $answer_tds,
3667            'myfname'       => $myfname,
3668            'answertext'    => $answertext,
3669            'answerwidth'=>$answerwidth,
3670            'value'         => $value,
3671            'error'         => $error,
3672            'sDisplayStyle' => $sDisplayStyle,
3673            'odd'           => ($j % 2), // true for odd, false for even
3674            ), true);
3675        $answer_tds = '';
3676        $fn++;
3677        $inputnames[] = $myfname;
3678    }
3679
3680    $answer = doRender('/survey/questions/answer/arrays/5point/answer', array(
3681        'coreClass' => $coreClass,
3682        'sColumns'   => $sColumns,
3683        'answerwidth'   => $answerwidth,
3684        'sHeaders'   => $sHeaders,
3685        'sRows'      => $sRows,
3686        'basename' => $ia[1],
3687        ), true);
3688
3689    return array($answer, $inputnames);
3690}
3691
3692
3693
3694
3695// ---------------------------------------------------------------
3696/**
3697* Construct answer part array_10point
3698* @param array $ia
3699* @return array
3700*/
3701// TMSW TODO - Can remove DB query by passing in answer list from EM
3702function do_array_10point($ia)
3703{
3704    global $thissurvey;
3705    $aLastMoveResult = LimeExpressionManager::GetLastMoveResult();
3706    $aMandatoryViolationSubQ = ($aLastMoveResult['mandViolation'] && $ia[6] == 'Y') ? explode("|", $aLastMoveResult['unansweredSQs']) : array();
3707    $coreClass = "ls-answers subquestion-list questions-list radio-array";
3708
3709    $checkconditionFunction = "checkconditions";
3710
3711    $aQuestionAttributes = QuestionAttribute::model()->getQuestionAttributes($ia[0]);
3712    if (ctype_digit(trim($aQuestionAttributes['answer_width']))) {
3713        $answerwidth = trim($aQuestionAttributes['answer_width']);
3714    } else {
3715        $answerwidth = 33;
3716    }
3717    $cellwidth = 10; // number of columns
3718    if ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1) {
3719        //Question is not mandatory
3720        ++$cellwidth; // add another column
3721    }
3722    $cellwidth = round(((100 - $answerwidth) / $cellwidth), 1); // convert number of columns to percentage of table width
3723
3724    if ($aQuestionAttributes['random_order'] == 1) {
3725        $ansquery = "SELECT * FROM {{questions}} WHERE parent_qid=$ia[0] AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' ORDER BY ".dbRandom();
3726    } else {
3727        $ansquery = "SELECT * FROM {{questions}} WHERE parent_qid=$ia[0] AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' ORDER BY question_order";
3728    }
3729    $ansresult = dbExecuteAssoc($ansquery); //Checked
3730    $aSubquestions = $ansresult->readAll();
3731
3732    $fn = 1;
3733
3734    $odd_even = '';
3735
3736    $sColumns = '';
3737    for ($xc = 1; $xc <= 10; $xc++) {
3738        $odd_even = alternation($odd_even);
3739        $sColumns .= doRender('/survey/questions/answer/arrays/10point/columns/col', array('odd_even'=>$odd_even, 'cellwidth'=>$cellwidth), true);
3740    }
3741
3742    if ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1) {
3743        //Question is not mandatory
3744        $odd_even = alternation($odd_even);
3745        $sColumns .= doRender('/survey/questions/answer/arrays/10point/columns/col', array('odd_even'=>$odd_even, 'cellwidth'=>$cellwidth), true);
3746    }
3747
3748    $sHeaders = '';
3749    $sHeaders .= doRender('/survey/questions/answer/arrays/10point/rows/cells/header_information', array(
3750        'class'=>'',
3751        'content'=>'',
3752        ), true);
3753    for ($xc = 1; $xc <= 10; $xc++) {
3754        $sHeaders .= doRender('/survey/questions/answer/arrays/10point/rows/cells/header_answer', array(
3755            'class'=>'answer-text',
3756            'content'=>$xc,
3757            ), true);
3758    }
3759
3760    if ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1) {
3761        //Question is not mandatory
3762        $sHeaders .= doRender('/survey/questions/answer/arrays/10point/rows/cells/header_answer', array(
3763            'class'=>'answer-text noanswer-text',
3764            'content'=>gT('No answer'),
3765            ), true);
3766    }
3767
3768    $trbc = '';
3769
3770    $sRows = '';
3771    $inputnames = array();
3772    foreach ($aSubquestions as $j => $ansrow) {
3773        $myfname = $ia[1].$ansrow['title'];
3774        $answertext = $ansrow['question'];
3775        /* Check if this item has not been answered */
3776        $error = ($ia[6] == 'Y' && in_array($myfname, $aMandatoryViolationSubQ)) ?true:false;
3777        $trbc = alternation($trbc, 'row');
3778
3779        //Get array filter stuff
3780        //list($htmltbody2, $hiddenfield)=return_array_filter_strings($ia, $aQuestionAttributes, $thissurvey, $ansrow, $myfname, $trbc, $myfname,"tr","$trbc answers-list radio-list");
3781        $sDisplayStyle = return_display_style($ia, $aQuestionAttributes, $thissurvey, $myfname);
3782
3783        // Value
3784        $value = (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname])) ? $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] : '';
3785
3786        $answer_tds = '';
3787        for ($i = 1; $i <= 10; $i++) {
3788            $CHECKED = (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname]) && $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] == $i) ? 'CHECKED' : '';
3789
3790            $answer_tds .= doRender('/survey/questions/answer/arrays/10point/rows/cells/answer_td_input', array(
3791                'i'=>$i,
3792                'labelText'=>$i,
3793                'myfname'=>$myfname,
3794                'CHECKED'=>$CHECKED,
3795                'checkconditionFunction'=>$checkconditionFunction,
3796                'value'=>$i,
3797                ), true);
3798        }
3799
3800        if ($ia[6] != "Y" && SHOW_NO_ANSWER == 1) {
3801            $CHECKED = (!isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname]) || $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] == '') ? 'CHECKED' : '';
3802            $answer_tds .= doRender('/survey/questions/answer/arrays/10point/rows/cells/answer_td_input', array(
3803                'i'=>'',
3804                'labelText'=>gT('No answer'),
3805                'myfname'=>$myfname,
3806                'CHECKED'=>$CHECKED,
3807                'checkconditionFunction'=>$checkconditionFunction,
3808                'value'=>'',
3809                ), true);
3810        }
3811
3812        $sRows .= doRender('/survey/questions/answer/arrays/10point/rows/answer_row', array(
3813            'myfname'       => $myfname,
3814            'answerwidth'   => $answerwidth,
3815            'answertext'    => $answertext,
3816            'value'         => $value,
3817            'error'         => $error,
3818            'sDisplayStyle' => $sDisplayStyle,
3819            'odd'           => ($j % 2),
3820            'answer_tds'    => $answer_tds,
3821            ), true);
3822
3823        $inputnames[] = $myfname;
3824        $fn++;
3825    }
3826
3827    $answer = doRender(
3828        '/survey/questions/answer/arrays/10point/answer',
3829        array(
3830        'coreClass'     => $coreClass,
3831        'answerwidth'   => $answerwidth,
3832        'sColumns'      => $sColumns,
3833        'sHeaders'      => $sHeaders,
3834        'sRows'         => $sRows,
3835        'basename' => $ia[1],
3836        ),
3837        true
3838    );
3839    return array($answer, $inputnames);
3840}
3841
3842
3843function do_array_yesnouncertain($ia)
3844{
3845    $aLastMoveResult         = LimeExpressionManager::GetLastMoveResult();
3846    $aMandatoryViolationSubQ = ($aLastMoveResult['mandViolation'] && $ia[6] == 'Y') ? explode("|", $aLastMoveResult['unansweredSQs']) : array();
3847    $coreClass               = "ls-answers subquestion-list questions-list radio-array";
3848    $checkconditionFunction  = "checkconditions";
3849    $aQuestionAttributes     = QuestionAttribute::model()->getQuestionAttributes($ia[0]);
3850    if (ctype_digit(trim($aQuestionAttributes['answer_width']))) {
3851        $answerwidth = trim($aQuestionAttributes['answer_width']);
3852    } else {
3853        $answerwidth = 33;
3854    }
3855    $cellwidth               = 3; // number of columns
3856
3857    if ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1) {
3858        //Question is not mandatory
3859        ++$cellwidth; // add another column
3860    }
3861
3862    $cellwidth = round(((100 - $answerwidth) / $cellwidth), 1); // convert number of columns to percentage of table width
3863
3864    if ($aQuestionAttributes['random_order'] == 1) {
3865        $ansquery = "SELECT * FROM {{questions}} WHERE parent_qid=$ia[0] AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' ORDER BY ".dbRandom();
3866    } else {
3867        $ansquery = "SELECT * FROM {{questions}} WHERE parent_qid=$ia[0] AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' ORDER BY question_order";
3868    }
3869
3870    $ansresult      = dbExecuteAssoc($ansquery); //Checked
3871    $aSubquestions  = $ansresult->readAll();
3872    $anscount       = count($aSubquestions);
3873    $fn             = 1;
3874
3875    $odd_even = '';
3876    $sColumns = '';
3877
3878    for ($xc = 1; $xc <= 3; $xc++) {
3879        $odd_even  = alternation($odd_even);
3880        $sColumns .= doRender('/survey/questions/answer/arrays/yesnouncertain/columns/col', array('odd_even'=>$odd_even, 'cellwidth'=>$cellwidth), true);
3881    }
3882
3883    if ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1) {
3884        //Question is not mandatory
3885        $odd_even  = alternation($odd_even);
3886        $sColumns .= doRender('/survey/questions/answer/arrays/yesnouncertain/columns/col', array('odd_even'=>$odd_even, 'cellwidth'=>$cellwidth, 'no_answer'=>true), true);
3887    }
3888
3889    $no_answer = ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1) ?true:false;
3890    $sHeaders  = doRender('/survey/questions/answer/arrays/yesnouncertain/rows/cells/thead', array('no_answer'=>$no_answer, 'anscount'=>$anscount), true);
3891
3892    $inputnames = array();
3893    if ($anscount > 0) {
3894        $sRows = '';
3895
3896        foreach ($aSubquestions as $i => $ansrow) {
3897            $myfname = $ia[1].$ansrow['title'];
3898            $answertext = $ansrow['question'];
3899            /* Check the sub question mandatory violation */
3900            $error = ($ia[6] == 'Y' && in_array($myfname, $aMandatoryViolationSubQ)) ?true:false;
3901
3902            // Get array_filter stuff
3903            $no_answer = ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1) ?true:false;
3904            $value     = (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname])) ? $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] : '';
3905            $Ychecked  = (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname]) && $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] == 'Y') ? 'CHECKED' : '';
3906            $Uchecked  = (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname]) && $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] == 'U') ? 'CHECKED' : '';
3907            $Nchecked  = (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname]) && $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] == 'N') ? 'CHECKED' : '';
3908            $NAchecked = (!isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname]) || $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] == '') ? 'CHECKED' : '';
3909
3910            $sRows .= doRender('/survey/questions/answer/arrays/yesnouncertain/rows/answer_row', array(
3911                'myfname'                => $myfname,
3912                'answertext'             => $answertext,
3913                'answerwidth'=>$answerwidth,
3914                'Ychecked'               => $Ychecked,
3915                'Uchecked'               => $Uchecked,
3916                'Nchecked'               => $Nchecked,
3917                'NAchecked'              => $NAchecked,
3918                'value'                  => $value,
3919                'checkconditionFunction' => $checkconditionFunction,
3920                'error'                  => $error,
3921                'no_answer'              => $no_answer,
3922                'odd'                    => ($i % 2)
3923                ), true);
3924            $inputnames[] = $myfname;
3925            $fn++;
3926        }
3927    }
3928
3929    $answer = doRender('/survey/questions/answer/arrays/yesnouncertain/answer', array(
3930        'answerwidth' => $answerwidth,
3931        'coreClass'   => $coreClass,
3932        'sColumns'    => $sColumns,
3933        'sHeaders'    => $sHeaders,
3934        'sRows'       => (isset($sRows)) ? $sRows : '',
3935        'anscount'    => $anscount,
3936        'basename' => $ia[1],
3937        ), true);
3938
3939    return array($answer, $inputnames);
3940}
3941
3942
3943function do_array_increasesamedecrease($ia)
3944{
3945    $aLastMoveResult         = LimeExpressionManager::GetLastMoveResult();
3946    $aMandatoryViolationSubQ = ($aLastMoveResult['mandViolation'] && $ia[6] == 'Y') ? explode("|", $aLastMoveResult['unansweredSQs']) : array();
3947    $coreClass               = "ls-answers subquestion-list questions-list radio-array";
3948    $checkconditionFunction  = "checkconditions";
3949    $aQuestionAttributes     = QuestionAttribute::model()->getQuestionAttributes($ia[0]);
3950    if (ctype_digit(trim($aQuestionAttributes['answer_width']))) {
3951        $answerwidth = trim($aQuestionAttributes['answer_width']);
3952    } else {
3953        $answerwidth = 33;
3954    }
3955    $cellwidth               = 3; // number of columns
3956    $inputnames              = array();
3957
3958    if ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1) {
3959        //Question is not mandatory
3960        ++$cellwidth; // add another column
3961    }
3962
3963    $cellwidth = round(((100 - $answerwidth) / $cellwidth), 1); // convert number of columns to percentage of table width
3964
3965    if ($aQuestionAttributes['random_order'] == 1) {
3966        $ansquery = "SELECT * FROM {{questions}} WHERE parent_qid=$ia[0] AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' ORDER BY ".dbRandom();
3967    } else {
3968        $ansquery = "SELECT * FROM {{questions}} WHERE parent_qid=$ia[0] AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' ORDER BY question_order";
3969    }
3970
3971    $ansresult      = dbExecuteAssoc($ansquery); //Checked
3972    $aSubquestions  = $ansresult->readAll();
3973    $anscount       = count($aSubquestions);
3974    $fn             = 1;
3975    $odd_even       = '';
3976    $sColumns       = "";
3977
3978    for ($xc = 1; $xc <= 3; $xc++) {
3979        $odd_even  = alternation($odd_even);
3980        $sColumns .= doRender('/survey/questions/answer/arrays/increasesamedecrease/columns/col', array('odd_even'=>$odd_even, 'cellwidth'=>$cellwidth), true);
3981    }
3982    if ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1) {
3983        //Question is not mandatory
3984        $odd_even  = alternation($odd_even);
3985        $sColumns .= doRender('/survey/questions/answer/arrays/increasesamedecrease/columns/col', array('odd_even'=>$odd_even, 'cellwidth'=>$cellwidth), true);
3986    }
3987
3988    $no_answer = ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1) ?true:false; //Question is not mandatory
3989
3990    $sHeaders = doRender('/survey/questions/answer/arrays/increasesamedecrease/rows/cells/thead', array('no_answer'=>$no_answer), true);
3991
3992
3993    // rows
3994    $sRows = '';
3995    foreach ($aSubquestions as $i => $ansrow) {
3996        $myfname        = $ia[1].$ansrow['title'];
3997        $answertext     = $ansrow['question'];
3998        $error          = ($ia[6] == 'Y' && in_array($myfname, $aMandatoryViolationSubQ)) ?true:false; /* Check the sub Q mandatory violation */
3999        $value          = (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname])) ? $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] : '';
4000        $Ichecked       = (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname]) && $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] == 'I') ? 'CHECKED' : '';
4001        $Schecked       = (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname]) && $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] == 'S') ? 'CHECKED' : '';
4002        $Dchecked       = (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname]) && $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] == 'D') ? 'CHECKED' : '';
4003        $NAchecked      = (!isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname]) || $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] == '') ? 'CHECKED' : '';
4004        $no_answer      = ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1) ?true:false;
4005
4006        $sRows .= doRender('/survey/questions/answer/arrays/increasesamedecrease/rows/answer_row', array(
4007            'myfname'=> $myfname,
4008            'answertext'=> $answertext,
4009            'answerwidth'=>$answerwidth,
4010            'Ichecked'=>$Ichecked,
4011            'Schecked'=> $Schecked,
4012            'Dchecked'=>$Dchecked,
4013            'NAchecked'=>$NAchecked,
4014            'value'=>$value,
4015            'checkconditionFunction'=>$checkconditionFunction,
4016            'error'=>$error,
4017            'no_answer'=>$no_answer,
4018            'odd' => ($i % 2)
4019            ), true);
4020
4021        $inputnames[] = $myfname;
4022        $fn++;
4023    }
4024
4025    $answer = doRender('/survey/questions/answer/arrays/increasesamedecrease/answer', array(
4026        'coreClass'  => $coreClass,
4027        'answerwidth'=> $answerwidth,
4028        'sColumns'   => $sColumns,
4029        'sHeaders'   => $sHeaders,
4030        'sRows'      => $sRows,
4031        'anscount'   => $anscount,
4032        'basename' => $ia[1],
4033        ), true);
4034
4035    return array($answer, $inputnames);
4036}
4037
4038// ---------------------------------------------------------------
4039// TMSW TODO - Can remove DB query by passing in answer list from EM
4040function do_array($ia)
4041{
4042    $aLastMoveResult         = LimeExpressionManager::GetLastMoveResult();
4043    $aMandatoryViolationSubQ = ($aLastMoveResult['mandViolation'] && $ia[6] == 'Y') ? explode("|", $aLastMoveResult['unansweredSQs']) : array();
4044    $repeatheadings          = Yii::app()->getConfig("repeatheadings");
4045    $minrepeatheadings       = Yii::app()->getConfig("minrepeatheadings");
4046    $coreClass = "ls-answers subquestion-list questions-list";
4047    $checkconditionFunction  = "checkconditions";
4048    $aQuestionAttributes     = QuestionAttribute::model()->getQuestionAttributes($ia[0]);
4049
4050    if ($aQuestionAttributes['use_dropdown'] == 1) {
4051        $useDropdownLayout = true;
4052        $coreClass .= " dropdown-array";
4053        $caption           = gT("A table with a subquestion on each row. You have to select your answer.");
4054    } else {
4055        $useDropdownLayout = false;
4056        $coreClass .= " radio-array";
4057        $caption           = gT("A table with a subquestion on each row. The answer options are contained in the table header.");
4058    }
4059
4060    if (ctype_digit(trim($aQuestionAttributes['repeat_headings'])) && trim($aQuestionAttributes['repeat_headings'] != "")) {
4061        $repeatheadings    = intval($aQuestionAttributes['repeat_headings']);
4062        $minrepeatheadings = 0;
4063    }
4064
4065    $lresult    = Answer::model()->findAll(array('order'=>'sortorder, code', 'condition'=>'qid=:qid AND language=:language AND scale_id=0', 'params'=>array(':qid'=>$ia[0], ':language'=>$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang'])));
4066    $labelans   = array();
4067    $labelcode  = array();
4068
4069    foreach ($lresult as $lrow) {
4070        $labelans[]  = $lrow->answer;
4071        $labelcode[] = $lrow->code;
4072    }
4073
4074    // No-dropdown layout
4075    if ($useDropdownLayout === false && count($lresult) > 0) {
4076        if (ctype_digit(trim($aQuestionAttributes['answer_width']))) {
4077            $answerwidth = trim($aQuestionAttributes['answer_width']);
4078            $defaultWidth = false;
4079        } else {
4080            $answerwidth = 33;
4081            $defaultWidth = true;
4082        }
4083        $columnswidth = 100 - $answerwidth;
4084        $iCount = intval(Question::model()->count("parent_qid=:qid and question like :separator", array(':qid'=>$ia[0], ":separator"=>'%|%')));
4085        if ($iCount > 0) {
4086            $right_exists = true;
4087            /* put the right answer to same width : take place in answer width only if it's not default */
4088            if ($defaultWidth) {
4089                $columnswidth -= $answerwidth;
4090            } else {
4091                $answerwidth = $answerwidth / 2;
4092            }
4093        } else {
4094            $right_exists = false;
4095        }
4096        // $right_exists is a flag to find out if there are any right hand answer parts. If there arent we can leave out the right td column
4097        if ($aQuestionAttributes['random_order'] == 1) {
4098            $ansquery = "SELECT * FROM {{questions}} WHERE parent_qid={$ia[0]} AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' ORDER BY ".dbRandom();
4099        } else {
4100            $ansquery = "SELECT * FROM {{questions}} WHERE parent_qid={$ia[0]} AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' ORDER BY question_order";
4101        }
4102
4103        $ansresult  = dbExecuteAssoc($ansquery); //Checked
4104        $aQuestions = $ansresult->readAll();
4105        $anscount   = count($aQuestions);
4106        $fn         = 1;
4107        $numrows    = count($labelans);
4108
4109        if ($right_exists) {
4110            ++$numrows;
4111            $caption .= gT("After the answer options a cell does give some information.");
4112        }
4113        if ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1) {
4114            ++$numrows;
4115        }
4116
4117        $cellwidth = round(($columnswidth / $numrows), 1);
4118
4119        $sHeaders = doRender('/survey/questions/answer/arrays/array/no_dropdown/rows/cells/header_information', array(
4120            'class'   => '',
4121            'content' => '',
4122            ), true);
4123
4124        foreach ($labelans as $ld) {
4125            $sHeaders .= doRender('/survey/questions/answer/arrays/array/no_dropdown/rows/cells/header_answer', array(
4126                'class'   => "answer-text",
4127                'content' => $ld,
4128                ), true);
4129        }
4130
4131        if ($right_exists) {
4132            $sHeaders .= doRender('/survey/questions/answer/arrays/array/no_dropdown/rows/cells/header_information', array(
4133                'class'     => '',
4134                'content'   => '',
4135                ), true);
4136        }
4137
4138        if ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1) {
4139            //Question is not mandatory and we can show "no answer"
4140            $sHeaders .= doRender('/survey/questions/answer/arrays/array/no_dropdown/rows/cells/header_answer', array(
4141                'class'   => 'answer-text noanswer-text',
4142                'content' => gT('No answer'),
4143                ), true);
4144        }
4145
4146        $inputnames = array();
4147
4148        $sRows = '';
4149        foreach ($aQuestions as $i => $ansrow) {
4150            if (isset($repeatheadings) && $repeatheadings > 0 && ($fn - 1) > 0 && ($fn - 1) % $repeatheadings == 0) {
4151                if (($anscount - $fn + 1) >= $minrepeatheadings) {
4152                    // Close actual body and open another one
4153                    $sRows .= doRender('/survey/questions/answer/arrays/array/no_dropdown/rows/repeat_header', array(
4154                        'sHeaders'=>$sHeaders
4155                        ), true);
4156                }
4157            }
4158
4159            $myfname        = $ia[1].$ansrow['title'];
4160            $answertext     = $ansrow['question'];
4161            $answertext     = (strpos($answertext, '|') !== false) ? substr($answertext, 0, strpos($answertext, '|')) : $answertext;
4162
4163            if ($right_exists && strpos($ansrow['question'], '|') !== false) {
4164                $answertextright = substr($ansrow['question'], strpos($ansrow['question'], '|') + 1);
4165            } else {
4166                $answertextright = '';
4167            }
4168
4169            $error          = (in_array($myfname, $aMandatoryViolationSubQ)) ?true:false; /* Check the mandatory sub Q violation */
4170            $value          = (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname])) ? $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] : '';
4171            $thiskey        = 0;
4172            $answer_tds     = '';
4173            $fn++;
4174
4175            foreach ($labelcode as $ld) {
4176                $CHECKED     = (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname]) && $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] == $ld) ? 'CHECKED' : '';
4177                $answer_tds .= doRender('/survey/questions/answer/arrays/array/no_dropdown/rows/cells/answer_td', array(
4178                    'myfname'=>$myfname,
4179                    'ld'=>$ld,
4180                    'label'=>$labelans[$thiskey],
4181                    'CHECKED'=>$CHECKED,
4182                    'checkconditionFunction'=>$checkconditionFunction,
4183                    ), true);
4184                $thiskey++;
4185            }
4186
4187            // NB: $ia[6] = mandatory
4188            $no_answer_td = '';
4189            if ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1) {
4190                $CHECKED = (!isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname]) || $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] == '') ? 'CHECKED' : '';
4191                $no_answer_td .= doRender('/survey/questions/answer/arrays/array/no_dropdown/rows/cells/answer_td', array(
4192                    'myfname'                => $myfname,
4193                    'ld'                     => '',
4194                    'label'                  => gT('No answer'),
4195                    'CHECKED'                => $CHECKED,
4196                    'checkconditionFunction' => $checkconditionFunction,
4197                    ), true);
4198            }
4199            $sRows .= doRender('/survey/questions/answer/arrays/array/no_dropdown/rows/answer_row', array(
4200                'answer_tds' => $answer_tds,
4201                'no_answer_td' => $no_answer_td,
4202                'myfname'    => $myfname,
4203                'answertext' => $answertext,
4204                'answerwidth'=>$answerwidth,
4205                'answertextright' => $answertextright,
4206                'right_exists' => $right_exists,
4207                'value'      => $value,
4208                'error'      => $error,
4209                'odd'        => ($i % 2), // true for odd, false for even
4210                ), true);
4211            $inputnames[] = $myfname;
4212        }
4213
4214
4215        $odd_even = '';
4216        $sColumns = '';
4217        foreach ($labelans as $c) {
4218            $odd_even = alternation($odd_even);
4219            $sColumns .= doRender('/survey/questions/answer/arrays/array/no_dropdown/columns/col', array(
4220                'class'     => $odd_even,
4221                'cellwidth' => $cellwidth,
4222                ), true);
4223        }
4224
4225        if ($right_exists) {
4226            $odd_even = alternation($odd_even);
4227            $sColumns .= doRender('/survey/questions/answer/arrays/array/no_dropdown/columns/col', array(
4228                'class'     => 'answertextright '.$odd_even,
4229                'cellwidth' => $answerwidth,
4230                ), true);
4231        }
4232
4233        if ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1) {
4234            //Question is not mandatory
4235            $odd_even = alternation($odd_even);
4236            $sColumns .= doRender('/survey/questions/answer/arrays/array/no_dropdown/columns/col', array(
4237                'class'     => 'col-no-answer '.$odd_even,
4238                'cellwidth' => $cellwidth,
4239                ), true);
4240        }
4241
4242        $answer = doRender('/survey/questions/answer/arrays/array/no_dropdown/answer', array(
4243            'answerwidth'=> $answerwidth,
4244            'anscount'   => $anscount,
4245            'sRows'      => $sRows,
4246            'coreClass'  => $coreClass,
4247            'sHeaders'   => $sHeaders,
4248            'sColumns'   => $sColumns,
4249            'basename' => $ia[1],
4250            ), true);
4251    }
4252
4253    // Dropdown layout
4254    elseif ($useDropdownLayout === true && count($lresult) > 0) {
4255        if (ctype_digit(trim($aQuestionAttributes['answer_width']))) {
4256            $answerwidth = trim($aQuestionAttributes['answer_width']);
4257            $defaultWidth = false;
4258        } else {
4259            $answerwidth = 33;
4260            $defaultWidth = true;
4261        }
4262        $columnswidth = 100 - $answerwidth;
4263        $labels = [];
4264        foreach ($lresult as $lrow) {
4265            $labels[] = array(
4266                'code'   => $lrow->code,
4267                'answer' => $lrow->answer
4268            );
4269        }
4270
4271        $sQuery = "SELECT count(question) FROM {{questions}} WHERE parent_qid={$ia[0]} AND question like '%|%' ";
4272        $iCount = Yii::app()->db->createCommand($sQuery)->queryScalar();
4273
4274        if ($iCount > 0) {
4275            $right_exists = true;
4276            /* put the right answer to same width : take place in answer width only if it's not default */
4277            if ($defaultWidth) {
4278                $columnswidth -= $answerwidth;
4279            } else {
4280                $answerwidth = $answerwidth / 2;
4281            }
4282        } else {
4283            $right_exists = false;
4284        }
4285        // $right_exists is a flag to find out if there are any right hand answer parts. If there arent we can leave out the right td column
4286        if ($aQuestionAttributes['random_order'] == 1) {
4287            $ansquery = "SELECT * FROM {{questions}} WHERE parent_qid={$ia[0]} AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' ORDER BY ".dbRandom();
4288        } else {
4289            $ansquery = "SELECT * FROM {{questions}} WHERE parent_qid={$ia[0]} AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' ORDER BY question_order";
4290        }
4291
4292        $ansresult  = dbExecuteAssoc($ansquery); //Checked
4293        $aQuestions = $ansresult->readAll();
4294        $fn         = 1;
4295
4296        $inputnames = array();
4297
4298        $sRows = "";
4299        foreach ($aQuestions as $j => $ansrow) {
4300            $myfname        = $ia[1].$ansrow['title'];
4301            $answertext     = $ansrow['question'];
4302            $answertext     = (strpos($answertext, '|') !== false) ? substr($answertext, 0, strpos($answertext, '|')) : $answertext;
4303            $error          = (in_array($myfname, $aMandatoryViolationSubQ)) ?true:false; /* Check the mandatory sub Q violation */
4304            $value          = (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname])) ? $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] : '';
4305
4306            if ($right_exists && (strpos($ansrow['question'], '|') !== false)) {
4307                $answertextright = substr($ansrow['question'], strpos($ansrow['question'], '|') + 1);
4308            } else {
4309                $answertextright = null;
4310            }
4311
4312            $options = array();
4313
4314            /* Dropdown representation : first choice (activated) must be Please choose... if there are no actual answer */
4315            $showNoAnswer = $ia[6] != 'Y' && SHOW_NO_ANSWER == 1; // Tag if we must show no-answer
4316            if (!isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname]) || $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] === '') {
4317                $options[] = array(
4318                    'text'=> gT('Please choose...'),
4319                    'value'=> '',
4320                    'selected'=>''
4321                );
4322                $showNoAnswer = false;
4323            }
4324            // Real options
4325            foreach ($labels as $i=>$lrow) {
4326                $options[] = array(
4327                    'value'=>$lrow['code'],
4328                    'selected'=>($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] == $lrow['code']) ? SELECTED :'',
4329                    'text'=> flattenText($lrow['answer'])
4330                );
4331            }
4332            /* Add the now answer if needed */
4333            if ($showNoAnswer) {
4334                $options[] = array(
4335                    'text'=> gT('No answer'),
4336                    'value'=> '',
4337                    'selected'=> ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] === '') ?  SELECTED :'',
4338                );
4339            }
4340            unset($showNoAnswer);
4341            $sRows .= doRender('/survey/questions/answer/arrays/array/dropdown/rows/answer_row', array(
4342                'myfname'                => $myfname,
4343                'answertext'             => $answertext,
4344                'answerwidth'=>$answerwidth,
4345                'value'                  => $value,
4346                'error'                  => $error,
4347                'checkconditionFunction' => $checkconditionFunction,
4348                'right_exists'           => $right_exists,
4349                'answertextright'        => $answertextright,
4350                'options'                => $options,
4351                'odd'                    => ($j % 2), // true for odd, false for even
4352                ), true);
4353
4354            $inputnames[] = $myfname;
4355            $fn++;
4356        }
4357
4358        $answer = doRender('/survey/questions/answer/arrays/array/dropdown/answer', array(
4359                'coreClass' => $coreClass,
4360                'basename' => $ia[1],
4361                'sRows'      => $sRows,
4362                'answerwidth'=> $answerwidth,
4363                'columnswidth'=> $columnswidth,
4364                'right_exists'=> $right_exists,
4365            ), true);
4366    } else {
4367        $answer = doRender('/survey/questions/answer/arrays/array/dropdown/empty', array(), true);
4368        $inputnames = '';
4369    }
4370    return array($answer, $inputnames);
4371}
4372
4373
4374function do_array_texts($ia)
4375{
4376    global $thissurvey;
4377    $aLastMoveResult            = LimeExpressionManager::GetLastMoveResult();
4378    $aMandatoryViolationSubQ    = ($aLastMoveResult['mandViolation'] && $ia[6] == 'Y') ? explode("|", $aLastMoveResult['unansweredSQs']) : array();
4379    $repeatheadings             = Yii::app()->getConfig("repeatheadings");
4380    $minrepeatheadings          = Yii::app()->getConfig("minrepeatheadings");
4381    $coreClass                  = "ls-answers subquestion-list questions-list text-array";
4382    $extraclass                 = "";
4383    $coreRowClass               = "subquestion-list questions-list";
4384    $caption                    = gT("A table of subquestions on each cell. The subquestion texts are in the column header and relate the particular row header.");
4385
4386    if ($thissurvey['nokeyboard'] == 'Y') {
4387        includeKeypad();
4388        $kpclass = "text-keypad";
4389    } else {
4390        $kpclass = "";
4391    }
4392
4393    $checkconditionFunction = "checkconditions";
4394    $sSeparator             = getRadixPointData($thissurvey['surveyls_numberformat']);
4395    $sSeparator             = $sSeparator['separator'];
4396    $aQuestionAttributes    = QuestionAttribute::model()->getQuestionAttributes($ia[0]);
4397    $show_grand             = $aQuestionAttributes['show_grand_total'];
4398    $totals_class           = '';
4399    $show_totals            = '';
4400    $col_total              = '';
4401    $row_total              = '';
4402    $col_head               = '';
4403    $row_head               = '';
4404    $grand_total            = '';
4405    $q_table_id             = '';
4406    $q_table_id_HTML        = '';
4407    $isNumber = intval($aQuestionAttributes['numbers_only'] == 1);
4408    $isInteger = 0;
4409    $inputnames             = array();
4410
4411    if (ctype_digit(trim($aQuestionAttributes['repeat_headings'])) && trim($aQuestionAttributes['repeat_headings'] != "")) {
4412        $repeatheadings     = intval($aQuestionAttributes['repeat_headings']);
4413        $minrepeatheadings  = 0;
4414    }
4415    if (intval(trim($aQuestionAttributes['maximum_chars'])) > 0) {
4416        // Only maxlength attribute, use textarea[maxlength] jquery selector for textarea
4417        $maxlength = intval(trim($aQuestionAttributes['maximum_chars']));
4418        $extraclass .= " ls-input-maxchars";
4419    } else {
4420        $maxlength = "";
4421    }
4422    if (ctype_digit(trim($aQuestionAttributes['input_size']))) {
4423        $inputsize = trim($aQuestionAttributes['input_size']);
4424        $extraclass .= " ls-input-sized";
4425    } else {
4426        $inputsize = null;
4427    }
4428    if ($aQuestionAttributes['numbers_only'] == 1) {
4429        $checkconditionFunction = "fixnum_checkconditions";
4430
4431        if (in_array($aQuestionAttributes['show_totals'], array("R", "C", "B"))) {
4432            $q_table_id      = 'totals_'.$ia[0];
4433            $q_table_id_HTML = ' id="'.$q_table_id.'"';
4434        }
4435
4436        $coreClass .= " number-array";
4437        $coreRowClass .= " number-list";
4438        $caption    .= gT("Each answer may only be a number.");
4439        $col_head    = '';
4440        switch ($aQuestionAttributes['show_totals']) {
4441
4442            case 'R':
4443                $totals_class   = $show_totals = 'row';
4444                $row_total      = doRender('/survey/questions/answer/arrays/texts/rows/cells/td_total', array('empty'=>false, 'inputsize'=>$inputsize), true);
4445                $col_head       = doRender('/survey/questions/answer/arrays/texts/rows/cells/thead', array('totalText'=>gT('Total'), 'classes'=>''), true);
4446
4447                if ($show_grand == true) {
4448                    $row_head    = doRender('/survey/questions/answer/arrays/texts/rows/cells/thead', array('totalText'=>gT('Grand total'), 'classes'=>'answertext'), true);
4449                    $col_total   = doRender('/survey/questions/answer/arrays/texts/columns/col_total', array('empty'=>true, 'inputsize'=>$inputsize), true);
4450                    $grand_total = doRender('/survey/questions/answer/arrays/texts/rows/cells/td_grand_total', array('empty'=>false, 'inputsize'=>$inputsize), true);
4451                };
4452
4453                $caption .= gT("The last row shows the total for the column.");
4454                break;
4455
4456            case 'C':
4457                $totals_class = $show_totals = 'col';
4458                $col_total    = doRender('/survey/questions/answer/arrays/texts/columns/col_total', array('empty'=>false, 'inputsize'=>$inputsize, 'label'=>true), true);
4459                $row_head     = doRender('/survey/questions/answer/arrays/texts/rows/cells/thead', array('totalText'=>gT('Total'), 'classes'=>'answertext'), true);
4460
4461                if ($show_grand == true) {
4462                    $row_total   = doRender('/survey/questions/answer/arrays/texts/rows/cells/td_total', array('empty'=>true, 'inputsize'=>$inputsize), true);
4463                    $col_head    = doRender('/survey/questions/answer/arrays/texts/rows/cells/thead', array('totalText'=>gT('Grand total'), 'classes'=>''), true);
4464                    $grand_total = doRender('/survey/questions/answer/arrays/texts/rows/cells/td_grand_total', array('empty'=>false, 'inputsize'=>$inputsize), true);
4465                };
4466                $caption .= gT("The last column shows the total for the row.");
4467                break;
4468
4469            case 'B':
4470                $totals_class = $show_totals = 'both';
4471                $row_total    = doRender('/survey/questions/answer/arrays/texts/rows/cells/td_total', array('empty'=>false, 'inputsize'=>$inputsize), true);
4472                $col_total    = doRender('/survey/questions/answer/arrays/texts/columns/col_total', array('empty'=>false, 'inputsize'=>$inputsize, 'label'=>false), true);
4473                $col_head     = doRender('/survey/questions/answer/arrays/texts/rows/cells/thead', array('totalText'=>gT('Total'), 'classes'=>''), true);
4474                $row_head     = doRender('/survey/questions/answer/arrays/texts/rows/cells/thead', array('totalText'=>gT('Total'), 'classes'=>'answertext'), true);
4475
4476                if ($show_grand == true) {
4477                    $grand_total = doRender('/survey/questions/answer/arrays/texts/rows/cells/td_grand_total', array('empty'=>false, 'inputsize'=>$inputsize), true);
4478                } else {
4479                    $grand_total = doRender('/survey/questions/answer/arrays/texts/rows/cells/td_grand_total', array('empty'=>true, 'inputsize'=>$inputsize), true);
4480                };
4481
4482                $caption .= gT("The last row shows the total for the column and the last column shows the total for the row.");
4483                break;
4484        };
4485
4486        if (!empty($totals_class)) {
4487            $totals_class = ' show-totals '.$totals_class;
4488
4489            if ($aQuestionAttributes['show_grand_total']) {
4490                $totals_class  .= ' grand';
4491                $show_grand     = true;
4492            };
4493        };
4494    }
4495
4496    if (ctype_digit(trim($aQuestionAttributes['answer_width']))) {
4497        $answerwidth = trim($aQuestionAttributes['answer_width']);
4498        $defaultWidth = false;
4499    } else {
4500        $answerwidth = 33;
4501        $defaultWidth = true;
4502    }
4503    $columnswidth = 100 - ($answerwidth);
4504    $lquery       = "SELECT * FROM {{questions}} WHERE parent_qid={$ia[0]}  AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' and scale_id=1 ORDER BY question_order";
4505    $lresult      = Yii::app()->db->createCommand($lquery)->query();
4506    $labelans     = array();
4507    $labelcode    = array();
4508    foreach ($lresult->readAll() as $lrow) {
4509        $labelans[]  = $lrow['question'];
4510        $labelcode[] = $lrow['title'];
4511    }
4512
4513    if ($numrows = count($labelans)) {
4514        // There are no "No answer" column
4515        if (($show_grand == true && $show_totals == 'col') || $show_totals == 'row' || $show_totals == 'both') {
4516            ++$numrows;
4517        }
4518
4519        $cellwidth = $columnswidth / $numrows;
4520
4521        $ansquery  = "SELECT count(question) FROM {{questions}} WHERE parent_qid={$ia[0]} and scale_id=0 AND question like '%|%'";
4522        $ansresult = Yii::app()->db->createCommand($ansquery)->queryScalar(); //Checked
4523
4524        if ($ansresult > 0) {
4525            $right_exists = true;
4526            if (!$defaultWidth) {
4527                $answerwidth = $answerwidth / 2;
4528            }
4529        } else {
4530            $right_exists = false;
4531        }
4532
4533        // $right_exists is a flag to find out if there are any right hand answer parts. If there arent we can leave out the right td column
4534        if ($aQuestionAttributes['random_order'] == 1) {
4535            $ansquery = "SELECT * FROM {{questions}} WHERE parent_qid=$ia[0] and scale_id=0 AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' ORDER BY ".dbRandom();
4536        } else {
4537            $ansquery = "SELECT * FROM {{questions}} WHERE parent_qid=$ia[0] and scale_id=0 AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' ORDER BY question_order";
4538        }
4539
4540        $ansresult  = dbExecuteAssoc($ansquery);
4541        $aQuestions = $ansresult->readAll();
4542        $anscount   = count($aQuestions);
4543        $fn         = 1;
4544
4545        $showGrandTotal = (($show_grand == true && $show_totals == 'col') || $show_totals == 'row' || $show_totals == 'both') ?true:false;
4546
4547        $sRows = '';
4548        $answertext = '';
4549        foreach ($aQuestions as $j => $ansrow) {
4550            if (isset($repeatheadings) && $repeatheadings > 0 && ($fn - 1) > 0 && ($fn - 1) % $repeatheadings == 0) {
4551                if (($anscount - $fn + 1) >= $minrepeatheadings) {
4552                    // Close actual body and open another one
4553                    $sRows .= doRender('/survey/questions/answer/arrays/texts/rows/repeat_header', array(
4554                        'answerwidth'  => $answerwidth,
4555                        'labelans'     => $labelans,
4556                        'right_exists' => $right_exists,
4557                        'col_head'     => $col_head,
4558                        ), true);
4559                }
4560            }
4561
4562            $myfname = $ia[1].$ansrow['title'];
4563            $answertext = $ansrow['question'];
4564            $answertextsave = $answertext;
4565            $error = false;
4566
4567            if ($ia[6] == 'Y' && !empty($aMandatoryViolationSubQ)) {
4568                //Go through each labelcode and check for a missing answer! If any are found, highlight this line
4569                $emptyresult = 0;
4570                foreach ($labelcode as $ld) {
4571                    $myfname2 = $myfname.'_'.$ld;
4572                    if (in_array($myfname2, $aMandatoryViolationSubQ)) {
4573                        $emptyresult = 1;
4574                    }
4575                }
4576                $error = false;
4577                if ($emptyresult == 1) {
4578                    $error = true;
4579                }
4580            }
4581            $value = (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname])) ? $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] : '';
4582
4583            if (strpos($answertext, '|') !== false) {
4584                $answertext = (string) substr($answertext, 0, strpos($answertext, '|'));
4585            }
4586
4587            $thiskey = 0;
4588            $answer_tds = '';
4589
4590            foreach ($labelcode as $ld) {
4591                $myfname2 = $myfname."_$ld";
4592                $myfname2value = isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname2]) ? $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname2] : "";
4593
4594                if ($aQuestionAttributes['numbers_only'] == 1) {
4595                    $myfname2value = str_replace('.', $sSeparator, $myfname2value);
4596                }
4597
4598                $inputnames[] = $myfname2;
4599                $value        = str_replace('"', "'", str_replace('\\', '', $myfname2value));
4600                $answer_tds  .= doRender('/survey/questions/answer/arrays/texts/rows/cells/answer_td', array(
4601                    'ld'         => $ld,
4602                    'myfname2'   => $myfname2,
4603                    'labelText'  => $labelans[$thiskey],
4604                    'kpclass'    => $kpclass,
4605                    'maxlength'  => $maxlength,
4606                    'inputsize'  => $inputsize,
4607                    'value'      => $myfname2value,
4608                    'isNumber'   => $isNumber,
4609                    'isInteger'  => $isInteger,
4610                    'error'      => ($error && $myfname2value === ''),
4611                    ), true);
4612                $thiskey += 1;
4613            }
4614
4615            $rightTd = $rightTdEmpty = false;
4616
4617            if (strpos($answertextsave, '|') !== false) {
4618                $answertext = (string) substr($answertextsave, strpos($answertextsave, '|') + 1);
4619                $rightTd    = true;
4620                $rightTdEmpty = false;
4621            } elseif ($right_exists) {
4622                $rightTd      = true;
4623                $rightTdEmpty = true;
4624            }
4625            $formatedRowTotal = str_replace(array('[[ROW_NAME]]', '[[INPUT_WIDTH]]'), array(strip_tags($answertext), $inputsize), $row_total);
4626            $sRows .= doRender('/survey/questions/answer/arrays/texts/rows/answer_row', array(
4627                'myfname'           =>  $myfname,
4628                'coreRowClass'      => $coreRowClass,
4629                'answertext'        =>  $answertext,
4630                'error'             =>  $error,
4631                'value'             =>  $value,
4632                'answer_tds'        =>  $answer_tds,
4633                'rightTd'           =>  $rightTd,
4634                'rightTdEmpty'      =>  $rightTdEmpty,
4635                'answerwidth'       =>  $answerwidth,
4636                'formatedRowTotal'  =>  $formatedRowTotal,
4637                'odd'               => ($j % 2),
4638                ), true);
4639
4640            $fn++;
4641        }
4642
4643        $showtotals = false;
4644        $total = '';
4645
4646        if ($show_totals == 'col' || $show_totals == 'both' || $grand_total !== '') {
4647            $showtotals = true;
4648
4649            $iLabelCodeCount = count($labelcode);
4650            for ($a = 0; $a < $iLabelCodeCount; ++$a) {
4651                $total .= str_replace(array('[[ROW_NAME]]', '[[INPUT_WIDTH]]'), array(strip_tags($answertext), $inputsize), $col_total);
4652            };
4653            $total .= str_replace(array('[[ROW_NAME]]', '[[INPUT_WIDTH]]'), array(strip_tags($answertext), $inputsize), $grand_total);
4654        }
4655
4656        $radix = '';
4657
4658        if (!empty($q_table_id)) {
4659            if ($aQuestionAttributes['numbers_only'] == 1) {
4660                $radix = $sSeparator;
4661            } else {
4662                $radix = 'X'; // to indicate that should not try to change entered values
4663            }
4664        }
4665
4666        $answer = doRender('/survey/questions/answer/arrays/texts/answer', array(
4667            'answerwidth'               => $answerwidth,
4668            'col_head'                  => $col_head,
4669            'cellwidth'                 => $cellwidth,
4670            'labelans'                  => $labelans,
4671            'right_exists'              => $right_exists,
4672            'showGrandTotal'            => $showGrandTotal,
4673            'q_table_id_HTML'           => $q_table_id_HTML,
4674            'coreClass'                 => $coreClass,
4675            'basename' => $ia[1],
4676            'extraclass'                => $extraclass,
4677            'totals_class'              => $totals_class,
4678            'showtotals'                => $showtotals,
4679            'row_head'                  => $row_head,
4680            'total'                     => $total,
4681            'q_table_id'                => $q_table_id,
4682            'radix'                     => $radix,
4683            'name'                      => $ia[0],
4684            'sRows'                     => $sRows,
4685            'checkconditionFunction'    => $checkconditionFunction
4686            ), true);
4687    } else {
4688        $inputnames = '';
4689        $answer = doRender('/survey/questions/answer/arrays/texts/empty_error', array(), true);
4690    }
4691    return array($answer, $inputnames);
4692}
4693
4694// ---------------------------------------------------------------
4695// TMSW TODO - Can remove DB query by passing in answer list from EM
4696// Used by array numbers, array_numbers (for searching)
4697function do_array_multiflexi($ia)
4698{
4699    global $thissurvey;
4700
4701    $inputnames                 = array();
4702    $aLastMoveResult            = LimeExpressionManager::GetLastMoveResult();
4703    $aMandatoryViolationSubQ    = ($aLastMoveResult['mandViolation'] && $ia[6] == 'Y') ? explode("|", $aLastMoveResult['unansweredSQs']) : array();
4704    $repeatheadings             = Yii::app()->getConfig("repeatheadings");
4705    $minrepeatheadings          = Yii::app()->getConfig("minrepeatheadings");
4706    $coreClass                  = "ls-answers subquestion-list questions-list";
4707    $coreRowClass = "subquestion-list questions-list";
4708    $extraclass                 = "";
4709    $answertypeclass            = "";
4710    $caption                    = gT("A table of subquestions on each cell. The subquestion texts are in the colum header and concern the row header.");
4711    $checkconditionFunction     = "fixnum_checkconditions";
4712    $minvalue                   = '';
4713    $maxvalue                   = '';
4714
4715    /*
4716    * Question Attributes
4717    */
4718    $aQuestionAttributes = QuestionAttribute::model()->getQuestionAttributes($ia[0]);
4719
4720    // Define min and max value
4721    if (trim($aQuestionAttributes['multiflexible_max']) != '' && trim($aQuestionAttributes['multiflexible_min']) == '') {
4722        $maxvalue    = $aQuestionAttributes['multiflexible_max'];
4723        $minvalue    = 1;
4724        $extraclass .= " maxvalue maxvalue-".trim($aQuestionAttributes['multiflexible_max']); // @todo : move to data
4725    }
4726
4727    if (trim($aQuestionAttributes['multiflexible_min']) != '' && trim($aQuestionAttributes['multiflexible_max']) == '') {
4728        $minvalue    = $aQuestionAttributes['multiflexible_min'];
4729        $maxvalue    = $aQuestionAttributes['multiflexible_min'] + 10;
4730        $extraclass .= " minvalue minvalue-".trim($aQuestionAttributes['multiflexible_max']); // @todo : move to data
4731    }
4732
4733    if (trim($aQuestionAttributes['multiflexible_min']) == '' && trim($aQuestionAttributes['multiflexible_max']) == '') {
4734        $maxvalue   = 10;
4735        $minvalue   = (isset($minvalue['value']) && $minvalue['value'] == 0) ? 0 : 1;
4736    }
4737
4738    if (trim($aQuestionAttributes['multiflexible_min']) != '' && trim($aQuestionAttributes['multiflexible_max']) != '') {
4739        if ($aQuestionAttributes['multiflexible_min'] < $aQuestionAttributes['multiflexible_max']) {
4740            $minvalue   = $aQuestionAttributes['multiflexible_min'];
4741            $maxvalue   = $aQuestionAttributes['multiflexible_max'];
4742        }
4743    }
4744
4745    $stepvalue = (trim($aQuestionAttributes['multiflexible_step']) != '' && $aQuestionAttributes['multiflexible_step'] > 0) ? $aQuestionAttributes['multiflexible_step'] : 1;
4746
4747    if ($aQuestionAttributes['reverse'] == 1) {
4748        $tmp        = $minvalue;
4749        $minvalue   = $maxvalue;
4750        $maxvalue   = $tmp;
4751        $reverse    = true;
4752        $stepvalue  = -$stepvalue;
4753    } else {
4754        $reverse    = false;
4755    }
4756
4757    $checkboxlayout = false;
4758    $inputboxlayout = false;
4759    $textAlignment  = 'right';
4760
4761    if ($aQuestionAttributes['multiflexible_checkbox'] != 0) {
4762        $layout = "checkbox";
4763        $minvalue            = 0;
4764        $maxvalue            = 1;
4765        $checkboxlayout      = true;
4766        $answertypeclass     = " checkbox-item";
4767        $coreClass          .= " checkbox-array";
4768        $coreRowClass .= " checkbox-list";
4769        $caption            .= gT("Please check the matching combinations.");
4770        $textAlignment       = 'center';
4771        App()->getClientScript()->registerScriptFile(Yii::app()->getConfig('generalscripts')."array-number-checkbox.js", CClientScript::POS_BEGIN);
4772        App()->getClientScript()->registerScript("doArrayNumberCheckbox", "doArrayNumberCheckbox();\n", LSYii_ClientScript::POS_POSTSCRIPT);
4773    } elseif ($aQuestionAttributes['input_boxes'] != 0) {
4774        $layout = "text";
4775        $inputboxlayout      = true;
4776        $answertypeclass    .= " numeric-item text-item";
4777        $coreClass          .= " text-array number-array";
4778        $coreRowClass .= " text-list number-list";
4779        $extraclass         .= " numberonly";
4780        $caption            .= gT("Please enter only numbers.");
4781    } else {
4782        $layout = "dropdown";
4783        $answertypeclass     = " dropdown-item";
4784        $coreClass          .= " dropdown-array";
4785        $coreRowClass .= " dropdown-list";
4786        $caption            .= gT("Please select an answer for each combination.");
4787    }
4788
4789    if (ctype_digit(trim($aQuestionAttributes['repeat_headings'])) && trim($aQuestionAttributes['repeat_headings'] != "")) {
4790        $repeatheadings     = intval($aQuestionAttributes['repeat_headings']);
4791        $minrepeatheadings  = 0;
4792    }
4793
4794    if (intval(trim($aQuestionAttributes['maximum_chars'])) > 0) {
4795        // Only maxlength attribute, use textarea[maxlength] jquery selector for textarea
4796        $maxlength = intval(trim($aQuestionAttributes['maximum_chars']));
4797        $extraclass .= " ls-input-maxchars"; // @todo : move to data or fix class
4798    } else {
4799        $maxlength = "";
4800    }
4801    if (ctype_digit(trim($aQuestionAttributes['input_size']))) {
4802        $inputsize = trim($aQuestionAttributes['input_size']);
4803        $extraclass .= " ls-input-sized";
4804    } else {
4805        $inputsize = null;
4806    }
4807
4808    if ($thissurvey['nokeyboard'] == 'Y') {
4809        includeKeypad();
4810        $kpclass     = " num-keypad";
4811        $extraclass .= " inputkeypad";
4812    } else {
4813        $kpclass = "";
4814    }
4815
4816    if (ctype_digit(trim($aQuestionAttributes['answer_width']))) {
4817        $answerwidth = trim($aQuestionAttributes['answer_width']);
4818        $defaultWidth = false;
4819    } else {
4820        $answerwidth = 33;
4821        $defaultWidth = true;
4822    }
4823
4824    $columnswidth   = 100 - ($answerwidth);
4825    $lquery         = "SELECT * FROM {{questions}} WHERE parent_qid={$ia[0]}  AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' and scale_id=1 ORDER BY question_order";
4826    $lresult        = dbExecuteAssoc($lquery);
4827    $aQuestions     = $lresult->readAll();
4828    $labelans       = array();
4829    $labelcode      = array();
4830
4831    foreach ($aQuestions as $lrow) {
4832        $labelans[]  = $lrow['question'];
4833        $labelcode[] = $lrow['title'];
4834    }
4835
4836    if ($numrows = count($labelans)) {
4837        // There are no "No answer" column
4838        $cellwidth  = $columnswidth / $numrows;
4839
4840        $sQuery     = "SELECT count(question) FROM {{questions}} WHERE parent_qid=".$ia[0]." AND scale_id=0 AND question like '%|%'";
4841        $iCount     = Yii::app()->db->createCommand($sQuery)->queryScalar();
4842
4843        if ($iCount > 0) {
4844            $right_exists = true;
4845            if (!$defaultWidth) {
4846                $answerwidth = $answerwidth / 2;
4847            }
4848        } else {
4849            $right_exists = false;
4850        }
4851
4852        // $right_exists is a flag to find out if there are any right hand answer parts. If there arent we can leave out the right td column
4853        if ($aQuestionAttributes['random_order'] == 1) {
4854            $ansquery = "SELECT * FROM {{questions}} WHERE parent_qid=$ia[0] AND scale_id=0 AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' ORDER BY ".dbRandom();
4855        } else {
4856            $ansquery = "SELECT * FROM {{questions}} WHERE parent_qid=$ia[0] AND scale_id=0 AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' ORDER BY question_order";
4857        }
4858
4859        $ansresult = dbExecuteAssoc($ansquery)->readAll(); //Checked
4860
4861        if (trim($aQuestionAttributes['parent_order'] != '')) {
4862            $iParentQID = (int) $aQuestionAttributes['parent_order'];
4863            $aResult    = array();
4864            $sessionao  = isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['answer_order']) ? $_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['answer_order'] : array();
4865
4866            if (isset($sessionao[$iParentQID])) {
4867                foreach ($sessionao[$iParentQID] as $aOrigRow) {
4868                    $sCode = $aOrigRow['title'];
4869
4870                    foreach ($ansresult as $aRow) {
4871                        if ($sCode == $aRow['title']) {
4872                            $aResult[] = $aRow;
4873                        }
4874                    }
4875                }
4876                $ansresult = $aResult;
4877            }
4878        }
4879        $anscount = count($ansresult);
4880        $fn = 1;
4881
4882        $sAnswerRows = '';
4883        foreach ($ansresult as $j => $ansrow) {
4884            if (isset($repeatheadings) && $repeatheadings > 0 && ($fn - 1) > 0 && ($fn - 1) % $repeatheadings == 0) {
4885                if (($anscount - $fn + 1) >= $minrepeatheadings) {
4886                    $sAnswerRows .= doRender('/survey/questions/answer/arrays/multiflexi/rows/repeat_header', array(
4887                        'labelans'      =>  $labelans,
4888                        'right_exists'  =>  $right_exists,
4889                        'cellwidth'     =>  $cellwidth,
4890                        'answerwidth'   =>  $answerwidth,
4891                        'textAlignment' => $textAlignment,
4892                        ), true);
4893                }
4894            }
4895
4896            $myfname        = $ia[1].$ansrow['title'];
4897            $answertext     = $ansrow['question'];
4898            $answertextsave = $answertext;
4899
4900            /* Check the sub Q mandatory violation */
4901            $error = false;
4902
4903            if ($ia[6] == 'Y' && !empty($aMandatoryViolationSubQ)) {
4904                //Go through each labelcode and check for a missing answer! Default :If any are found, highlight this line, checkbox : if one is not found : don't highlight
4905                // PS : we really need a better system : event for EM !
4906                $emptyresult = ($aQuestionAttributes['multiflexible_checkbox'] != 0) ? 1 : 0;
4907
4908                foreach ($labelcode as $ld) {
4909                    $myfname2 = $myfname.'_'.$ld;
4910                    if ($aQuestionAttributes['multiflexible_checkbox'] != 0) {
4911                        if (!in_array($myfname2, $aMandatoryViolationSubQ)) {
4912                            $emptyresult = 0;
4913                        }
4914                    } else {
4915                        if (in_array($myfname2, $aMandatoryViolationSubQ)) {
4916                            $emptyresult = 1;
4917                        }
4918                    }
4919                }
4920
4921                $error = ($emptyresult == 1) ?true:false;
4922            }
4923
4924            $sSeparator = getRadixPointData($thissurvey['surveyls_numberformat']);
4925            $sSeparator = $sSeparator['separator'];
4926
4927            // Get array_filter stuff
4928            $sDisplayStyle = return_display_style($ia, $aQuestionAttributes, $thissurvey, $myfname);
4929
4930
4931            if (strpos($answertext, '|') !== false) {
4932                $answertext = (string) substr($answertext, 0, strpos($answertext, '|'));
4933            }
4934
4935            $row_value = (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname])) ? $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] : '';
4936
4937            $thiskey            = 0;
4938            $answer_tds         = '';
4939
4940            foreach ($labelcode as $i => $ld) {
4941                $myfname2   = $myfname."_$ld";
4942                $value      = (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname2])) ? $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname2] : '';
4943
4944                // Possibly replace '.' with ','
4945                $surveyId = Yii::app()->getConfig('surveyID');
4946                $surveyLabel = 'survey_'.$surveyId;
4947                $fieldnameIsNumeric = isset($_SESSION[$surveyLabel][$myfname2])
4948                && is_numeric($_SESSION[$surveyLabel][$myfname2]);
4949                if ($fieldnameIsNumeric) {
4950                    $value = str_replace('.', $sSeparator, $_SESSION[$surveyLabel][$myfname2]);
4951                }
4952
4953                if ($checkboxlayout === false) {
4954                    $answer_tds .= doRender('/survey/questions/answer/arrays/multiflexi/rows/cells/answer_td', array(
4955                        'dataTitle'                 => $labelans[$i],
4956                        'ld'                        => $ld,
4957                        'answertypeclass'           => $answertypeclass,
4958                        'answertext'                => $answertext,
4959                        'stepvalue'                 => $stepvalue,
4960                        'extraclass'                => $extraclass,
4961                        'myfname2'                  => $myfname2,
4962                        'error'                     => $error,
4963                        'inputboxlayout'            => $inputboxlayout,
4964                        'checkconditionFunction'    => $checkconditionFunction,
4965                        'minvalue'                  => $minvalue,
4966                        'maxvalue'                  => $maxvalue,
4967                        'reverse'                   => $reverse,
4968                        'value'                     => $value,
4969                        'sSeparator'                => $sSeparator,
4970                        'kpclass'                   => $kpclass,
4971                        'maxlength'                 => $maxlength,
4972                        'inputsize'                 => $inputsize,
4973                        'error'                     => ($error && $value === '')
4974                        ), true);
4975
4976
4977                    $inputnames[] = $myfname2;
4978                    $thiskey++;
4979                } else {
4980                    if (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname2]) && $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname2] == '1') {
4981                        $myvalue    = '1';
4982                        $setmyvalue = CHECKED;
4983                    } else {
4984                        $myvalue    = '';
4985                        $setmyvalue = '';
4986                    }
4987
4988                    $answer_tds .= doRender('/survey/questions/answer/arrays/multiflexi/rows/cells/answer_td_checkboxes', array(
4989                        'dataTitle'                 => $labelans[$i],
4990                        'ld'                        => $ld,
4991                        'answertypeclass'           => $answertypeclass,
4992                        'value'                     => $myvalue,
4993                        'setmyvalue'                => $setmyvalue,
4994                        'myfname2'                  => $myfname2,
4995                        'checkconditionFunction'    => $checkconditionFunction,
4996                        'extraclass'                => $extraclass,
4997                        ), true);
4998                    $inputnames[] = $myfname2;
4999                    $thiskey++;
5000                }
5001            }
5002
5003            $rightTd = false;
5004            $answertextright = '';
5005
5006            if (strpos($answertextsave, '|')) {
5007                $answertextright    = substr($answertextsave, strpos($answertextsave, '|') + 1);
5008                $rightTd            = true;
5009            } elseif ($right_exists) {
5010                $rightTd = true;
5011            }
5012
5013            $sAnswerRows .= doRender('/survey/questions/answer/arrays/multiflexi/rows/answer_row', array(
5014                'sDisplayStyle'     => $sDisplayStyle,
5015                'coreRowClass'      => $coreRowClass,
5016                'answerwidth'       => $answerwidth,
5017                'myfname'           => $myfname,
5018                'error'             => $error,
5019                'row_value'         => $row_value,
5020                'answertext'        => $answertext,
5021                'answertextright'   => $answertextright,
5022                'answer_tds'        => $answer_tds,
5023                'rightTd'           => $rightTd,
5024                'odd'               => ($j % 2),
5025                'layout'            => $layout
5026                ), true);
5027            $fn++;
5028        }
5029
5030        $answer = doRender('/survey/questions/answer/arrays/multiflexi/answer', array(
5031            'answertypeclass'   => $answertypeclass,
5032            'coreClass'         => $coreClass,
5033            'basename' => $ia[1],
5034            'extraclass'        => $extraclass,
5035            'answerwidth'       => $answerwidth,
5036            'labelans'          => $labelans,
5037            'cellwidth'         => $cellwidth,
5038            'right_exists'      => $right_exists,
5039            'sAnswerRows'       => $sAnswerRows,
5040            'textAlignment'     => $textAlignment,
5041            ), true);
5042    } else {
5043        $answer     = doRender('/survey/questions/answer/arrays/multiflexi/empty_error', array(), true);
5044        $inputnames = '';
5045    }
5046    return array($answer, $inputnames);
5047}
5048
5049
5050// ---------------------------------------------------------------
5051// TMSW TODO - Can remove DB query by passing in answer list from EM
5052function do_arraycolumns($ia)
5053{
5054    $aLastMoveResult = LimeExpressionManager::GetLastMoveResult();
5055    $aMandatoryViolationSubQ = ($aLastMoveResult['mandViolation'] && $ia[6] == 'Y') ? explode("|", $aLastMoveResult['unansweredSQs']) : array();
5056    $coreClass = "ls-answers subquestion-list questions-list array-radio";
5057    $checkconditionFunction = "checkconditions";
5058
5059    $aQuestionAttributes = QuestionAttribute::model()->getQuestionAttributes($ia[0]);
5060
5061    $lquery = "SELECT * FROM {{answers}} WHERE qid=".$ia[0]."  AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' and scale_id=0 ORDER BY sortorder, code";
5062    $oAnswers = dbExecuteAssoc($lquery);
5063    $aAnswers = $oAnswers->readAll();
5064    $labelans = array();
5065    $labelcode = array();
5066    $labels = array();
5067
5068    foreach ($aAnswers as $lrow) {
5069        $labelans[] = $lrow['answer'];
5070        $labelcode[] = $lrow['code'];
5071        $labels[] = array("answer"=>$lrow['answer'], "code"=>$lrow['code']);
5072    }
5073
5074    $inputnames = array();
5075    if (count($labelans) > 0) {
5076        if ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1) {
5077            $labelcode[] = '';
5078            $labelans[] = gT('No answer');
5079            $labels[] = array('answer'=>gT('No answer'), 'code'=>'');
5080        }
5081        if ($aQuestionAttributes['random_order'] == 1) {
5082            $ansquery = "SELECT * FROM {{questions}} WHERE parent_qid=$ia[0] AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' ORDER BY ".dbRandom();
5083        } else {
5084            $ansquery = "SELECT * FROM {{questions}} WHERE parent_qid=$ia[0] AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' ORDER BY question_order";
5085        }
5086        $ansresult = dbExecuteAssoc($ansquery); //Checked
5087        $aQuestions = $ansresult->readAll();
5088        $anscount = count($aQuestions);
5089
5090        $aData = array();
5091        $aData['labelans'] = $labelans;
5092        $aData['labelcode'] = $labelcode;
5093
5094        if ($anscount > 0) {
5095            if (ctype_digit(trim($aQuestionAttributes['answer_width_bycolumn']))) {
5096                $answerwidth = trim($aQuestionAttributes['answer_width_bycolumn']);
5097            } else {
5098                $answerwidth = 33;
5099            }
5100            $cellwidth = (100 - $answerwidth) / $anscount;
5101
5102            $aData['anscount'] = $anscount;
5103            $aData['cellwidth'] = $cellwidth;
5104            $aData['answerwidth'] = $answerwidth;
5105            $aData['aQuestions'] = $aQuestions;
5106
5107            $anscode = [];
5108            $answers = [];
5109            foreach ($aQuestions as $ansrow) {
5110                $anscode[] = $ansrow['title'];
5111                $answers[] = $ansrow['question'];
5112            }
5113
5114            $aData['anscode'] = $anscode;
5115            $aData['answers'] = $answers;
5116
5117            $iAnswerCount = count($answers);
5118            for ($_i = 0; $_i < $iAnswerCount; ++$_i) {
5119                $myfname = $ia[1].$anscode[$_i];
5120                /* Check the Sub Q mandatory violation */
5121                if ($ia[6] == 'Y' && in_array($myfname, $aMandatoryViolationSubQ)) {
5122                    $aData['aQuestions'][$_i]['errormandatory'] = true;
5123                } else {
5124                    $aData['aQuestions'][$_i]['errormandatory'] = false;
5125                }
5126            }
5127
5128            $aData['labels'] = $labels;
5129            $aData['checkconditionFunction'] = $checkconditionFunction;
5130
5131            foreach ($labels as $ansrow) {
5132                foreach ($anscode as $j => $ld) {
5133                    $myfname = $ia[1].$ld;
5134                    $aData['aQuestions'][$j]['myfname'] = $myfname;
5135                    if (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname]) && $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] === $ansrow['code']) {
5136                        $aData['checked'][$ansrow['code']][$ld] = CHECKED;
5137                    } elseif (!isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname]) && $ansrow['code'] == '') {
5138                        $aData['checked'][$ansrow['code']][$ld] = CHECKED;
5139                    // Humm.. (by lemeur), not sure this section can be reached
5140                        // because I think $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] is always set (by save.php ??) !
5141                        // should remove the !isset part I think !!
5142                    } else {
5143                        $aData['checked'][$ansrow['code']][$ld] = "";
5144                    }
5145                }
5146            }
5147
5148            foreach ($anscode as $j => $ld) {
5149                $myfname = $ia[1].$ld;
5150                if (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname])) {
5151                    $aData['aQuestions'][$j]['myfname_value'] = $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname];
5152                } else {
5153                    $aData['aQuestions'][$j]['myfname_value'] = '';
5154                }
5155
5156                $inputnames[] = $myfname;
5157            }
5158            $aData['coreClass'] = $coreClass;
5159            $aData['basename'] = $ia[1];
5160            // Render question
5161            $answer = doRender(
5162                '/survey/questions/answer/arrays/column/answer',
5163                $aData,
5164                true
5165            );
5166        } else {
5167            $answer = '<p class="error">'.gT('Error: There are no answers defined for this question.')."</p>";
5168            $inputnames = "";
5169        }
5170    } else {
5171        $answer = "<p class='error'>".gT("Error: There are no answer options for this question and/or they don't exist in this language.")."</p>\n";
5172        $inputnames = '';
5173    }
5174    return array($answer, $inputnames);
5175}
5176
5177// ---------------------------------------------------------------
5178function do_array_dual($ia)
5179{
5180    global $thissurvey;
5181    $aLastMoveResult            = LimeExpressionManager::GetLastMoveResult();
5182    $aMandatoryViolationSubQ    = ($aLastMoveResult['mandViolation'] && $ia[6] == 'Y') ? explode("|", $aLastMoveResult['unansweredSQs']) : array();
5183    $repeatheadings             = Yii::app()->getConfig("repeatheadings");
5184    $minrepeatheadings          = Yii::app()->getConfig("minrepeatheadings");
5185    $coreClass                  = "ls-answers subquestion-list questions-list";
5186    $answertypeclass            = ""; // Maybe not
5187    $inputnames                 = array();
5188
5189    /*
5190    * Get Question Attributes
5191    */
5192    $aQuestionAttributes = QuestionAttribute::model()->getQuestionAttributes($ia[0]);
5193
5194    // Get questions and answers by defined order
5195    if ($aQuestionAttributes['random_order'] == 1) {
5196        $ansquery = "SELECT * FROM {{questions}} WHERE parent_qid=$ia[0] AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' and scale_id=0 ORDER BY ".dbRandom();
5197    } else {
5198        $ansquery = "SELECT * FROM {{questions}} WHERE parent_qid=$ia[0] AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' and scale_id=0 ORDER BY question_order";
5199    }
5200
5201    $ansresult      = dbExecuteAssoc($ansquery); //Checked
5202    $aSubQuestions  = $ansresult->readAll();
5203    $anscount       = count($aSubQuestions);
5204    $lquery         = "SELECT * FROM {{answers}} WHERE scale_id=0 AND qid={$ia[0]} AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' ORDER BY sortorder, code";
5205    $lresult        = dbExecuteAssoc($lquery); //Checked
5206    $aAnswersScale0 = $lresult->readAll();
5207    $lquery1        = "SELECT * FROM {{answers}} WHERE scale_id=1 AND qid={$ia[0]} AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' ORDER BY sortorder, code";
5208    $lresult1       = dbExecuteAssoc($lquery1); //Checked
5209    $aAnswersScale1 = $lresult1->readAll();
5210
5211    // Set attributes
5212    if ($aQuestionAttributes['use_dropdown'] == 1) {
5213        $useDropdownLayout = true;
5214        $coreClass .= " dropdown-array";
5215        $answertypeclass .= " dropdown";
5216        $doDualScaleFunction = "doDualScaleDropDown"; // javascript funtion to lauch at end of answers
5217    } else {
5218        $useDropdownLayout = false;
5219        $coreClass .= " radio-array";
5220        $answertypeclass .= " radio";
5221        $doDualScaleFunction = "doDualScaleRadio";
5222    }
5223    if (ctype_digit(trim($aQuestionAttributes['repeat_headings'])) && trim($aQuestionAttributes['repeat_headings'] != "")) {
5224        $repeatheadings = intval($aQuestionAttributes['repeat_headings']);
5225        $minrepeatheadings = 0;
5226    }
5227
5228    $leftheader     = (trim($aQuestionAttributes['dualscale_headerA'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']]) != '') ? $aQuestionAttributes['dualscale_headerA'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']] : '';
5229    $rightheader    = (trim($aQuestionAttributes['dualscale_headerB'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']]) != '') ? $aQuestionAttributes['dualscale_headerB'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']] : '';
5230    if (ctype_digit(trim($aQuestionAttributes['answer_width']))) {
5231        $answerwidth = trim($aQuestionAttributes['answer_width']);
5232        $defaultWidth = false;
5233    } else {
5234        $answerwidth = 33;
5235        $defaultWidth = true;
5236    }
5237    // Find if we have rigth and center text
5238    /* All of this part seem broken actually : we don't send it to view and don't explode it */
5239    $sQuery         = "SELECT count(question) FROM {{questions}} WHERE parent_qid=".$ia[0]." and scale_id=0 AND question like '%|%'";
5240    $rigthCount     = Yii::app()->db->createCommand($sQuery)->queryScalar();
5241    $rightexists    = ($rigthCount > 0); // $right_exists: flag to find out if there are any right hand answer parts. leaving right column but don't force with
5242    $sQuery         = "SELECT count(question) FROM {{questions}} WHERE parent_qid=".$ia[0]." and scale_id=0 AND question like '%|%|%'";
5243    $centerCount    = Yii::app()->db->createCommand($sQuery)->queryScalar();
5244    $centerexists   = ($centerCount > 0); // $center_exists: flag to find out if there are any center hand answer parts. leaving center column but don't force with
5245    /* Then always set to false : see bug https://bugs.limesurvey.org/view.php?id=11750 */
5246    //~ $rightexists=false;
5247    //~ $centerexists=false;
5248    // Label and code for input
5249    $labels0 = [];
5250    $labels1 = [];
5251    foreach ($aAnswersScale0 as $lrow) {
5252        $labels0[] = array('code' => $lrow['code'],
5253            'title' => $lrow['answer']);
5254    }
5255    foreach ($aAnswersScale1 as $lrow) {
5256        $labels1[] = array('code' => $lrow['code'],
5257            'title' => $lrow['answer']);
5258    }
5259    if (count($aAnswersScale0) > 0 && $anscount) {
5260        $answer = "";
5261        $fn = 1; // Used by repeat_heading
5262
5263        // No drop-down
5264        if ($useDropdownLayout === false) {
5265            $aData = array();
5266            $aData['coreClass'] = $coreClass;
5267            $aData['basename'] = $ia[1];
5268            $aData['answertypeclass'] = $answertypeclass;
5269
5270            $columnswidth = 100 - $answerwidth;
5271            $labelans0 = array();
5272            $labelans1 = array();
5273            $labelcode0 = array();
5274            $labelcode1 = array();
5275            foreach ($aAnswersScale0 as $lrow) {
5276                $labelans0[] = $lrow['answer'];
5277                $labelcode0[] = $lrow['code'];
5278            }
5279            foreach ($aAnswersScale1 as $lrow) {
5280                $labelans1[] = $lrow['answer'];
5281                $labelcode1[] = $lrow['code'];
5282            }
5283            $numrows = count($labelans0) + count($labelans1);
5284            // Add needed row and fill some boolean: shownoanswer, rightexists, centerexists
5285            $shownoanswer = ($ia[6] != "Y" && SHOW_NO_ANSWER == 1);
5286            if ($shownoanswer) {
5287                $numrows++;
5288            }
5289            /* right and center come from answer => go to answer part*/
5290            $numColExtraAnswer = 0;
5291            $rightwidth = 0;
5292            $separatorwidth = 4;
5293            if ($rightexists) {
5294                $numColExtraAnswer++;
5295            } elseif ($shownoanswer) {
5296                $columnswidth -= 4;
5297                $rightwidth = 4;
5298            }
5299            if ($centerexists) {
5300                $numColExtraAnswer++;
5301            } else {
5302                $columnswidth -= 4;
5303            }
5304            if ($numColExtraAnswer > 0) {
5305                $extraanswerwidth = $answerwidth / $numColExtraAnswer; /* If there are 2 separator : set to 1/2 else to same */
5306                if ($defaultWidth) {
5307                    $columnswidth -= $answerwidth;
5308                } else {
5309                    $answerwidth  = $answerwidth / 2;
5310                }
5311            } else {
5312                $extraanswerwidth = $separatorwidth;
5313            }
5314            $cellwidth = $columnswidth / $numrows;
5315
5316            // Header row and colgroups
5317            $aData['answerwidth'] = $answerwidth;
5318            $aData['cellwidth'] = $cellwidth;
5319            $aData['labelans0'] = $labelans0;
5320            $aData['labelcode0'] = $labelcode0;
5321            $aData['labelans1'] = $labelans1;
5322            $aData['labelcode1'] = $labelcode1;
5323            $aData['separatorwidth'] = $centerexists ? $extraanswerwidth : $separatorwidth;
5324            $aData['shownoanswer'] = $shownoanswer;
5325            $aData['rightexists'] = $rightexists;
5326            $aData['rightwidth'] = $rightexists ? $extraanswerwidth : $rightwidth;
5327
5328            // build first row of header if needed
5329            $aData['leftheader'] = $leftheader;
5330            $aData['rightheader'] = $rightheader;
5331            $aData['rightclass'] = ($rightexists) ? " header_answer_text_right" : "";
5332
5333            // And no each line of body
5334            $trbc = '';
5335            $aData['aSubQuestions'] = $aSubQuestions;
5336            foreach ($aSubQuestions as $i => $ansrow) {
5337
5338                // Build repeat headings if needed
5339                if (isset($repeatheadings) && $repeatheadings > 0 && ($fn - 1) > 0 && ($fn - 1) % $repeatheadings == 0) {
5340                    if (($anscount - $fn + 1) >= $minrepeatheadings) {
5341                        $aData['aSubQuestions'][$i]['repeatheadings'] = true;
5342                    }
5343                } else {
5344                    $aData['aSubQuestions'][$i]['repeatheadings'] = false;
5345                }
5346
5347                $trbc = alternation($trbc, 'row');
5348                $answertext = $ansrow['question'];
5349
5350                // right and center answertext: not explode for ? Why not
5351                if (strpos($answertext, '|') !== false) {
5352                    $answertextright = (string) substr($answertext, strpos($answertext, '|') + 1);
5353                    $answertext = (string) substr($answertext, 0, strpos($answertext, '|'));
5354                } else {
5355                    $answertextright = "";
5356                }
5357                if (strpos($answertextright, '|')) {
5358                    $answertextcenter = (string) substr($answertextright, 0, strpos($answertextright, '|'));
5359                    $answertextright = (string) substr($answertextright, strpos($answertextright, '|') + 1);
5360                } else {
5361                    $answertextcenter = "";
5362                }
5363
5364                $myfname = $ia[1].$ansrow['title'];
5365                $myfname0 = $ia[1].$ansrow['title'].'#0';
5366                $myfid0 = $ia[1].$ansrow['title'].'_0';
5367                $myfname1 = $ia[1].$ansrow['title'].'#1'; // new multi-scale-answer
5368                $myfid1 = $ia[1].$ansrow['title'].'_1';
5369                $aData['aSubQuestions'][$i]['myfname'] = $myfname;
5370                $aData['aSubQuestions'][$i]['myfname0'] = $myfname0;
5371                $aData['aSubQuestions'][$i]['myfid0'] = $myfid0;
5372                $aData['aSubQuestions'][$i]['myfname1'] = $myfname1;
5373                $aData['aSubQuestions'][$i]['myfid1'] = $myfid1;
5374
5375                $aData['aSubQuestions'][$i]['answertext'] = $answertext;
5376                $aData['aSubQuestions'][$i]['answertextcenter'] = $answertextcenter;
5377                $aData['aSubQuestions'][$i]['answertextright'] = $answertextright;
5378
5379                $aData['aSubQuestions'][$i]['odd'] = ($i % 2);
5380                // Check the Sub Q mandatory violation
5381                if ($ia[6] == 'Y' && (in_array($myfname0, $aMandatoryViolationSubQ) || in_array($myfname1, $aMandatoryViolationSubQ))) {
5382                    $aData['aSubQuestions'][$i]['showmandatoryviolation'] = true;
5383                } else {
5384                    $aData['aSubQuestions'][$i]['showmandatoryviolation'] = false;
5385                }
5386
5387                // Get array_filter stuff
5388                $aData['aSubQuestions'][$i]['sDisplayStyle'] = return_display_style($ia, $aQuestionAttributes, $thissurvey, $myfname);
5389                array_push($inputnames, $myfname0);
5390
5391                if (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname0])) {
5392                    $aData['aSubQuestions'][$i]['sessionfname0'] = $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname0];
5393                } else {
5394                    $aData['aSubQuestions'][$i]['sessionfname0'] = '';
5395                }
5396
5397                if (count($labelans1) > 0) {
5398                    // if second label set is used
5399                    if (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname1])) {
5400                        //$answer .= $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname1];
5401                        $aData['aSubQuestions'][$i]['sessionfname1'] = $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname1];
5402                    } else {
5403                        $aData['aSubQuestions'][$i]['sessionfname1'] = '';
5404                    }
5405                }
5406
5407                foreach ($labelcode0 as $j => $ld) {
5408                    // First label set
5409                    if (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname0]) && $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname0] == $ld) {
5410                        $aData['labelcode0_checked'][$ansrow['title']][$ld] = CHECKED;
5411                    } else {
5412                        $aData['labelcode0_checked'][$ansrow['title']][$ld] = "";
5413                    }
5414                }
5415
5416                if (count($labelans1) > 0) {
5417                    // if second label set is used
5418                    if ($shownoanswer) {
5419                        // No answer for accessibility and no javascript (but hide hide even with no js: need reworking)
5420                        if (!isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname0]) || $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname0] == "") {
5421                            $answer .= CHECKED;
5422                            $aData['myfname0_notset'] = CHECKED;
5423                        } else {
5424                            $aData['myfname0_notset'] = "";
5425                        }
5426                    }
5427
5428                    array_push($inputnames, $myfname1);
5429
5430                    foreach ($labelcode1 as $j => $ld) {
5431                        // second label set
5432                        if (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname1]) && $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname1] == $ld) {
5433                            $aData['labelcode1_checked'][$ansrow['title']][$ld] = CHECKED;
5434                        } else {
5435                            $aData['labelcode1_checked'][$ansrow['title']][$ld] = "";
5436                        }
5437                    }
5438                }
5439                $aData['answertextright'] = $answertextright;
5440                if ($shownoanswer) {
5441                    if (count($labelans1) > 0) {
5442                        if (!isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname1]) || $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname1] == "") {
5443                            $answer .= CHECKED;
5444                            $aData['myfname1_notset'] = CHECKED;
5445                        } else {
5446                            $aData['myfname1_notset'] = "";
5447                        }
5448                    } else {
5449                        if (!isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname0]) || $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname0] == "") {
5450                            $answer .= CHECKED;
5451                            $aData['myfname0_notset'] = CHECKED;
5452                        } else {
5453                            $aData['myfname0_notset'] = '';
5454                        }
5455                    }
5456                }
5457                $fn++;
5458            }
5459
5460            $answer = doRender(
5461                '/survey/questions/answer/arrays/dualscale/answer',
5462                $aData,
5463                true
5464            );
5465        }
5466
5467        // Dropdown Layout
5468        elseif ($useDropdownLayout === true) {
5469            $aData = array();
5470            $aData['coreClass'] = $coreClass;
5471            $aData['basename'] = $ia[1];
5472
5473            // Get attributes for Headers and Prefix/Suffix
5474            if (trim($aQuestionAttributes['dropdown_prepostfix'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']]) != '') {
5475                list($ddprefix, $ddsuffix) = explode("|", $aQuestionAttributes['dropdown_prepostfix'][$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']]);
5476            } else {
5477                $ddprefix = null;
5478                $ddsuffix = null;
5479            }
5480            if (trim($aQuestionAttributes['dropdown_separators']) != '') {
5481                $aSeparator = explode('|', $aQuestionAttributes['dropdown_separators']);
5482                if (isset($aSeparator[1])) {
5483                    $interddSep = $aSeparator[1];
5484                } else {
5485                    $interddSep = $aSeparator[0];
5486                }
5487            } else {
5488                $interddSep = '';
5489            }
5490            if ($interddSep) {
5491                $separatorwidth = 8;
5492            } else {
5493                $separatorwidth = 4;
5494            }
5495            $cellwidth = (100 - $answerwidth - $separatorwidth) / 2;
5496            $aData['answerwidth'] = $answerwidth;
5497            $aData['ddprefix'] = $ddprefix;
5498            $aData['ddsuffix'] = $ddsuffix;
5499            $aData['cellwidth'] = $cellwidth;
5500
5501            $aData['separatorwidth'] = $separatorwidth;
5502
5503            $aData['leftheader'] = $leftheader;
5504            $aData['rightheader'] = $rightheader;
5505
5506            $aData['aSubQuestions'] = $aSubQuestions;
5507            foreach ($aSubQuestions as $i => $ansrow) {
5508                $myfname = $ia[1].$ansrow['title'];
5509                $myfname0 = $ia[1].$ansrow['title']."#0";
5510                $myfid0 = $ia[1].$ansrow['title']."_0";
5511                $myfname1 = $ia[1].$ansrow['title']."#1";
5512                $myfid1 = $ia[1].$ansrow['title']."_1";
5513                $sActualAnswer0 = isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname0]) ? $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname0] : "";
5514                $sActualAnswer1 = isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname1]) ? $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname1] : "";
5515
5516                $aData['aSubQuestions'][$i]['myfname'] = $myfname;
5517                $aData['aSubQuestions'][$i]['myfname0'] = $myfname0;
5518                $aData['aSubQuestions'][$i]['myfid0'] = $myfid0;
5519                $aData['aSubQuestions'][$i]['myfname1'] = $myfname1;
5520                $aData['aSubQuestions'][$i]['myfid1'] = $myfid1;
5521                $aData['aSubQuestions'][$i]['sActualAnswer0'] = $sActualAnswer0;
5522                $aData['aSubQuestions'][$i]['sActualAnswer1'] = $sActualAnswer1;
5523                $aData['aSubQuestions'][$i]['odd'] = ($i % 2);
5524                // Set mandatory alert
5525                $aData['aSubQuestions'][$i]['alert'] = ($ia[6] == 'Y' && (in_array($myfname0, $aMandatoryViolationSubQ) || in_array($myfname1, $aMandatoryViolationSubQ)));
5526                $aData['aSubQuestions'][$i]['mandatoryviolation'] = ($ia[6] == 'Y' && (in_array($myfname0, $aMandatoryViolationSubQ) || in_array($myfname1, $aMandatoryViolationSubQ)));
5527                // Array filter : maybe leave EM do the trick
5528                $aData['aSubQuestions'][$i]['sDisplayStyle'] = return_display_style($ia, $aQuestionAttributes, $thissurvey, $myfname);
5529
5530                //~ list($htmltbody2, $hiddenfield)=return_array_filter_strings($ia, $aQuestionAttributes, $thissurvey, $ansrow, $myfname, $trbc, $myfname,"tr","$trbc subquestion-list questions-list dropdown-list");
5531                //~ $aData['aSubQuestions'][$i]['htmltbody2'] = $htmltbody2;
5532                //~ $aData['aSubQuestions'][$i]['hiddenfield'] = $hiddenfield;
5533                $aData['labels0'] = $labels0;
5534                $aData['labels1'] = $labels1;
5535                $aData['aSubQuestions'][$i]['showNoAnswer0'] = ($sActualAnswer0 != '' && $ia[6] != 'Y' && SHOW_NO_ANSWER);
5536                $aData['aSubQuestions'][$i]['showNoAnswer1'] = ($sActualAnswer1 != '' && $ia[6] != 'Y' && SHOW_NO_ANSWER);
5537                $aData['interddSep'] = $interddSep;
5538
5539                $inputnames[] = $myfname0;
5540
5541                $inputnames[] = $myfname1;
5542            }
5543
5544            $answer = doRender(
5545                '/survey/questions/answer/arrays/dualscale/answer_dropdown',
5546                $aData,
5547                true
5548            );
5549        }
5550    } else {
5551        $answer = "<p class='error'>".gT("Error: There are no answer options for this question and/or they don't exist in this language.")."</p>\n";
5552        $inputnames = "";
5553    }
5554    if (!Yii::app()->getClientScript()->isScriptFileRegistered(Yii::app()->getConfig('generalscripts')."dualscale.js", LSYii_ClientScript::POS_BEGIN)) {
5555        Yii::app()->getClientScript()->registerScriptFile(Yii::app()->getConfig('generalscripts')."dualscale.js", LSYii_ClientScript::POS_BEGIN);
5556    }
5557    Yii::app()->getClientScript()->registerScript('doDualScaleFunction'.$ia[0], "{$doDualScaleFunction}({$ia[0]});", LSYii_ClientScript::POS_POSTSCRIPT);
5558    return array($answer, $inputnames);
5559}
5560
5561/**
5562* Find the label / input width
5563* @param string|int $labelAttributeWidth label width from attribute
5564* @param string|int $inputAttributeWidth input width from attribute
5565* @return array labelWidth as integer,inputWidth as integer,defaultWidth as boolean
5566*/
5567function getLabelInputWidth($labelAttributeWidth, $inputAttributeWidth)
5568{
5569    $attributeInputContainerWidth = intval(trim($inputAttributeWidth));
5570    if ($attributeInputContainerWidth < 1 || $attributeInputContainerWidth > 12) {
5571        $attributeInputContainerWidth = null;
5572    }
5573
5574    $attributeLabelWidth = trim($labelAttributeWidth);
5575    if ($attributeLabelWidth === 'hidden') {
5576        $attributeLabelWidth = 0;
5577    } else {
5578        $attributeLabelWidth = intval($attributeLabelWidth);
5579        if ($attributeLabelWidth < 1 || $attributeLabelWidth > 12) {
5580            /* old system or imported or '' */
5581            $attributeLabelWidth = null;
5582        }
5583    }
5584    if ($attributeInputContainerWidth === null && $attributeLabelWidth === null) {
5585        $sInputContainerWidth = 8;
5586        $sLabelWidth = 4;
5587        $defaultWidth = true;
5588    } else {
5589        if ($attributeInputContainerWidth !== null) {
5590            $sInputContainerWidth = $attributeInputContainerWidth;
5591        } elseif ($attributeLabelWidth == 12) {
5592            $sInputContainerWidth = 12;
5593        } else {
5594            $sInputContainerWidth = 12 - $attributeLabelWidth;
5595        }
5596        if (!is_null($attributeLabelWidth)) {
5597            $sLabelWidth = $attributeLabelWidth;
5598        } elseif ($attributeInputContainerWidth == 12) {
5599            $sLabelWidth = 12;
5600        } else {
5601            $sLabelWidth = 12 - $attributeInputContainerWidth;
5602        }
5603        $defaultWidth = false;
5604    }
5605    return array(
5606        $sLabelWidth,
5607        $sInputContainerWidth,
5608        $defaultWidth,
5609    );
5610}
5611
5612/**
5613* Take a date string and fill out missing parts, like day, hour, minutes
5614* (not seconds).
5615* If string is NOT in standard date format (Y-m-d H:i), this methods makes no
5616* sense.
5617* Used when fetching answer for do_date, where answer can come from a default
5618* answer expression like date('Y').
5619* Will also truncate date('c') to format Y-m-d H:i.
5620* @param string $dateString
5621* @return string
5622*/
5623function fillDate($dateString)
5624{
5625    switch (strlen($dateString)) {
5626        // Only year
5627        case 4:
5628            return $dateString.'-01-01 00:00';
5629            // Year and month
5630        case 7:
5631            return $dateString.'-01 00:00';
5632            // Year, month and day
5633        case 10:
5634            return $dateString.' 00:00';
5635            // Year, month day and hour
5636        case 13:
5637            return $dateString.':00';
5638            // Complete, return as is.
5639        case 16:
5640            return $dateString;
5641        case 19:
5642        case 21: // Y-m-d H:i.s.n (n==1)
5643        case 22: // Y-m-d H:i.s.n (n==2)
5644        case 23: // mssql Y-m-d H:i.s.n (n==3)
5645        case 24: // Y-m-d H:i.s.n (n==4)
5646        case 25: // Assume date('c')
5647            $date = new DateTime($dateString);
5648            if ($date) {
5649                return $date->format('Y-m-d H:i');
5650            }
5651            // no break
5652        default:
5653            return '';
5654    }
5655}
5656
5657/**
5658* Render the question view.
5659*
5660* By default, it just renders the required core view from application/views/survey/...
5661* If user added a question template in the upload dirctory, add applied it to the question in its display settings, then the function will check if the required view exist in this directory
5662* and then will use this one to render the question.
5663*
5664* Rem: all the logic has been moved to LSETwigViewRenderer::renderQuestion()
5665* We keep the function doRender here for convenience (it will probably be removed in further cycles of dev).
5666**
5667* @param string    $sView      name of the view to be rendered.
5668* @param array     $aData      data to be extracted into PHP variables and made available to the view script
5669* @param boolean   $bReturn    whether the rendering result should be returned instead of being displayed to end users (should be always true)
5670*/
5671function doRender($sView, $aData, $bReturn = true)
5672{
5673    return App()->twigRenderer->renderQuestion($sView, $aData);
5674}
5675