コード例 #1
0
 /**
  * Create HTML view of the survey, showing everything that uses EM
  * @param <type> $sid
  * @param <type> $gid
  * @param <type> $qid
  */
 public static function ShowSurveyLogicFile($sid, $gid = NULL, $qid = NULL, $LEMdebugLevel = 0, $assessments = false)
 {
     // Title
     // Welcome
     // G1, name, relevance, text
     // *Q1, name [type], relevance [validation], text, help, default, help_msg
     // SQ1, name [scale], relevance [validation], text
     // A1, code, assessment_value, text
     // End Message
     $LEM =& LimeExpressionManager::singleton();
     $LEM->sPreviewMode = 'logic';
     $aSurveyInfo = getSurveyInfo($sid, $_SESSION['LEMlang']);
     $allErrors = array();
     $warnings = 0;
     $surveyOptions = array('assessments' => $aSurveyInfo['assessments'] == 'Y', 'hyperlinkSyntaxHighlighting' => true);
     $varNamesUsed = array();
     // keeps track of whether variables have been declared
     if (!is_null($qid)) {
         $surveyMode = 'question';
         LimeExpressionManager::StartSurvey($sid, 'question', $surveyOptions, false, $LEMdebugLevel);
         $qseq = LimeExpressionManager::GetQuestionSeq($qid);
         $moveResult = LimeExpressionManager::JumpTo($qseq + 1, true, false, true);
     } else {
         if (!is_null($gid)) {
             $surveyMode = 'group';
             LimeExpressionManager::StartSurvey($sid, 'group', $surveyOptions, false, $LEMdebugLevel);
             $gseq = LimeExpressionManager::GetGroupSeq($gid);
             $moveResult = LimeExpressionManager::JumpTo($gseq + 1, true, false, true);
         } else {
             $surveyMode = 'survey';
             LimeExpressionManager::StartSurvey($sid, 'survey', $surveyOptions, false, $LEMdebugLevel);
             $moveResult = LimeExpressionManager::NavigateForwards();
         }
     }
     $qtypes = getQuestionTypeList('', 'array');
     if (is_null($moveResult) || is_null($LEM->currentQset) || count($LEM->currentQset) == 0) {
         return array('errors' => 1, 'html' => sprintf($LEM->gT('Invalid question - probably missing sub-questions or language-specific settings for language %s'), $_SESSION['LEMlang']));
     }
     $surveyname = viewHelper::stripTagsEM(templatereplace('{SURVEYNAME}', array('SURVEYNAME' => $aSurveyInfo['surveyls_title'])));
     $out = '<div id="showlogicfilediv" class="table-responsive"><h3>' . $LEM->gT('Logic File for Survey # ') . '[' . $LEM->sid . "]: {$surveyname}</h3>\n";
     $out .= "<table id='logicfiletable' class='table table-bordered'>";
     if (is_null($gid) && is_null($qid)) {
         if ($aSurveyInfo['surveyls_description'] != '') {
             $LEM->ProcessString($aSurveyInfo['surveyls_description'], 0);
             $sPrint = viewHelper::purified(viewHelper::filterScript($LEM->GetLastPrettyPrintExpression()));
             $errClass = $LEM->em->HasErrors() ? 'danger' : '';
             $out .= "<tr class='LEMgroup {$errClass}'><td colspan=2>" . $LEM->gT("Description:") . "</td><td colspan=2>" . $sPrint . "</td></tr>";
         }
         if ($aSurveyInfo['surveyls_welcometext'] != '') {
             $LEM->ProcessString($aSurveyInfo['surveyls_welcometext'], 0);
             $sPrint = viewHelper::purified(viewHelper::filterScript($LEM->GetLastPrettyPrintExpression()));
             $errClass = $LEM->em->HasErrors() ? 'danger' : '';
             $out .= "<tr class='LEMgroup {$errClass}'><td colspan=2>" . $LEM->gT("Welcome:") . "</td><td colspan=2>" . $sPrint . "</td></tr>";
         }
         if ($aSurveyInfo['surveyls_endtext'] != '') {
             $LEM->ProcessString($aSurveyInfo['surveyls_endtext']);
             $sPrint = viewHelper::purified(viewHelper::filterScript($LEM->GetLastPrettyPrintExpression()));
             $errClass = $LEM->em->HasErrors() ? 'danger' : '';
             $out .= "<tr class='LEMgroup {$errClass}'><td colspan=2>" . $LEM->gT("End message:") . "</td><td colspan=2>" . $sPrint . "</td></tr>";
         }
         if ($aSurveyInfo['surveyls_url'] != '') {
             $LEM->ProcessString($aSurveyInfo['surveyls_urldescription'] . " - " . $aSurveyInfo['surveyls_url']);
             $sPrint = viewHelper::purified($LEM->GetLastPrettyPrintExpression());
             $errClass = $LEM->em->HasErrors() ? 'danger' : '';
             $out .= "<tr class='LEMgroup {$errClass}'><td colspan=2>" . $LEM->gT("End URL:") . "</td><td colspan=2>" . $sPrint . "</td></tr>";
         }
     }
     $out .= "<tr><th>#</th><th>" . $LEM->gT('Name [ID]') . "</th><th>" . $LEM->gT('Relevance [Validation] (Default value)') . "</th><th>" . $LEM->gT('Text [Help] (Tip)') . "</th></tr>\n";
     $_gseq = -1;
     foreach ($LEM->currentQset as $q) {
         $gseq = $q['info']['gseq'];
         $gid = $q['info']['gid'];
         $qid = $q['info']['qid'];
         $qseq = $q['info']['qseq'];
         $errorCount = 0;
         //////
         // SHOW GROUP-LEVEL INFO
         //////
         if ($gseq != $_gseq) {
             $bGroupHaveError = false;
             $errClass = '';
             $LEM->ParseResultCache = array();
             // reset for each group so get proper color coding?
             $_gseq = $gseq;
             $ginfo = $LEM->gseq2info[$gseq];
             $sGroupRelevance = '{' . ($ginfo['grelevance'] == '' ? 1 : $ginfo['grelevance']) . '}';
             $LEM->ProcessString($sGroupRelevance, $qid, NULL, false, 1, 1, false, false);
             $bGroupHaveError = $bGroupHaveError || $LEM->em->HasErrors();
             $sGroupRelevance = viewHelper::stripTagsEM($LEM->GetLastPrettyPrintExpression());
             $sGroupText = trim($ginfo['description']) == '' ? '&nbsp;' : $ginfo['description'];
             $LEM->ProcessString($sGroupText, $qid, NULL, false, 1, 1, false, false);
             $bGroupHaveError = $bGroupHaveError || $LEM->em->HasErrors();
             $sGroupText = viewHelper::purified(viewHelper::filterScript($LEM->GetLastPrettyPrintExpression()));
             $editlink = Yii::app()->getController()->createUrl('admin/survey/sa/view/surveyid/' . $LEM->sid . '/gid/' . $gid);
             if ($bGroupHaveError) {
                 $errClass = 'text-danger';
             }
             $groupRow = "<tr class='LEMgroup'>" . "<td class='{$errClass}'>G-{$gseq}</td>" . "<td><b>" . $ginfo['group_name'] . "</b><br />[<a target='_blank' href='{$editlink}'>GID " . $gid . "</a>]</td>" . "<td>" . $sGroupRelevance . "</td>" . "<td>" . $sGroupText . "</td>" . "</tr>\n";
             $out .= $groupRow;
         }
         //////
         // SHOW QUESTION-LEVEL INFO
         //////
         $mandatory = $q['info']['mandatory'] == 'Y' ? "<span class='mandatory'>*</span>" : '';
         $type = $q['info']['type'];
         $typedesc = $qtypes[$type]['description'];
         $sgqas = explode('|', $q['sgqa']);
         if (count($sgqas) == 1 && !is_null($q['info']['default'])) {
             $LEM->ProcessString($q['info']['default'], $qid, NULL, false, 1, 1, false, false);
             // Default value is Y or answer code or go to input/textarea, then we can filter it
             $_default = viewHelper::stripTagsEM($LEM->GetLastPrettyPrintExpression());
             if ($LEM->em->HasErrors()) {
                 ++$errorCount;
             }
             $default = '<br />(' . $LEM->gT('Default:') . '  ' . $_default . ')';
         } else {
             $default = '';
         }
         $sQuestionText = $q['info']['qtext'] != '' ? $q['info']['qtext'] : '&nbsp';
         $LEM->ProcessString($sQuestionText, $qid, NULL, false, 1, 1, false, false);
         $sQuestionText = viewHelper::purified(viewHelper::filterScript($LEM->GetLastPrettyPrintExpression()));
         if ($LEM->em->HasErrors()) {
             ++$errorCount;
         }
         $sQuestionHelp = "";
         if (trim($q['info']['help']) != "") {
             $sQuestionHelp = $q['info']['help'];
             $LEM->ProcessString($sQuestionHelp, $qid, NULL, false, 1, 1, false, false);
             $sQuestionHelp = viewHelper::purified(viewHelper::filterScript($LEM->GetLastPrettyPrintExpression()));
             if ($LEM->em->HasErrors()) {
                 ++$errorCount;
             }
             $sQuestionHelp = '<hr/>[' . $LEM->gT("Help:") . ' ' . $sQuestionHelp . ']';
         }
         $prettyValidTip = $q['prettyValidTip'] == '' ? '' : '<hr/>(' . $LEM->gT("Tip:") . ' ' . viewHelper::stripTagsEM($q['prettyValidTip']) . ')';
         // Unsure need to filter
         //////
         // SHOW QUESTION ATTRIBUTES THAT ARE PROCESSED BY EM
         //////
         $attrTable = '';
         $attrs = isset($LEM->qattr[$qid]) ? $LEM->qattr[$qid] : array();
         if (isset($LEM->q2subqInfo[$qid]['preg'])) {
             $attrs['regex_validation'] = $LEM->q2subqInfo[$qid]['preg'];
         }
         if (isset($LEM->questionSeq2relevance[$qseq]['other'])) {
             $attrs['other'] = $LEM->questionSeq2relevance[$qseq]['other'];
         }
         if (count($attrs) > 0) {
             $attrTable = "<table id='logicfileattributetable'><tr><th>" . $LEM->gT("Question attribute") . "</th><th>" . $LEM->gT("Value") . "</th></tr>\n";
             $count = 0;
             foreach ($attrs as $key => $value) {
                 if (is_null($value) || trim($value) == '') {
                     continue;
                 }
                 switch ($key) {
                     // @todo: Rather compares the current attribute value to the defaults in the question attributes array to decide which ones should show (only the ones that are non-standard)
                     default:
                     case 'exclude_all_others':
                     case 'exclude_all_others_auto':
                     case 'hidden':
                         if ($value == false || $value == '0') {
                             $value = NULL;
                             // so can skip this one - just using continue here doesn't work.
                         }
                         break;
                     case 'time_limit_action':
                         if ($value == '1') {
                             $value = NULL;
                             // so can skip this one - just using continue here doesn't work.
                         }
                     case 'relevance':
                         $value = NULL;
                         // means an outdate database structure
                         break;
                     case 'array_filter':
                     case 'array_filter_exclude':
                     case 'code_filter':
                     case 'date_max':
                     case 'date_min':
                     case 'em_validation_q_tip':
                     case 'em_validation_sq_tip':
                         break;
                     case 'equals_num_value':
                     case 'em_validation_q':
                     case 'em_validation_sq':
                     case 'max_answers':
                     case 'max_num_value':
                     case 'max_num_value_n':
                     case 'min_answers':
                     case 'min_num_value':
                     case 'min_num_value_n':
                     case 'min_num_of_files':
                     case 'max_num_of_files':
                     case 'multiflexible_max':
                     case 'multiflexible_min':
                     case 'slider_accuracy':
                     case 'slider_min':
                     case 'slider_max':
                     case 'slider_default':
                         $value = '{' . $value . '}';
                         $LEM->ProcessString($value, $qid, NULL, false, 1, 1, false, false);
                         $value = viewHelper::stripTagsEM($LEM->GetLastPrettyPrintExpression());
                         if ($LEM->em->HasErrors()) {
                             ++$errorCount;
                         }
                         break;
                     case 'other_replace_text':
                     case 'show_totals':
                     case 'regex_validation':
                         break;
                     case 'other':
                         if ($value == 'N') {
                             $value = NULL;
                             // so can skip this one
                         }
                         break;
                 }
                 if (is_null($value)) {
                     continue;
                     // since continuing from within a switch statement doesn't work
                 }
                 ++$count;
                 $attrTable .= "<tr><td>{$key}</td><td>{$value}</td></tr>\n";
             }
             $attrTable .= "</table>\n";
             if ($count == 0) {
                 $attrTable = '';
             }
         }
         $qdetails = $sQuestionText . $sQuestionHelp . $prettyValidTip . $attrTable;
         //////
         // SHOW RELEVANCE
         //////
         // Must parse Relevance this way, otherwise if try to first split expressions, regex equations won't work
         $relevanceEqn = $q['info']['relevance'] == '' ? 1 : $q['info']['relevance'];
         if (!isset($LEM->ParseResultCache[$relevanceEqn])) {
             $result = $LEM->em->ProcessBooleanExpression($relevanceEqn, $gseq, $qseq);
             $prettyPrint = viewHelper::stripTagsEM($LEM->em->GetPrettyPrintString());
             $hasErrors = $LEM->em->HasErrors();
             $LEM->ParseResultCache[$relevanceEqn] = array('result' => $result, 'prettyprint' => $prettyPrint, 'hasErrors' => $hasErrors);
         }
         $relevance = $LEM->ParseResultCache[$relevanceEqn]['prettyprint'];
         if ($LEM->ParseResultCache[$relevanceEqn]['hasErrors']) {
             ++$errorCount;
         }
         //////
         // SHOW VALIDATION EQUATION
         //////
         // Must parse Validation this way so that regex (preg) works
         $prettyValidEqn = '';
         if ($q['prettyValidEqn'] != '') {
             $validationEqn = $q['validEqn'];
             if (!isset($LEM->ParseResultCache[$validationEqn])) {
                 $result = $LEM->em->ProcessBooleanExpression($validationEqn, $gseq, $qseq);
                 $prettyPrint = viewHelper::stripTagsEM($LEM->em->GetPrettyPrintString());
                 $hasErrors = $LEM->em->HasErrors();
                 $LEM->ParseResultCache[$validationEqn] = array('result' => $result, 'prettyprint' => $prettyPrint, 'hasErrors' => $hasErrors);
             }
             $prettyValidEqn = '<hr/>(VALIDATION: ' . $LEM->ParseResultCache[$validationEqn]['prettyprint'] . ')';
             if ($LEM->ParseResultCache[$validationEqn]['hasErrors']) {
                 ++$errorCount;
             }
         }
         //////
         // TEST VALIDITY OF ROOT VARIABLE NAME AND WHETHER HAS BEEN USED
         //////
         $rootVarName = $q['info']['rootVarName'];
         $varNameErrorMsg = '';
         $varNameError = NULL;
         if (isset($varNamesUsed[$rootVarName])) {
             $varNameErrorMsg .= $LEM->gT('This variable name has already been used.');
         } else {
             $varNamesUsed[$rootVarName] = array('gseq' => $gseq, 'qid' => $qid);
         }
         if (!preg_match('/^[a-zA-Z][0-9a-zA-Z]*$/', $rootVarName)) {
             $varNameErrorMsg .= $LEM->gT('Starting in 2.05, variable names should only contain letters and numbers; and may not start with a number. This variable name is deprecated.');
         }
         if ($varNameErrorMsg != '') {
             $varNameError = array('message' => $varNameErrorMsg, 'gseq' => $varNamesUsed[$rootVarName]['gseq'], 'qid' => $varNamesUsed[$rootVarName]['qid'], 'gid' => $gid);
             if (!$LEM->sgqaNaming) {
                 ++$errorCount;
             } else {
                 ++$warnings;
             }
         }
         //////
         // SHOW ALL SUB-QUESTIONS
         //////
         $sqRows = '';
         $i = 0;
         $sawThis = array();
         // array of rowdivids already seen so only show them once
         foreach ($sgqas as $sgqa) {
             $bSubQhasError = false;
             if ($LEM->knownVars[$sgqa]['qcode'] == $rootVarName) {
                 continue;
                 // so don't show the main question as a sub-question too
             }
             $rowdivid = $sgqa;
             $varName = $LEM->knownVars[$sgqa]['qcode'];
             switch ($q['info']['type']) {
                 case '1':
                     if (preg_match('/#1$/', $sgqa)) {
                         $rowdivid = NULL;
                         // so that doesn't show same message for second scale
                     } else {
                         $rowdivid = substr($sgqa, 0, -2);
                         // strip suffix
                         $varName = substr($LEM->knownVars[$sgqa]['qcode'], 0, -2);
                     }
                     break;
                 case 'P':
                     if (preg_match('/comment$/', $sgqa)) {
                         $rowdivid = NULL;
                     }
                     break;
                 case ':':
                 case ';':
                     $_rowdivid = $LEM->knownVars[$sgqa]['rowdivid'];
                     if (isset($sawThis[$qid . '~' . $_rowdivid])) {
                         $rowdivid = NULL;
                         // so don't show again
                     } else {
                         $sawThis[$qid . '~' . $_rowdivid] = true;
                         $rowdivid = $_rowdivid;
                         $sgqa_len = strlen($sid . 'X' . $gid . 'X' . $qid);
                         $varName = $rootVarName . '_' . substr($_rowdivid, $sgqa_len);
                     }
             }
             if (is_null($rowdivid)) {
                 continue;
             }
             ++$i;
             $subQeqn = '&nbsp;';
             if (isset($LEM->subQrelInfo[$qid][$rowdivid])) {
                 $sq = $LEM->subQrelInfo[$qid][$rowdivid];
                 $subQeqn = viewHelper::stripTagsEM($sq['prettyPrintEqn']);
                 // {' . $sq['eqn'] . '}';  // $sq['prettyPrintEqn'];
                 if ($sq['hasErrors']) {
                     ++$errorCount;
                 }
             }
             $sgqaInfo = $LEM->knownVars[$sgqa];
             $subqText = $sgqaInfo['subqtext'];
             $LEM->ProcessString($subqText, $qid, NULL, false, 1, 1, false, false);
             $subqText = viewHelper::purified(viewHelper::filterScript($LEM->GetLastPrettyPrintExpression()));
             if ($LEM->em->HasErrors()) {
                 ++$errorCount;
             }
             if (isset($sgqaInfo['default']) && $sgqaInfo['default'] !== '') {
                 $LEM->ProcessString($sgqaInfo['default'], $qid, NULL, false, 1, 1, false, false);
                 $_default = viewHelper::stripTagsEM($LEM->GetLastPrettyPrintExpression());
                 if ($LEM->em->HasErrors()) {
                     ++$errorCount;
                 }
                 $subQeqn .= '<br />(' . $LEM->gT('Default:') . '  ' . $_default . ')';
             }
             $sqRows .= "<tr class='LEMsubq'>" . "<td>SQ-{$i}</td>" . "<td><b>" . $varName . "</b></td>" . "<td>{$subQeqn}</td>" . "<td>" . $subqText . "</td>" . "</tr>";
         }
         //////
         // SHOW ANSWER OPTIONS FOR ENUMERATED LISTS, AND FOR MULTIFLEXI
         //////
         $answerRows = '';
         if (isset($LEM->qans[$qid]) || isset($LEM->multiflexiAnswers[$qid])) {
             $_scale = -1;
             if (isset($LEM->multiflexiAnswers[$qid])) {
                 $ansList = $LEM->multiflexiAnswers[$qid];
             } else {
                 $ansList = $LEM->qans[$qid];
             }
             foreach ($ansList as $ans => $value) {
                 $ansInfo = explode('~', $ans);
                 $valParts = explode('|', $value);
                 $valInfo[0] = array_shift($valParts);
                 $valInfo[1] = implode('|', $valParts);
                 if ($_scale != $ansInfo[0]) {
                     $i = 1;
                     $_scale = $ansInfo[0];
                 }
                 $subQeqn = '';
                 $rowdivid = $sgqas[0] . $ansInfo[1];
                 if ($q['info']['type'] == 'R') {
                     $rowdivid = $LEM->sid . 'X' . $gid . 'X' . $qid . $ansInfo[1];
                 }
                 if (isset($LEM->subQrelInfo[$qid][$rowdivid])) {
                     $sq = $LEM->subQrelInfo[$qid][$rowdivid];
                     $subQeqn = ' ' . viewHelper::stripTagsEM($sq['prettyPrintEqn']);
                     if ($sq['hasErrors']) {
                         ++$errorCount;
                     }
                 }
                 $sAnswerText = $valInfo[1];
                 $LEM->ProcessString($sAnswerText, $qid, NULL, false, 1, 1, false, false);
                 $sAnswerText = viewHelper::purified(viewHelper::filterScript($LEM->GetLastPrettyPrintExpression()));
                 if ($LEM->em->HasErrors()) {
                     ++$errorCount;
                 }
                 $answerRows .= "<tr class='LEManswer'>" . "<td>A[" . $ansInfo[0] . "]-" . $i++ . "</td>" . "<td><b>" . $ansInfo[1] . "</b></td>" . "<td>[VALUE: " . $valInfo[0] . "]" . $subQeqn . "</td>" . "<td>" . $sAnswerText . "</td>" . "</tr>\n";
             }
         }
         //////
         // FINALLY, SHOW THE QUESTION ROW(S), COLOR-CODING QUESTIONS THAT CONTAIN ERRORS
         //////
         $errclass = $errorCount > 0 ? 'danger' : '';
         $errText = $errorCount > 0 ? "<br><em class='label label-danger'>" . $LEM->ngT("This question has at least {n} error.|This question has at least {n} errors.", $errorCount) . "<em>" : "";
         $questionRow = "<tr class='LEMquestion'>" . "<td class='{$errclass}'>Q-" . $q['info']['qseq'] . "</td>" . "<td><b>" . $mandatory;
         if ($varNameErrorMsg == '') {
             $editlink = Yii::app()->getController()->createUrl('admin/survey/sa/view/surveyid/' . $sid . '/gid/' . $gid . '/qid/' . $qid);
             $questionRow .= $rootVarName;
         } else {
             $editlink = Yii::app()->getController()->createUrl('admin/survey/sa/view/surveyid/' . $LEM->sid . '/gid/' . $varNameError['gid'] . '/qid/' . $varNameError['qid']);
             $questionRow .= "<span class='highlighterror' title='" . $varNameError['message'] . "' " . "onclick='window.open(\"{$editlink}\",\"_blank\")'>" . $rootVarName . "</span>";
         }
         $questionRow .= "</b><br />[<a target='_blank' href='{$editlink}'>QID {$qid}</a>]<br/>{$typedesc} [{$type}] {$errText}</td>" . "<td>" . $relevance . $prettyValidEqn . $default . "</td>" . "<td>" . $qdetails . "</td>" . "</tr>\n";
         $out .= $questionRow;
         $out .= $sqRows;
         $out .= $answerRows;
         if ($errorCount > 0) {
             $allErrors[$gid . '~' . $qid] = $errorCount;
         }
     }
     $out .= "</table>";
     LimeExpressionManager::FinishProcessingPage();
     if (($LEMdebugLevel & LEM_DEBUG_TIMING) == LEM_DEBUG_TIMING) {
         $out .= LimeExpressionManager::GetDebugTimingMessage();
     }
     if (count($allErrors) > 0) {
         $out = "<p class='alert alert-danger'>" . $LEM->ngT("{n} question contains errors that need to be corrected.|{n} questions contain errors that need to be corrected.", count($allErrors)) . "</p>\n" . $out;
     } else {
         switch ($surveyMode) {
             case 'survey':
                 $message = $LEM->gT('No syntax errors detected in this survey.');
                 break;
             case 'group':
                 $message = $LEM->gT('This group, by itself, does not contain any syntax errors.');
                 break;
             case 'question':
                 $message = $LEM->gT('This question, by itself, does not contain any syntax errors.');
                 break;
         }
         $out = "<p class='LEMheading'>{$message}</p>\n" . $out . "</div>";
     }
     return array('errors' => $allErrors, 'html' => $out);
 }