function index($subaction, $iSurveyID = null, $gid = null, $qid = null) { $iSurveyID = sanitize_int($iSurveyID); $gid = sanitize_int($gid); $qid = sanitize_int($qid); $imageurl = Yii::app()->getConfig("adminimageurl"); Yii::app()->loadHelper("database"); $aData['sidemenu']['state'] = false; $surveyinfo = Survey::model()->findByPk($iSurveyID)->surveyinfo; $aData['title_bar']['title'] = $surveyinfo['surveyls_title'] . "(" . gT("ID") . ":" . $iSurveyID . ")"; $aData['questionbar']['closebutton']['url'] = 'admin/questions/sa/view/surveyid/' . $iSurveyID . '/gid/' . $gid . '/qid/' . $qid; // Close button $aData['questionbar']['buttons']['conditions'] = TRUE; switch ($subaction) { case 'editconditionsform': $aData['questionbar']['buttons']['condition']['edit'] = TRUE; break; case 'conditions': $aData['questionbar']['buttons']['condition']['conditions'] = TRUE; break; case 'copyconditionsform': $aData['questionbar']['buttons']['condition']['copyconditionsform'] = TRUE; break; default: $aData['questionbar']['buttons']['condition']['edit'] = TRUE; break; } if (!empty($_POST['subaction'])) { $subaction = Yii::app()->request->getPost('subaction'); } //BEGIN Sanitizing POSTed data if (!isset($iSurveyID)) { $iSurveyID = returnGlobal('sid'); } if (!isset($qid)) { $qid = returnGlobal('qid'); } if (!isset($gid)) { $gid = returnGlobal('gid'); } if (!isset($p_scenario)) { $p_scenario = returnGlobal('scenario'); } if (!isset($p_cqid)) { $p_cqid = returnGlobal('cqid'); if ($p_cqid == '') { $p_cqid = 0; } // we are not using another question as source of condition } if (!isset($p_cid)) { $p_cid = returnGlobal('cid'); } if (!isset($p_subaction)) { if (isset($_POST['subaction'])) { $p_subaction = $_POST['subaction']; } else { $p_subaction = $subaction; } } if (!isset($p_cquestions)) { $p_cquestions = returnGlobal('cquestions'); } if (!isset($p_csrctoken)) { $p_csrctoken = returnGlobal('csrctoken'); } if (!isset($p_prevquestionsgqa)) { $p_prevquestionsgqa = returnGlobal('prevQuestionSGQA'); } if (!isset($p_canswers)) { if (isset($_POST['canswers']) && is_array($_POST['canswers'])) { foreach ($_POST['canswers'] as $key => $val) { $p_canswers[$key] = preg_replace("/[^_.a-zA-Z0-9]@/", "", $val); } } } // this array will be used soon, // to explain wich conditions is used to evaluate the question if (Yii::app()->getConfig('stringcomparizonoperators') == 1) { $method = array("<" => gT("Less than"), "<=" => gT("Less than or equal to"), "==" => gT("Equals"), "!=" => gT("Not equal to"), ">=" => gT("Greater than or equal to"), ">" => gT("Greater than"), "RX" => gT("Regular expression"), "a<b" => gT("Less than (Strings)"), "a<=b" => gT("Less than or equal to (Strings)"), "a>=b" => gT("Greater than or equal to (Strings)"), "a>b" => gT("Greater than (Strings)")); } else { $method = array("<" => gT("Less than"), "<=" => gT("Less than or equal to"), "==" => gT("equals"), "!=" => gT("Not equal to"), ">=" => gT("Greater than or equal to"), ">" => gT("Greater than"), "RX" => gT("Regular expression")); } if (isset($_POST['method'])) { if (!in_array($_POST['method'], array_keys($method))) { $p_method = "=="; } else { $p_method = trim($_POST['method']); } } if (isset($_POST['newscenarionum'])) { $p_newscenarionum = sanitize_int($_POST['newscenarionum']); } //END Sanitizing POSTed data //include_once("login_check.php"); include_once "database.php"; // Caution (lemeur): database.php uses autoUnescape on all entries in $_POST // Take care to not use autoUnescape on $_POST variables after this $br = CHtml::openTag('br /'); //MAKE SURE THAT THERE IS A SID if (!isset($iSurveyID) || !$iSurveyID) { $conditionsoutput = gT("You have not selected a survey") . str_repeat($br, 2); $conditionsoutput .= CHtml::submitButton(gT("Main admin screen", 'unescaped'), array('onclick' => "window.open('" . $this->getController()->createUrl("admin/") . "', '_top')")) . $br; safeDie($conditionsoutput); return; } if (isset($p_subaction) && $p_subaction == "resetsurveylogic") { $resetsurveylogicoutput = $br; $resetsurveylogicoutput .= CHtml::openTag('table', array('class' => 'alertbox')); $resetsurveylogicoutput .= CHtml::openTag('tr') . CHtml::openTag('td', array('colspan' => '2')); $resetsurveylogicoutput .= CHtml::tag('font', array('size' => '1'), CHtml::tag('strong', array(), gT("Reset Survey Logic"))); $resetsurveylogicoutput .= CHtml::closeTag('td') . CHtml::closeTag('tr'); if (!isset($_GET['ok'])) { $button_yes = CHtml::submitButton(gT("Yes", 'unescaped'), array('onclick' => "window.open('" . $this->getController()->createUrl("admin/conditions/sa/index/subaction/resetsurveylogic/surveyid/{$iSurveyID}") . "?ok=Y" . "', '_top')")); $button_cancel = CHtml::submitButton(gT("Cancel", 'unescaped'), array('onclick' => "window.open('" . $this->getController()->createUrl("admin/survey/sa/view/surveyid/{$iSurveyID}") . "', '_top')")); $messagebox_content = gT("You are about to delete all conditions on this survey's questions") . "({$iSurveyID})" . $br . gT("We recommend that before you proceed, you export the entire survey from the main administration screen.") . $br . gT("Continue?") . $br . $button_yes . $button_cancel; $this->_renderWrappedTemplate('conditions', array('message' => array('title' => gT("Warning"), 'message' => $messagebox_content))); exit; } else { LimeExpressionManager::RevertUpgradeConditionsToRelevance($iSurveyID); Condition::model()->deleteRecords("qid in (select qid from {{questions}} where sid={$iSurveyID})"); Yii::app()->setFlashMessage(gT("All conditions in this survey have been deleted.")); $this->getController()->redirect(array('admin/survey/sa/view/surveyid/' . $iSurveyID)); } } // MAKE SURE THAT THERE IS A QID if (!isset($qid) || !$qid) { $conditionsoutput = gT("You have not selected a question") . str_repeat($br, 2); $conditionsoutput .= CHtml::submitButton(gT("Main admin screen", 'unescaped'), array('onclick' => "window.open('" . $this->getController()->createUrl("admin/") . "', '_top')")) . $br; safeDie($conditionsoutput); return; } // If we made it this far, then lets develop the menu items // add the conditions container table $extraGetParams = ""; if (isset($qid) && isset($gid)) { $extraGetParams = "/gid/{$gid}/qid/{$qid}"; } $conditionsoutput_action_error = ""; // defined during the actions $markcidarray = array(); if (isset($_GET['markcid'])) { $markcidarray = explode("-", $_GET['markcid']); } //BEGIN PROCESS ACTIONS // ADD NEW ENTRY IF THIS IS AN ADD if (isset($p_subaction) && $p_subaction == "insertcondition") { if (!isset($p_canswers) && !isset($_POST['ConditionConst']) && !isset($_POST['prevQuestionSGQA']) && !isset($_POST['tokenAttr']) && !isset($_POST['ConditionRegexp']) || !isset($p_cquestions) && !isset($p_csrctoken)) { $conditionsoutput_action_error .= CHtml::script("\n<!--\n alert(\"" . gT("Your condition could not be added! It did not include the question and/or answer upon which the condition was based. Please ensure you have selected a question and an answer.", "js") . "\")\n //-->\n"); } else { if (isset($p_cquestions) && $p_cquestions != '') { $conditionCfieldname = $p_cquestions; } elseif (isset($p_csrctoken) && $p_csrctoken != '') { $conditionCfieldname = $p_csrctoken; } $condition_data = array('qid' => $qid, 'scenario' => $p_scenario, 'cqid' => $p_cqid, 'cfieldname' => $conditionCfieldname, 'method' => $p_method); if (isset($p_canswers)) { foreach ($p_canswers as $ca) { //First lets make sure there isn't already an exact replica of this condition $condition_data['value'] = $ca; $result = Condition::model()->findAllByAttributes($condition_data); $count_caseinsensitivedupes = count($result); if ($count_caseinsensitivedupes == 0) { $result = Condition::model()->insertRecords($condition_data); } } } unset($posted_condition_value); // Please note that autoUnescape is already applied in database.php included above // so we only need to db_quote _POST variables if (isset($_POST['ConditionConst']) && isset($_POST['editTargetTab']) && $_POST['editTargetTab'] == "#CONST") { $posted_condition_value = Yii::app()->request->getPost('ConditionConst'); } elseif (isset($_POST['prevQuestionSGQA']) && isset($_POST['editTargetTab']) && $_POST['editTargetTab'] == "#PREVQUESTIONS") { $posted_condition_value = Yii::app()->request->getPost('prevQuestionSGQA'); } elseif (isset($_POST['tokenAttr']) && isset($_POST['editTargetTab']) && $_POST['editTargetTab'] == "#TOKENATTRS") { $posted_condition_value = Yii::app()->request->getPost('tokenAttr'); } elseif (isset($_POST['ConditionRegexp']) && isset($_POST['editTargetTab']) && $_POST['editTargetTab'] == "#REGEXP") { $posted_condition_value = Yii::app()->request->getPost('ConditionRegexp'); } if (isset($posted_condition_value)) { $condition_data['value'] = $posted_condition_value; $result = Condition::model()->insertRecords($condition_data); } } LimeExpressionManager::UpgradeConditionsToRelevance(NULL, $qid); } // UPDATE ENTRY IF THIS IS AN EDIT if (isset($p_subaction) && $p_subaction == "updatecondition") { if (!isset($p_canswers) && !isset($_POST['ConditionConst']) && !isset($_POST['prevQuestionSGQA']) && !isset($_POST['tokenAttr']) && !isset($_POST['ConditionRegexp']) || !isset($p_cquestions) && !isset($p_csrctoken)) { $conditionsoutput_action_error .= CHtml::script("\n<!--\n alert(\"" . gT("Your condition could not be added! It did not include the question and/or answer upon which the condition was based. Please ensure you have selected a question and an answer.", "js") . "\")\n //-->\n"); } else { if (isset($p_cquestions) && $p_cquestions != '') { $conditionCfieldname = $p_cquestions; } elseif (isset($p_csrctoken) && $p_csrctoken != '') { $conditionCfieldname = $p_csrctoken; } if (isset($p_canswers)) { foreach ($p_canswers as $ca) { // This is an Edit, there will only be ONE VALUE $updated_data = array('qid' => $qid, 'scenario' => $p_scenario, 'cqid' => $p_cqid, 'cfieldname' => $conditionCfieldname, 'method' => $p_method, 'value' => $ca); $result = Condition::model()->insertRecords($updated_data, TRUE, array('cid' => $p_cid)); } } unset($posted_condition_value); // Please note that autoUnescape is already applied in database.php included above // so we only need to db_quote _POST variables if (isset($_POST['ConditionConst']) && isset($_POST['editTargetTab']) && $_POST['editTargetTab'] == "#CONST") { $posted_condition_value = Yii::app()->request->getPost('ConditionConst'); } elseif (isset($_POST['prevQuestionSGQA']) && isset($_POST['editTargetTab']) && $_POST['editTargetTab'] == "#PREVQUESTIONS") { $posted_condition_value = Yii::app()->request->getPost('prevQuestionSGQA'); } elseif (isset($_POST['tokenAttr']) && isset($_POST['editTargetTab']) && $_POST['editTargetTab'] == "#TOKENATTRS") { $posted_condition_value = Yii::app()->request->getPost('tokenAttr'); } elseif (isset($_POST['ConditionRegexp']) && isset($_POST['editTargetTab']) && $_POST['editTargetTab'] == "#REGEXP") { $posted_condition_value = Yii::app()->request->getPost('ConditionRegexp'); } if (isset($posted_condition_value)) { $updated_data = array('qid' => $qid, 'scenario' => $p_scenario, 'cqid' => $p_cqid, 'cfieldname' => $conditionCfieldname, 'method' => $p_method, 'value' => $posted_condition_value); $result = Condition::model()->insertRecords($updated_data, TRUE, array('cid' => $p_cid)); } } LimeExpressionManager::UpgradeConditionsToRelevance(NULL, $qid); } // DELETE ENTRY IF THIS IS DELETE if (isset($p_subaction) && $p_subaction == "delete") { LimeExpressionManager::RevertUpgradeConditionsToRelevance(NULL, $qid); // in case deleted the last condition $result = Condition::model()->deleteRecords(array('cid' => $p_cid)); LimeExpressionManager::UpgradeConditionsToRelevance(NULL, $qid); } // DELETE ALL CONDITIONS IN THIS SCENARIO if (isset($p_subaction) && $p_subaction == "deletescenario") { LimeExpressionManager::RevertUpgradeConditionsToRelevance(NULL, $qid); // in case deleted the last condition $result = Condition::model()->deleteRecords(array('qid' => $qid, 'scenario' => $p_scenario)); LimeExpressionManager::UpgradeConditionsToRelevance(NULL, $qid); } // UPDATE SCENARIO if (isset($p_subaction) && $p_subaction == "updatescenario" && isset($p_newscenarionum)) { $result = Condition::model()->insertRecords(array('scenario' => $p_newscenarionum), TRUE, array('qid' => $qid, 'scenario' => $p_scenario)); LimeExpressionManager::UpgradeConditionsToRelevance(NULL, $qid); } // DELETE ALL CONDITIONS FOR THIS QUESTION if (isset($p_subaction) && $p_subaction == "deleteallconditions") { LimeExpressionManager::RevertUpgradeConditionsToRelevance(NULL, $qid); // in case deleted the last condition $result = Condition::model()->deleteRecords(array('qid' => $qid)); } // RENUMBER SCENARIOS if (isset($p_subaction) && $p_subaction == "renumberscenarios") { $query = "SELECT DISTINCT scenario FROM {{conditions}} WHERE qid=:qid ORDER BY scenario"; $result = Yii::app()->db->createCommand($query)->bindParam(":qid", $qid, PDO::PARAM_INT)->query() or safeDie("Couldn't select scenario<br />{$query}<br />"); $newindex = 1; foreach ($result->readAll() as $srow) { // new var $update_result == old var $result2 $update_result = Condition::model()->insertRecords(array('scenario' => $newindex), TRUE, array('qid' => $qid, 'scenario' => $srow['scenario'])); $newindex++; } LimeExpressionManager::UpgradeConditionsToRelevance(NULL, $qid); Yii::app()->setFlashMessage(gT("All conditions scenarios were renumbered.")); } // COPY CONDITIONS IF THIS IS COPY if (isset($p_subaction) && $p_subaction == "copyconditions") { $qid = returnGlobal('qid'); $copyconditionsfrom = returnGlobal('copyconditionsfrom'); $copyconditionsto = returnGlobal('copyconditionsto'); if (isset($copyconditionsto) && is_array($copyconditionsto) && isset($copyconditionsfrom) && is_array($copyconditionsfrom)) { //Get the conditions we are going to copy foreach ($copyconditionsfrom as &$entry) { $entry = Yii::app()->db->quoteValue($entry); } $query = "SELECT * FROM {{conditions}}\n" . "WHERE cid in ("; $query .= implode(", ", $copyconditionsfrom); $query .= ")"; $result = Yii::app()->db->createCommand($query)->query() or safeDie("Couldn't get conditions for copy<br />{$query}<br />"); foreach ($result->readAll() as $row) { $proformaconditions[] = array("scenario" => $row['scenario'], "cqid" => $row['cqid'], "cfieldname" => $row['cfieldname'], "method" => $row['method'], "value" => $row['value']); } // while foreach ($copyconditionsto as $copyc) { list($newsid, $newgid, $newqid) = explode("X", $copyc); foreach ($proformaconditions as $pfc) { //TIBO //First lets make sure there isn't already an exact replica of this condition $conditions_data = array('qid' => $newqid, 'scenario' => $pfc['scenario'], 'cqid' => $pfc['cqid'], 'cfieldname' => $pfc['cfieldname'], 'method' => $pfc['method'], 'value' => $pfc['value']); $result = Condition::model()->findAllByAttributes($conditions_data); $count_caseinsensitivedupes = count($result); $countduplicates = 0; if ($count_caseinsensitivedupes != 0) { foreach ($result as $ccrow) { if ($ccrow['value'] == $pfc['value']) { $countduplicates++; } } } if ($countduplicates == 0) { $result = Condition::model()->insertRecords($conditions_data); $conditionCopied = true; } else { $conditionDuplicated = true; } } } if (isset($conditionCopied) && $conditionCopied === true) { if (isset($conditionDuplicated) && $conditionDuplicated == true) { $CopyConditionsMessage = CHtml::tag('div', array('class' => 'partialheader'), '(' . gT("Condition successfully copied (some were skipped because they were duplicates)") . ')'); Yii::app()->setFlashMessage(gT("Condition successfully copied (some were skipped because they were duplicates)"), 'warning'); } else { $CopyConditionsMessage = CHtml::tag('div', array('class' => 'successheader'), '(' . gT("Condition successfully copied") . ')'); Yii::app()->setFlashMessage(gT("Condition successfully copied")); } } else { $CopyConditionsMessage = CHtml::tag('div', array('class' => 'warningheader'), '(' . gT("No conditions could be copied (due to duplicates)") . ')'); Yii::app()->setFlashMessage(gT("No conditions could be copied (due to duplicates)"), 'error'); } } LimeExpressionManager::UpgradeConditionsToRelevance($iSurveyID); // do for whole survey, since don't know which questions affected. } //END PROCESS ACTIONS $cquestions = array(); $canswers = array(); //BEGIN: GATHER INFORMATION // 1: Get information for this question // @todo : use viewHelper::getFieldText and getFieldCode for 2.06 for string show to user if (!isset($qid)) { $qid = returnGlobal('qid'); } if (!isset($iSurveyID)) { $iSurveyID = returnGlobal('sid'); } $thissurvey = getSurveyInfo($iSurveyID); $qresult = Question::model()->with('groups')->findByAttributes(array('qid' => $qid, 'parent_qid' => 0, 'language' => Survey::model()->findByPk($iSurveyID)->language)); $questiongroupname = $qresult->groups->group_name; $questiontitle = $qresult['title']; $sCurrentFullQuestionText = $qresult['question']; $questiontype = $qresult['type']; // 2: Get all other questions that occur before this question that are pre-determined answer types // To avoid natural sort order issues, // first get all questions in natural sort order // , and find out which number in that order this question is $qresult = Question::model()->with(array('groups' => array('condition' => 'groups.language = :lang', 'params' => array(':lang' => Survey::model()->findByPk($iSurveyID)->language))))->findAllByAttributes(array('parent_qid' => 0, 'sid' => $iSurveyID, 'language' => Survey::model()->findByPk($iSurveyID)->language)); $qrows = array(); foreach ($qresult as $k => $v) { $qrows[$k] = array_merge($v->attributes, $v->groups->attributes); } // Perform a case insensitive natural sort on group name then question title (known as "code" in the form) of a multidimensional array usort($qrows, 'groupOrderThenQuestionOrder'); $position = "before"; // Go through each question until we reach the current one foreach ($qrows as $qrow) { if ($qrow["qid"] != $qid && $position == "before") { // remember all previous questions // all question types are supported. $questionlist[] = $qrow["qid"]; } elseif ($qrow["qid"] == $qid) { break; } } // Now, using the same array which is now properly sorted by group then question // Create an array of all the questions that appear AFTER the current one $position = "before"; foreach ($qrows as $qrow) { if ($qrow["qid"] == $qid) { $position = "after"; //break; } elseif ($qrow["qid"] != $qid && $position == "after") { $postquestionlist[] = $qrow['qid']; } } $theserows = array(); $postrows = array(); if (isset($questionlist) && is_array($questionlist)) { foreach ($questionlist as $ql) { $result = Question::model()->with(array('groups' => array('condition' => 'groups.language = :lang', 'params' => array(':lang' => Survey::model()->findByPk($iSurveyID)->language))))->findAllByAttributes(array('qid' => $ql, 'parent_qid' => 0, 'sid' => $iSurveyID, 'language' => Survey::model()->findByPk($iSurveyID)->language)); $thiscount = count($result); // And store again these questions in this array... foreach ($result as $myrows) { //key => value $theserows[] = array("qid" => $myrows['qid'], "sid" => $myrows['sid'], "gid" => $myrows['gid'], "question" => $myrows['question'], "type" => $myrows['type'], "mandatory" => $myrows['mandatory'], "other" => $myrows['other'], "title" => $myrows['title']); } } } if (isset($postquestionlist) && is_array($postquestionlist)) { foreach ($postquestionlist as $pq) { $result = Question::model()->with(array('groups' => array('condition' => 'groups.language = :lang', 'params' => array(':lang' => Survey::model()->findByPk($iSurveyID)->language))))->findAllByAttributes(array('qid' => $pq, 'parent_qid' => 0, 'sid' => $iSurveyID, 'language' => Survey::model()->findByPk($iSurveyID)->language)); $postcount = count($result); foreach ($result as $myrows) { $postrows[] = array("qid" => $myrows['qid'], "sid" => $myrows['sid'], "gid" => $myrows['gid'], "question" => $myrows['question'], "type" => $myrows['type'], "mandatory" => $myrows['mandatory'], "other" => $myrows['other'], "title" => $myrows['title']); } // while } $postquestionscount = count($postrows); } $questionscount = count($theserows); if (isset($postquestionscount) && $postquestionscount > 0) { //Build the array used for the questionNav and copyTo select boxes foreach ($postrows as $pr) { $pquestions[] = array("text" => $pr['title'] . ": " . substr(strip_tags($pr['question']), 0, 80), "fieldname" => $pr['sid'] . "X" . $pr['gid'] . "X" . $pr['qid']); } } // Previous question parsing ==> building cquestions[] and canswers[] if ($questionscount > 0) { $X = "X"; foreach ($theserows as $rows) { $shortquestion = $rows['title'] . ": " . strip_tags($rows['question']); if ($rows['type'] == "A" || $rows['type'] == "B" || $rows['type'] == "C" || $rows['type'] == "E" || $rows['type'] == "F" || $rows['type'] == "H") { $aresult = Question::model()->findAllByAttributes(array('parent_qid' => $rows['qid'], 'language' => Survey::model()->findByPk($iSurveyID)->language), array('order' => 'question_order ASC')); foreach ($aresult as $arows) { $shortanswer = "{$arows['title']}: [" . flattenText($arows['question']) . "]"; $shortquestion = $rows['title'] . ":{$shortanswer} " . flattenText($rows['question']); $cquestions[] = array($shortquestion, $rows['qid'], $rows['type'], $rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title']); switch ($rows['type']) { case "A": //Array 5 buttons for ($i = 1; $i <= 5; $i++) { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'], $i, $i); } break; case "B": //Array 10 buttons for ($i = 1; $i <= 10; $i++) { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'], $i, $i); } break; case "C": //Array Y/N/NA $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'], "Y", gT("Yes")); $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'], "U", gT("Uncertain")); $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'], "N", gT("No")); break; case "E": //Array >/=/< $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'], "I", gT("Increase")); $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'], "S", gT("Same")); $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'], "D", gT("Decrease")); break; case "F": //Array Flexible Row //Array Flexible Row case "H": //Array Flexible Column $fresult = Answer::model()->findAllByAttributes(array('qid' => $rows['qid'], "language" => Survey::model()->findByPk($iSurveyID)->language, 'scale_id' => 0), array('order' => 'sortorder, code')); foreach ($fresult as $frow) { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'], $frow['code'], $frow['answer']); } break; } // Only Show No-Answer if question is not mandatory if ($rows['mandatory'] != 'Y') { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'], "", gT("No answer")); } } //while } elseif ($rows['type'] == ":" || $rows['type'] == ";") { // Multiflexi // Get the Y-Axis $fquery = "SELECT sq.*, q.other" . " FROM {{questions sq}}, {{questions q}}" . " WHERE sq.sid={$iSurveyID} AND sq.parent_qid=q.qid " . "AND q.language=:lang1" . " AND sq.language=:lang2" . " AND q.qid=:qid\n AND sq.scale_id=0\n ORDER BY sq.question_order"; $sLanguage = Survey::model()->findByPk($iSurveyID)->language; $y_axis_db = Yii::app()->db->createCommand($fquery)->bindParam(":lang1", $sLanguage, PDO::PARAM_STR)->bindParam(":lang2", $sLanguage, PDO::PARAM_STR)->bindParam(":qid", $rows['qid'], PDO::PARAM_INT)->query(); // Get the X-Axis $aquery = "SELECT sq.*\n FROM {{questions q}}, {{questions sq}}\n WHERE q.sid={$iSurveyID}\n AND sq.parent_qid=q.qid\n AND q.language=:lang1\n AND sq.language=:lang2\n AND q.qid=:qid\n AND sq.scale_id=1\n ORDER BY sq.question_order"; $x_axis_db = Yii::app()->db->createCommand($aquery)->bindParam(":lang1", $sLanguage, PDO::PARAM_STR)->bindParam(":lang2", $sLanguage, PDO::PARAM_STR)->bindParam(":qid", $rows['qid'], PDO::PARAM_INT)->query() or safeDie("Couldn't get answers to Array questions<br />{$aquery}<br />"); foreach ($x_axis_db->readAll() as $frow) { $x_axis[$frow['title']] = $frow['question']; } foreach ($y_axis_db->readAll() as $yrow) { foreach ($x_axis as $key => $val) { $shortquestion = $rows['title'] . ":{$yrow['title']}:{$key}: [" . strip_tags($yrow['question']) . "][" . strip_tags($val) . "] " . flattenText($rows['question']); $cquestions[] = array($shortquestion, $rows['qid'], $rows['type'], $rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $yrow['title'] . "_" . $key); if ($rows['mandatory'] != 'Y') { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $yrow['title'] . "_" . $key, "", gT("No answer")); } } } unset($x_axis); } elseif ($rows['type'] == "1") { $aresult = Question::model()->findAllByAttributes(array('parent_qid' => $rows['qid'], 'language' => Survey::model()->findByPk($iSurveyID)->language), array('order' => 'question_order desc')); foreach ($aresult as $arows) { $attr = getQuestionAttributeValues($rows['qid']); $sLanguage = Survey::model()->findByPk($iSurveyID)->language; // dualscale_header are allways set, but can be empty $label1 = empty($attr['dualscale_headerA'][$sLanguage]) ? gT('Scale 1') : $attr['dualscale_headerA'][$sLanguage]; $label2 = empty($attr['dualscale_headerB'][$sLanguage]) ? gT('Scale 2') : $attr['dualscale_headerB'][$sLanguage]; $shortanswer = "{$arows['title']}: [" . strip_tags($arows['question']) . "][{$label1}]"; $shortquestion = $rows['title'] . ":{$shortanswer} " . strip_tags($rows['question']); $cquestions[] = array($shortquestion, $rows['qid'], $rows['type'], $rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'] . "#0"); $shortanswer = "{$arows['title']}: [" . strip_tags($arows['question']) . "][{$label2}]"; $shortquestion = $rows['title'] . ":{$shortanswer} " . strip_tags($rows['question']); $cquestions[] = array($shortquestion, $rows['qid'], $rows['type'], $rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'] . "#1"); // first label $lresult = Answer::model()->findAllByAttributes(array('qid' => $rows['qid'], 'scale_id' => 0, 'language' => Survey::model()->findByPk($iSurveyID)->language), array('order' => 'sortorder, answer')); foreach ($lresult as $lrows) { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'] . "#0", "{$lrows['code']}", "{$lrows['code']}"); } // second label $lresult = Answer::model()->findAllByAttributes(array('qid' => $rows['qid'], 'scale_id' => 1, 'language' => Survey::model()->findByPk($iSurveyID)->language), array('order' => 'sortorder, answer')); foreach ($lresult as $lrows) { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'] . "#1", "{$lrows['code']}", "{$lrows['code']}"); } // Only Show No-Answer if question is not mandatory if ($rows['mandatory'] != 'Y') { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'] . "#0", "", gT("No answer")); $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'] . "#1", "", gT("No answer")); } } //while } elseif ($rows['type'] == "K" || $rows['type'] == "Q") { $aresult = Question::model()->findAllByAttributes(array("parent_qid" => $rows['qid'], "language" => Survey::model()->findByPk($iSurveyID)->language), array('order' => 'question_order desc')); foreach ($aresult as $arows) { $shortanswer = "{$arows['title']}: [" . strip_tags($arows['question']) . "]"; $shortquestion = $rows['title'] . ":{$shortanswer} " . strip_tags($rows['question']); $cquestions[] = array($shortquestion, $rows['qid'], $rows['type'], $rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title']); // Only Show No-Answer if question is not mandatory if ($rows['mandatory'] != 'Y') { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'], "", gT("No answer")); } } //while } elseif ($rows['type'] == "R") { $aresult = Answer::model()->findAllByAttributes(array("qid" => $rows['qid'], "scale_id" => 0, "language" => Survey::model()->findByPk($iSurveyID)->language), array('order' => 'sortorder, answer')); $acount = count($aresult); foreach ($aresult as $arow) { $theanswer = addcslashes($arow['answer'], "'"); $quicky[] = array($arow['code'], $theanswer); } for ($i = 1; $i <= $acount; $i++) { $cquestions[] = array("{$rows['title']}: [RANK {$i}] " . strip_tags($rows['question']), $rows['qid'], $rows['type'], $rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $i); foreach ($quicky as $qck) { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $i, $qck[0], $qck[1]); } // Only Show No-Answer if question is not mandatory if ($rows['mandatory'] != 'Y') { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $i, " ", gT("No answer")); } } unset($quicky); } elseif ($rows['type'] == "M" || $rows['type'] == "P") { $shortanswer = " [" . gT("Group of checkboxes") . "]"; $shortquestion = $rows['title'] . ":{$shortanswer} " . strip_tags($rows['question']); $cquestions[] = array($shortquestion, $rows['qid'], $rows['type'], $rows['sid'] . $X . $rows['gid'] . $X . $rows['qid']); $aresult = Question::model()->findAllByAttributes(array("parent_qid" => $rows['qid'], "language" => Survey::model()->findByPk($iSurveyID)->language), array('order' => 'question_order desc')); foreach ($aresult as $arows) { $theanswer = addcslashes($arows['question'], "'"); $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'], $arows['title'], $theanswer); $shortanswer = "{$arows['title']}: [" . strip_tags($arows['question']) . "]"; $shortanswer .= "[" . gT("Single checkbox") . "]"; $shortquestion = $rows['title'] . ":{$shortanswer} " . strip_tags($rows['question']); $cquestions[] = array($shortquestion, $rows['qid'], $rows['type'], "+" . $rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title']); $canswers[] = array("+" . $rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'], 'Y', gT("checked")); $canswers[] = array("+" . $rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'], '', gT("not checked")); } } elseif ($rows['type'] == "X") { //Just ignore this questiontype } else { $cquestions[] = array($shortquestion, $rows['qid'], $rows['type'], $rows['sid'] . $X . $rows['gid'] . $X . $rows['qid']); switch ($rows['type']) { case "Y": // Y/N/NA $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'], "Y", gT("Yes")); $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'], "N", gT("No")); // Only Show No-Answer if question is not mandatory if ($rows['mandatory'] != 'Y') { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'], " ", gT("No answer")); } break; case "G": //Gender $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'], "F", gT("Female")); $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'], "M", gT("Male")); // Only Show No-Answer if question is not mandatory if ($rows['mandatory'] != 'Y') { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'], " ", gT("No answer")); } break; case "5": // 5 choice for ($i = 1; $i <= 5; $i++) { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'], $i, $i); } // Only Show No-Answer if question is not mandatory if ($rows['mandatory'] != 'Y') { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'], " ", gT("No answer")); } break; case "N": // Simple Numerical questions // Only Show No-Answer if question is not mandatory if ($rows['mandatory'] != 'Y') { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'], " ", gT("No answer")); } break; default: $aresult = Answer::model()->findAllByAttributes(array('qid' => $rows['qid'], 'scale_id' => 0, 'language' => Survey::model()->findByPk($iSurveyID)->language), array('order' => 'sortorder, answer')); foreach ($aresult as $arows) { $theanswer = addcslashes($arows['answer'], "'"); $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'], $arows['code'], $theanswer); } if ($rows['type'] == "D") { // Only Show No-Answer if question is not mandatory if ($rows['mandatory'] != 'Y') { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'], " ", gT("No answer")); } } elseif ($rows['type'] != "M" && $rows['type'] != "P" && $rows['type'] != "J" && $rows['type'] != "I") { // For dropdown questions // optinnaly add the 'Other' answer if (($rows['type'] == "L" || $rows['type'] == "!") && $rows['other'] == "Y") { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'], "-oth-", gT("Other")); } // Only Show No-Answer if question is not mandatory if ($rows['mandatory'] != 'Y') { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'], " ", gT("No answer")); } } break; } //switch row type } //else } //foreach theserows } //if questionscount > 0 //END Gather Information for this question $questionNavOptions = CHtml::openTag('optgroup', array('class' => 'activesurveyselect', 'label' => gT("Before", "js"))); foreach ($theserows as $row) { $question = $row['question']; $question = strip_tags($question); $questionselecter = viewHelper::flatEllipsizeText($question, true, '40'); $questionNavOptions .= CHtml::tag('option', array('value' => $this->getController()->createUrl("/admin/conditions/sa/index/subaction/editconditionsform/surveyid/{$iSurveyID}/gid/{$row['gid']}/qid/{$row['qid']}")), strip_tags($row['title']) . ':' . $questionselecter); } $questionNavOptions .= CHtml::closeTag('optgroup'); $questionNavOptions .= CHtml::openTag('optgroup', array('class' => 'activesurveyselect', 'label' => gT("Current", "js"))); $question = strip_tags($sCurrentFullQuestionText); $questiontextshort = viewHelper::flatEllipsizeText($question, true, '40'); $questionNavOptions .= CHtml::tag('option', array('value' => $this->getController()->createUrl("/admin/conditions/sa/index/subaction/editconditionsform/surveyid/{$iSurveyID}/gid/{$gid}/qid/{$qid}"), 'selected' => 'selected'), $questiontitle . ': ' . $questiontextshort); $questionNavOptions .= CHtml::closeTag('optgroup'); $questionNavOptions .= CHtml::openTag('optgroup', array('class' => 'activesurveyselect', 'label' => gT("After", "js"))); foreach ($postrows as $row) { $question = $row['question']; $question = strip_tags($question); $questionselecter = viewHelper::flatEllipsizeText($question, true, '40'); $questionNavOptions .= CHtml::tag('option', array('value' => $this->getController()->createUrl("/admin/conditions/sa/index/subaction/editconditionsform/surveyid/{$iSurveyID}/gid/{$row['gid']}/qid/{$row['qid']}")), strip_tags($row['title']) . ':' . $questionselecter); } $questionNavOptions .= CHtml::closeTag('optgroup'); //Now display the information and forms //BEGIN: PREPARE JAVASCRIPT TO SHOW MATCHING ANSWERS TO SELECTED QUESTION $javascriptpre = CHtml::openTag('script', array('type' => 'text/javascript')) . "<!--\n" . "\tvar Fieldnames = new Array();\n" . "\tvar Codes = new Array();\n" . "\tvar Answers = new Array();\n" . "\tvar QFieldnames = new Array();\n" . "\tvar Qcqids = new Array();\n" . "\tvar Qtypes = new Array();\n"; $jn = 0; if (isset($canswers)) { foreach ($canswers as $can) { $an = ls_json_encode(flattenText($can[2])); $javascriptpre .= "Fieldnames[{$jn}]='{$can[0]}';\n" . "Codes[{$jn}]='{$can[1]}';\n" . "Answers[{$jn}]={$an};\n"; $jn++; } } $jn = 0; if (isset($cquestions)) { foreach ($cquestions as $cqn) { $javascriptpre .= "QFieldnames[{$jn}]='{$cqn['3']}';\n" . "Qcqids[{$jn}]='{$cqn['1']}';\n" . "Qtypes[{$jn}]='{$cqn['2']}';\n"; $jn++; } } // record a JS variable to let jQuery know if survey is Anonymous if ($thissurvey['anonymized'] == 'Y') { $javascriptpre .= "isAnonymousSurvey = true;"; } else { $javascriptpre .= "isAnonymousSurvey = false;"; } $javascriptpre .= "//-->\n" . CHtml::closeTag('script'); //END: PREPARE JAVASCRIPT TO SHOW MATCHING ANSWERS TO SELECTED QUESTION $aViewUrls = array(); $oQuestion = Question::model()->find('qid=:qid', array(':qid' => $qid)); $aData['oQuestion'] = $oQuestion; $aData['surveyid'] = $iSurveyID; $aData['qid'] = $qid; $aData['gid'] = $gid; $aData['imageurl'] = $imageurl; $aData['extraGetParams'] = $extraGetParams; $aData['questionNavOptions'] = $questionNavOptions; $aData['conditionsoutput_action_error'] = $conditionsoutput_action_error; $aData['javascriptpre'] = $javascriptpre; $aViewUrls['conditionshead_view'][] = $aData; //BEGIN DISPLAY CONDITIONS FOR THIS QUESTION if ($subaction == 'index' || $subaction == 'editconditionsform' || $subaction == 'insertcondition' || $subaction == "editthiscondition" || $subaction == "delete" || $subaction == "updatecondition" || $subaction == "deletescenario" || $subaction == "renumberscenarios" || $subaction == "deleteallconditions" || $subaction == "updatescenario" || $subaction == 'copyconditionsform' || $subaction == 'copyconditions' || $subaction == 'conditions') { //3: Get other conditions currently set for this question $conditionscount = 0; $conditionsList = array(); $s = 0; $criteria = new CDbCriteria(); $criteria->select = 'scenario'; // only select the 'scenario' column $criteria->condition = 'qid=:qid'; $criteria->params = array(':qid' => $qid); $criteria->order = 'scenario'; $criteria->group = 'scenario'; $scenarioresult = Condition::model()->findAll($criteria); $scenariocount = count($scenarioresult); $aData['conditionsoutput'] = ''; $aData['extraGetParams'] = $extraGetParams; $aData['questionNavOptions'] = $questionNavOptions; $aData['conditionsoutput_action_error'] = $conditionsoutput_action_error; $aData['javascriptpre'] = $javascriptpre; $aData['onlyshow'] = sprintf(gT("Only show question %s IF"), $questiontitle . ': ' . $sCurrentFullQuestionText); $aData['sCurrentQuestionText'] = $questiontitle . ': ' . viewHelper::flatEllipsizeText($sCurrentFullQuestionText, true, '120'); $aData['subaction'] = $subaction; $aData['scenariocount'] = $scenariocount; $aViewUrls['conditionslist_view'][] = $aData; if ($scenariocount > 0) { $this->registerScriptFile('ADMIN_SCRIPT_PATH', 'checkgroup.js'); foreach ($scenarioresult as $scenarionr) { $scenariotext = ""; if ($s == 0 && $scenariocount > 1) { $scenariotext = " -------- <i>Scenario {$scenarionr['scenario']}</i> --------"; } if ($s > 0) { $scenariotext = " -------- <i>" . gT("OR") . " Scenario {$scenarionr['scenario']}</i> --------"; } if ($subaction == "copyconditionsform" || $subaction == "copyconditions") { $initialCheckbox = "<td><input type='checkbox' id='scenarioCbx{$scenarionr['scenario']}' checked='checked'/>\n" . "<script type='text/javascript'>\$(document).ready(function () { \$('#scenarioCbx{$scenarionr['scenario']}').checkgroup({ groupName:'aConditionFromScenario{$scenarionr['scenario']}'}); });</script>" . "</td><td> </td>\n"; } else { $initialCheckbox = ""; } if ($scenariotext != "" && ($subaction == "editconditionsform" || $subaction == "insertcondition" || $subaction == "updatecondition" || $subaction == "editthiscondition" || $subaction == "renumberscenarios" || $subaction == "updatescenario" || $subaction == "deletescenario" || $subaction == "delete")) { $img_tag = '<span class="glyphicon glyphicon-trash"></span>'; $additional_main_content = CHtml::link($img_tag, '#', array('onclick' => "if ( confirm('" . gT("Are you sure you want to delete all conditions set in this scenario?", "js") . "')) { document.getElementById('deletescenario{$scenarionr['scenario']}').submit();}")); $img_tag = '<span class="glyphicon glyphicon-pencil"></span>'; $additional_main_content .= CHtml::link($img_tag, '#', array('id' => 'editscenariobtn' . $scenarionr['scenario'], 'onclick' => "\$('#editscenario{$scenarionr['scenario']}').toggle('slow');")); $aData['additional_content'] = $additional_main_content; } $aData['initialCheckbox'] = $initialCheckbox; $aData['scenariotext'] = $scenariotext; $aData['scenarionr'] = $scenarionr; if (!isset($aViewUrls['output'])) { $aViewUrls['output'] = ''; } $aViewUrls['output'] .= $this->getController()->renderPartial('/admin/conditions/includes/conditions_scenario', $aData, TRUE); unset($currentfield); $query = "SELECT count(*) as recordcount\n FROM {{conditions}} c, {{questions}} q, {{groups}} g\n WHERE c.cqid=q.qid " . "AND q.gid=g.gid " . "AND q.parent_qid=0 " . "AND q.language=:lang1 " . "AND g.language=:lang2 " . "AND c.qid=:qid " . "AND c.scenario=:scenario " . "AND c.cfieldname NOT LIKE '{%' "; // avoid catching SRCtokenAttr conditions $sLanguage = Survey::model()->findByPk($iSurveyID)->language; $result = Yii::app()->db->createCommand($query)->bindValue(":scenario", $scenarionr['scenario'])->bindValue(":qid", $qid, PDO::PARAM_INT)->bindValue(":lang1", $sLanguage, PDO::PARAM_STR)->bindValue(":lang2", $sLanguage, PDO::PARAM_STR)->queryRow(); $conditionscount = (int) $result['recordcount']; $query = "SELECT c.cid, c.scenario, c.cqid, c.cfieldname, c.method, c.value, q.type\n FROM {{conditions}} c, {{questions}} q, {{groups}} g\n WHERE c.cqid=q.qid " . "AND q.gid=g.gid " . "AND q.parent_qid=0 " . "AND q.language=:lang1 " . "AND g.language=:lang2 " . "AND c.qid=:qid " . "AND c.scenario=:scenario " . "AND c.cfieldname NOT LIKE '{%' " . "ORDER BY g.group_order, q.question_order, c.cfieldname"; $sLanguage = Survey::model()->findByPk($iSurveyID)->language; $result2 = Yii::app()->db->createCommand($query)->bindValue(":scenario", $scenarionr['scenario'])->bindValue(":qid", $qid, PDO::PARAM_INT)->bindValue(":lang1", $sLanguage, PDO::PARAM_STR)->bindValue(":lang2", $sLanguage, PDO::PARAM_STR)->query() or safeDie("Couldn't get other conditions for question {$qid}<br />{$query}<br />"); $result2 = $result2->readAll(); $querytoken = "SELECT count(*) as recordcount " . "FROM {{conditions}} " . "WHERE " . " {{conditions}}.qid=:qid " . "AND {{conditions}}.scenario=:scenario " . "AND {{conditions}}.cfieldname LIKE '{%' "; // only catching SRCtokenAttr conditions $resulttoken = Yii::app()->db->createCommand($querytoken)->bindValue(":scenario", $scenarionr['scenario'], PDO::PARAM_INT)->bindValue(":qid", $qid, PDO::PARAM_INT)->queryRow() or safeDie("Couldn't get other conditions for question {$qid}<br />{$query}<br />"); $conditionscounttoken = (int) $resulttoken['recordcount']; $querytoken = "SELECT {{conditions}}.cid, " . "{{conditions}}.scenario, " . "{{conditions}}.cqid, " . "{{conditions}}.cfieldname, " . "{{conditions}}.method, " . "{{conditions}}.value, " . "'' AS type " . "FROM {{conditions}} " . "WHERE " . " {{conditions}}.qid=:qid " . "AND {{conditions}}.scenario=:scenario " . "AND {{conditions}}.cfieldname LIKE '{%' " . "ORDER BY {{conditions}}.cfieldname"; $resulttoken = Yii::app()->db->createCommand($querytoken)->bindValue(":scenario", $scenarionr['scenario'], PDO::PARAM_INT)->bindValue(":qid", $qid, PDO::PARAM_INT)->query() or safeDie("Couldn't get other conditions for question {$qid}<br />{$query}<br />"); $conditionscount = $conditionscount + $conditionscounttoken; ////////////////// BUILD CONDITIONS DISPLAY if ($conditionscount > 0) { $aConditionsMerged = array(); foreach ($resulttoken->readAll() as $arow) { $aConditionsMerged[] = $arow; } foreach ($result2 as $arow) { $aConditionsMerged[] = $arow; } foreach ($aConditionsMerged as $rows) { if ($rows['method'] == "") { $rows['method'] = "=="; } //Fill in the empty method from previous versions $markcidstyle = "oddrow"; if (array_search($rows['cid'], $markcidarray) !== FALSE) { // This is the style used when the condition editor is called // in order to check which conditions prevent a question deletion $markcidstyle = "markedrow"; } if ($subaction == "editthiscondition" && isset($p_cid) && $rows['cid'] === $p_cid) { // Style used when editing a condition $markcidstyle = "editedrow"; } if (isset($currentfield) && $currentfield != $rows['cfieldname']) { $aViewUrls['output'] .= "<tr class='evenrow'>\n" . "\t<td colspan='2' class='operator'>\n" . gT("and") . "</td></tr>"; } elseif (isset($currentfield)) { $aViewUrls['output'] .= "<tr class='evenrow'>\n" . "\t<td colspan='2' class='operator'>\n" . gT("or") . "</td></tr>"; } $aViewUrls['output'] .= "\t<tr class='{$markcidstyle}'>\n" . "\t<td colspan='2'>" . CHtml::form(array("/admin/conditions/sa/index/subaction/{$subaction}/surveyid/{$iSurveyID}/gid/{$gid}/qid/{$qid}/"), 'post', array('id' => "conditionaction{$rows['cid']}", 'name' => "conditionaction{$rows['cid']}")) . "<table class='table' id='conditionstable'>\n" . "\t<tr class='active'>\n"; if ($subaction == "copyconditionsform" || $subaction == "copyconditions") { $aViewUrls['output'] .= "<td> </td>" . "<td class='scenariotd'>\n" . "\t<input type='checkbox' name='aConditionFromScenario{$scenarionr['scenario']}' id='cbox{$rows['cid']}' value='{$rows['cid']}' checked='checked'/>\n" . "</td>\n"; } $aViewUrls['output'] .= "" . "<td class='col-md-4' id='questionnamecol'>\n" . "\t<span>\n"; $leftOperandType = 'unknown'; // prevquestion, tokenattr if ($thissurvey['anonymized'] != 'Y' && preg_match('/^{TOKEN:([^}]*)}$/', $rows['cfieldname'], $extractedTokenAttr) > 0) { $leftOperandType = 'tokenattr'; $aTokenAttrNames = getTokenFieldsAndNames($iSurveyID); if (isset($aTokenAttrNames[strtolower($extractedTokenAttr[1])])) { $thisAttrName = HTMLEscape($aTokenAttrNames[strtolower($extractedTokenAttr[1])]['description']); } else { $thisAttrName = HTMLEscape($extractedTokenAttr[1]); } if (tableExists("{{tokens_{$iSurveyID}}}")) { $thisAttrName .= " [" . gT("From token table") . "]"; } else { $thisAttrName .= " [" . gT("Inexistant token table") . "]"; } $aViewUrls['output'] .= "\t{$thisAttrName}\n"; // TIBO not sure this is used anymore !! $conditionsList[] = array("cid" => $rows['cid'], "text" => $thisAttrName); } else { $leftOperandType = 'prevquestion'; foreach ($cquestions as $cqn) { if ($cqn[3] == $rows['cfieldname']) { $aViewUrls['output'] .= "\t{$cqn['0']} (qid{$rows['cqid']})\n"; $conditionsList[] = array("cid" => $rows['cid'], "text" => $cqn[0] . " ({$rows['value']})"); } else { //$aViewUrls['output'] .= "\t<font color='red'>ERROR: Delete this condition. It is out of order.</font>\n"; } } } $aViewUrls['output'] .= "\t</span></td>\n" . "\t<td class='col-md-2' id='operatornametd'>\n" . "<span>\n" . $method[trim($rows['method'])] . "</span>\n" . "\t</td>\n" . "\n" . "\t<td class='col-md-3' id='questionanswertd'>\n" . "<span>\n"; // let's read the condition's right operand // determine its type and display it $rightOperandType = 'unknown'; // predefinedAnsw,constantVal, prevQsgqa, tokenAttr, regexp if ($rows['method'] == 'RX') { $rightOperandType = 'regexp'; $aViewUrls['output'] .= "" . HTMLEscape($rows['value']) . "\n"; } elseif (preg_match('/^@([0-9]+X[0-9]+X[^@]*)@$/', $rows['value'], $matchedSGQA) > 0) { // SGQA $rightOperandType = 'prevQsgqa'; $textfound = false; foreach ($cquestions as $cqn) { if ($cqn[3] == $matchedSGQA[1]) { $matchedSGQAText = $cqn[0]; $textfound = true; break; } } if ($textfound === false) { $matchedSGQAText = $rows['value'] . ' (' . gT("Not found") . ')'; } $aViewUrls['output'] .= "" . HTMLEscape($matchedSGQAText) . "\n"; } elseif ($thissurvey['anonymized'] != 'Y' && preg_match('/^{TOKEN:([^}]*)}$/', $rows['value'], $extractedTokenAttr) > 0) { $rightOperandType = 'tokenAttr'; $aTokenAttrNames = getTokenFieldsAndNames($iSurveyID); if (count($aTokenAttrNames) != 0) { $thisAttrName = HTMLEscape($aTokenAttrNames[strtolower($extractedTokenAttr[1])]['description']) . " [" . gT("From token table") . "]"; } else { $thisAttrName = HTMLEscape($extractedTokenAttr[1]) . " [" . gT("Inexistant token table") . "]"; } $aViewUrls['output'] .= "\t{$thisAttrName}\n"; } elseif (isset($canswers)) { foreach ($canswers as $can) { if ($can[0] == $rows['cfieldname'] && $can[1] == $rows['value']) { $aViewUrls['output'] .= "{$can['2']} ({$can['1']})\n"; $rightOperandType = 'predefinedAnsw'; } } } // if $rightOperandType is still unknown then it is a simple constant if ($rightOperandType == 'unknown') { $rightOperandType = 'constantVal'; if ($rows['value'] == ' ' || $rows['value'] == '') { $aViewUrls['output'] .= "" . gT("No answer") . "\n"; } else { $aViewUrls['output'] .= "" . HTMLEscape($rows['value']) . "\n"; } } $aViewUrls['output'] .= "\t</span></td>\n" . "\t<td class='text-right'>\n"; if ($subaction == "editconditionsform" || $subaction == "insertcondition" || $subaction == "updatecondition" || $subaction == "editthiscondition" || $subaction == "renumberscenarios" || $subaction == "deleteallconditions" || $subaction == "updatescenario" || $subaction == "deletescenario" || $subaction == "delete") { // show single condition action buttons in edit mode $aData['rows'] = $rows; $aData['sImageURL'] = Yii::app()->getConfig('adminimageurl'); //$aViewUrls['includes/conditions_edit'][] = $aData; $aViewUrls['output'] .= $this->getController()->renderPartial('/admin/conditions/includes/conditions_edit', $aData, TRUE); // now sets e corresponding hidden input field // depending on the leftOperandType if ($leftOperandType == 'tokenattr') { $aViewUrls['output'] .= CHtml::hiddenField('csrctoken', HTMLEscape($rows['cfieldname']), array('id' => 'csrctoken' . $rows['cid'])); } else { $aViewUrls['output'] .= CHtml::hiddenField('cquestions', HTMLEscape($rows['cfieldname']), array('id' => 'cquestions' . $rows['cid'])); } // now set the corresponding hidden input field // depending on the rightOperandType // This is used when editing a condition if ($rightOperandType == 'predefinedAnsw') { $aViewUrls['output'] .= CHtml::hiddenField('EDITcanswers[]', HTMLEscape($rows['value']), array('id' => 'editModeTargetVal' . $rows['cid'])); } elseif ($rightOperandType == 'prevQsgqa') { $aViewUrls['output'] .= CHtml::hiddenField('EDITprevQuestionSGQA', HTMLEscape($rows['value']), array('id' => 'editModeTargetVal' . $rows['cid'])); } elseif ($rightOperandType == 'tokenAttr') { $aViewUrls['output'] .= CHtml::hiddenField('EDITtokenAttr', HTMLEscape($rows['value']), array('id' => 'editModeTargetVal' . $rows['cid'])); } elseif ($rightOperandType == 'regexp') { $aViewUrls['output'] .= CHtml::hiddenField('EDITConditionRegexp', HTMLEscape($rows['value']), array('id' => 'editModeTargetVal' . $rows['cid'])); } else { $aViewUrls['output'] .= CHtml::hiddenField('EDITConditionConst', HTMLEscape($rows['value']), array('id' => 'editModeTargetVal' . $rows['cid'])); } } $aViewUrls['output'] .= CHtml::closeTag('td') . CHtml::closeTag('tr') . CHtml::closeTag('table') . CHtml::closeTag('form') . CHtml::closeTag('td') . CHtml::closeTag('tr'); $currentfield = $rows['cfieldname']; } } $s++; } // If we have a condition, allways reset the condition, this can fix old import (see #09344) LimeExpressionManager::UpgradeConditionsToRelevance(NULL, $qid); } else { // no condition ==> disable delete all conditions button, and display a simple comment // no_conditions $aViewUrls['output'] = $this->getController()->renderPartial('/admin/conditions/no_condition', $aData, true); } $aViewUrls['output'] .= CHtml::closeTag('table'); //// To close the div opened in condition header.... see : https://goo.gl/BY7gUJ $aViewUrls['afteroutput'] = '</div></div></div>'; } //END DISPLAY CONDITIONS FOR THIS QUESTION //// NICE COMMENTS : but a subaction copy would be even nicer // BEGIN: DISPLAY THE COPY CONDITIONS FORM if ($subaction == "copyconditionsform" || $subaction == "copyconditions") { $aViewUrls['output'] .= "<tr class=''><td colspan='3'>\n" . CHtml::form(array("/admin/conditions/sa/index/subaction/copyconditions/surveyid/{$iSurveyID}/gid/{$gid}/qid/{$qid}/"), 'post', array('id' => "copyconditions", 'name' => "copyconditions")) . "<h3>" . gT("Copy conditions") . "</h3>\n"; //CopyConditionsMessage if (isset($CopyConditionsMessage)) { $aViewUrls['output'] .= "<div class='messagebox ui-corner-all'>\n" . "{$CopyConditionsMessage}\n" . "</div>\n"; } if (count($conditionsList)) { // Multiselect is not working, so better to disable (as in 2.06) //App()->getClientScript()->registerCssFile(Yii::app()->getConfig('publicstyleurl') . 'jquery.multiselect.filter.css'); //$this->registerScriptFile( 'SCRIPT_PATH', 'jquery.multiselect.min.js'); $this->registerScriptFile('ADMIN_SCRIPT_PATH', 'checkgroup.js'); // TODO $aViewUrls['output'] .= "<script type='text/javascript'>\$(document).ready(function () { \$('#copytomultiselect').multiselect( { autoOpen: true, noneSelectedText: '" . gT("No questions selected") . "', checkAllText: '" . gT("Check all") . "', uncheckAllText: '" . gT("Uncheck all") . "', selectedText: '# " . gT("selected") . "', beforeclose: function(){ return false;},height: 200 } ); });</script>"; $aViewUrls['output'] .= "\t<div class='conditioncopy-tbl-row'>\n" . "\t<div class='condition-tbl-left'>" . gT("Copy the selected conditions to") . ":</div>\n" . "\t<div class='condition-tbl-right'>\n" . "\t\t<select class='form-control' name='copyconditionsto[]' id='copytomultiselect' multiple='multiple' >\n"; if (isset($pquestions) && count($pquestions) != 0) { foreach ($pquestions as $pq) { $aViewUrls['output'] .= "\t\t<option value='{$pq['fieldname']}'>" . $pq['text'] . "</option>\n"; } } $aViewUrls['output'] .= "\t\t</select>\n" . "\t</div>\n" . "\t</div>\n"; if (!isset($pquestions) || count($pquestions) == 0) { $disableCopyCondition = " disabled='disabled'"; } else { $disableCopyCondition = " "; } $aViewUrls['output'] .= "\t<div class='condition-tbl-full'>\n" . "<br/>\t\t<input class='btn btn-default' type='submit' value='" . gT("Copy conditions") . "' onclick=\"prepareCopyconditions(); return true;\" {$disableCopyCondition}/>\n" . "<input type='hidden' name='subaction' value='copyconditions' />\n" . "<input type='hidden' name='sid' value='{$iSurveyID}' />\n" . "<input type='hidden' name='gid' value='{$gid}' />\n" . "<input type='hidden' name='qid' value='{$qid}' />\n" . "</div>\n"; $aViewUrls['output'] .= "<script type=\"text/javascript\">\n" . "function prepareCopyconditions()\n" . "{\n" . "\t\$(\"input:checked[name^='aConditionFromScenario']\").each(function(i,val)\n" . "\t{\n" . "var thecid = val.value;\n" . "var theform = document.getElementById('copyconditions');\n" . "addHiddenElement(theform,'copyconditionsfrom[]',thecid);\n" . "return true;\n" . "\t});\n" . "}\n" . "</script>\n"; } else { $aViewUrls['output'] .= "<div class='messagebox ui-corner-all'>\n" . "<div class='partialheader'>" . gT("There are no existing conditions in this survey.") . "</div><br />\n" . "</div>\n"; } $aViewUrls['output'] .= "</form></td></tr>\n"; } // END: DISPLAY THE COPY CONDITIONS FORM if (isset($cquestions)) { if (count($cquestions) > 0 && count($cquestions) <= 10) { $qcount = count($cquestions); } else { $qcount = 9; } } else { $qcount = 0; } //BEGIN: DISPLAY THE ADD or EDIT CONDITION FORM if ($subaction == "editconditionsform" || $subaction == "insertcondition" || $subaction == "updatecondition" || $subaction == "deletescenario" || $subaction == "renumberscenarios" || $subaction == "deleteallconditions" || $subaction == "updatescenario" || $subaction == "editthiscondition" || $subaction == "delete") { $mytitle = $subaction == "editthiscondition" && isset($p_cid) ? gT("Edit condition") : gT("Add condition"); $scenario = ''; $showScenario = $subaction != "editthiscondition" && isset($scenariocount) && ($scenariocount == 1 || $scenariocount == 0) || $subaction == "editthiscondition" && $scenario == 1 ? true : false; $aDataEditconditions = array('subaction' => $subaction, 'iSurveyID' => $iSurveyID, 'gid' => $gid, 'qid' => $qid, 'mytitle' => $mytitle, 'showScenario' => $showScenario, 'qcountI' => $qcount + 1); $aViewUrls['output'] .= $this->getController()->renderPartial('/admin/conditions/includes/form_editconditions_header', $aDataEditconditions, true); //form_editconditions_header if (isset($cquestions)) { $js_getAnswers_onload = ""; foreach ($cquestions as $cqn) { $aViewUrls['output'] .= "<option value='{$cqn['3']}' title=\"" . htmlspecialchars($cqn[0]) . "\""; if (isset($p_cquestions) && $cqn[3] == $p_cquestions) { $aViewUrls['output'] .= " selected"; if (isset($p_canswers)) { $canswersToSelect = ""; foreach ($p_canswers as $checkval) { $canswersToSelect .= ";{$checkval}"; } $canswersToSelect = substr($canswersToSelect, 1); $js_getAnswers_onload .= "\$('#canswersToSelect').val('{$canswersToSelect}');\n"; } } $aViewUrls['output'] .= ">{$cqn['0']}</option>\n"; } } $aViewUrls['output'] .= "</select>\n" . "</div>\n"; // Source token Tab $aViewUrls['output'] .= "<div id='SRCTOKENATTRS' class='tab-pane fade in'><select class='form-control' name='csrctoken' id='csrctoken' >\n"; foreach (getTokenFieldsAndNames($iSurveyID) as $tokenattr => $tokenattrName) { // Check to select if (isset($p_csrctoken) && $p_csrctoken == '{TOKEN:' . strtoupper($tokenattr) . '}') { $selectThisSrcTokenAttr = "selected=\"selected\""; } else { $selectThisSrcTokenAttr = ""; } $aViewUrls['output'] .= "<option value='{TOKEN:" . strtoupper($tokenattr) . "}' {$selectThisSrcTokenAttr}>" . HTMLEscape($tokenattrName['description']) . "</option>\n"; } $aViewUrls['output'] .= "</select>\n </div>\n\n"; $aViewUrls['output'] .= "\t</div>\n"; // end conditionsource div $aViewUrls['output'] .= "\t</div>\n"; // end tab-content div $aViewUrls['output'] .= "</div>\n </div>\n"; // Begin "Comparison operator" row $aViewUrls['output'] .= "<div class='condition-tbl-row'>\n" . "<div class='condition-tbl-left'>" . gT("Comparison operator") . "</div>\n" . "<div class='condition-tbl-right'>\n" . "<select class='form-control' name='method' id='method'>\n"; foreach ($method as $methodCode => $methodTxt) { $selected = $methodCode == "==" ? " selected='selected'" : ""; $aViewUrls['output'] .= "\t<option value='" . $methodCode . "'{$selected}>" . $methodTxt . "</option>\n"; } $aViewUrls['output'] .= "</select>\n" . "</div>\n" . "</div>\n"; // Begin "Answer" row $aViewUrls['output'] .= "<div class='condition-tbl-row'>\n" . "<div class='condition-tbl-left'>" . gT("Answer") . "</div>\n"; if ($subaction == "editthiscondition") { $multipletext = ""; if (isset($_POST['EDITConditionConst']) && $_POST['EDITConditionConst'] != '') { $EDITConditionConst = HTMLEscape($_POST['EDITConditionConst']); } else { $EDITConditionConst = ""; } if (isset($_POST['EDITConditionRegexp']) && $_POST['EDITConditionRegexp'] != '') { $EDITConditionRegexp = HTMLEscape($_POST['EDITConditionRegexp']); } else { $EDITConditionRegexp = ""; } } else { $multipletext = "multiple"; if (isset($_POST['ConditionConst']) && $_POST['ConditionConst'] != '') { $EDITConditionConst = HTMLEscape($_POST['ConditionConst']); } else { $EDITConditionConst = ""; } if (isset($_POST['ConditionRegexp']) && $_POST['ConditionRegexp'] != '') { $EDITConditionRegexp = HTMLEscape($_POST['ConditionRegexp']); } else { $EDITConditionRegexp = ""; } } $aViewUrls['output'] .= "" . "<div class='condition-tbl-right'>\n" . "<div id=\"conditiontarget\">\n" . "\t<ul class='nav nav-tabs'>\n" . "\t\t<li role='presentation' class='active'><a data-toggle='tab' href=\"#CANSWERSTAB\"><span>" . gT("Predefined") . "</span></a></li>\n" . "\t\t<li role='presentation'><a data-toggle='tab' href=\"#CONST\"><span>" . gT("Constant") . "</span></a></li>\n" . "\t\t<li role='presentation'><a data-toggle='tab' href=\"#PREVQUESTIONS\"><span>" . gT("Questions") . "</span></a></li>\n" . "\t\t<li role='presentation'><a data-toggle='tab' href=\"#TOKENATTRS\"><span>" . gT("Token fields") . "</span></a></li>\n" . "\t\t<li role='presentation'><a data-toggle='tab' href=\"#REGEXP\"><span>" . gT("RegExp") . "</span></a></li>\n" . "\t</ul>\n"; // Predefined answers tab $aViewUrls['output'] .= "\t<div class='tab-content'>\n"; $aViewUrls['output'] .= "\t<div id='CANSWERSTAB' class='tab-pane fade in active'>\n" . "\t\t<select class='form-control' name='canswers[]' {$multipletext} id='canswers' size='7'>\n" . "\t\t</select>\n" . "\t\t<br /><span id='canswersLabel'>" . gT("Predefined answer options for this question") . "</span>\n" . "\t</div>\n"; // Constant tab $aViewUrls['output'] .= "\t<div id='CONST' class='tab-pane fade in'>\n" . "\t\t<textarea name='ConditionConst' id='ConditionConst' rows='5' cols='113'>{$EDITConditionConst}</textarea>\n" . "\t\t<br /><div id='ConditionConstLabel'>" . gT("Constant value") . "</div>\n" . "\t</div>\n"; // Previous answers tab @SGQA@ placeholders $aViewUrls['output'] .= "\t<div id='PREVQUESTIONS' class='tab-pane fade in'>\n" . "\t\t<br /><label for='prevQuestionSGQA'>" . gT("Answer from previous question") . "</label>\n" . "\t\t<select class='form-control' name='prevQuestionSGQA' id='prevQuestionSGQA' size='7'>\n"; foreach ($cquestions as $cqn) { // building the @SGQA@ placeholders options if ($cqn[2] != 'M' && $cqn[2] != 'P') { // Type M or P aren't real fieldnames and thus can't be used in @SGQA@ placehodlers $aViewUrls['output'] .= "\t\t<option value='@{$cqn['3']}@' title=\"" . htmlspecialchars($cqn[0]) . "\""; if (isset($p_prevquestionsgqa) && $p_prevquestionsgqa == "@" . $cqn[3] . "@") { $aViewUrls['output'] .= " selected='selected'"; } $aViewUrls['output'] .= ">{$cqn['0']}</option>\n"; } } $aViewUrls['output'] .= "\t\t</select>\n" . "\t</div>\n"; // Token tab $aViewUrls['output'] .= "\t<div id='TOKENATTRS' class='tab-pane fade in'>\n" . "\t\t<br /><label for='tokenAttr'>" . gT("Attributes of the survey participant") . "</label>\n" . "\t\t<select class='form-control' name='tokenAttr' id='tokenAttr' size='7'>\n"; foreach (getTokenFieldsAndNames($iSurveyID) as $tokenattr => $tokenattrName) { $aViewUrls['output'] .= "\t\t<option value='{TOKEN:" . strtoupper($tokenattr) . "}'>" . HTMLEscape($tokenattrName['description']) . "</option>\n"; } $aViewUrls['output'] .= "\t\t</select>\n" . "\t</div>\n"; // Regexp Tab $aViewUrls['output'] .= "\t<div id='REGEXP' class='tab-pane fade in'>\n" . "\t\t<textarea name='ConditionRegexp' id='ConditionRegexp' rows='5' cols='113'>{$EDITConditionRegexp}</textarea>\n" . "\t\t<br /><div id='ConditionRegexpLabel'><a href=\"http://manual.limesurvey.org/wiki/Using_regular_expressions\" target=\"_blank\">" . gT("Regular expression") . "</a></div>\n" . "\t</div>\n"; $aViewUrls['output'] .= "</div>\n"; // end conditiontarget div $this->registerScriptFile('ADMIN_SCRIPT_PATH', 'conditions.js'); if ($subaction == "editthiscondition" && isset($p_cid)) { $submitLabel = gT("Update condition"); $submitSubaction = "updatecondition"; $submitcid = sanitize_int($p_cid); } else { $submitLabel = gT("Add condition"); $submitSubaction = "insertcondition"; $submitcid = ""; } $aViewUrls['output'] .= "</div>\n" . "</div>\n"; // Begin buttons row $aViewUrls['output'] .= "<div class='condition-tbl-full'>\n" . "\t<input type='reset' class='btn btn-default' id='resetForm' value='" . gT("Clear") . "' />\n" . "\t<input type='submit' class='btn btn-default' value='" . $submitLabel . "' />\n" . "<input type='hidden' name='sid' value='{$iSurveyID}' />\n" . "<input type='hidden' name='gid' value='{$gid}' />\n" . "<input type='hidden' name='qid' value='{$qid}' />\n" . "<input type='hidden' name='subaction' value='{$submitSubaction}' />\n" . "<input type='hidden' name='cqid' id='cqid' value='' />\n" . "<input type='hidden' name='cid' id='cid' value='" . $submitcid . "' />\n" . "<input type='hidden' name='editTargetTab' id='editTargetTab' value='' />\n" . "<input type='hidden' name='editSourceTab' id='editSourceTab' value='' />\n" . "<input type='hidden' name='canswersToSelect' id='canswersToSelect' value='' />\n" . "</div>\n" . "</form>\n"; if (!isset($js_getAnswers_onload)) { $js_getAnswers_onload = ''; } $aViewUrls['output'] .= "<script type='text/javascript'>\n" . "<!--\n" . "\t" . $js_getAnswers_onload . "\n"; if (isset($p_method)) { $aViewUrls['output'] .= "\tdocument.getElementById('method').value='" . $p_method . "';\n"; } if ($subaction == "editthiscondition") { // in edit mode we read previous values in order to dusplay them in the corresponding inputs if (isset($_POST['EDITConditionConst']) && $_POST['EDITConditionConst'] != '') { // In order to avoid issues with backslash escaping, I don't use javascript to set the value // Thus the value is directly set when creating the Textarea element //$aViewUrls['output'] .= "\tdocument.getElementById('ConditionConst').value='".HTMLEscape($_POST['EDITConditionConst'])."';\n"; $aViewUrls['output'] .= "\tdocument.getElementById('editTargetTab').value='#CONST';\n"; } elseif (isset($_POST['EDITprevQuestionSGQA']) && $_POST['EDITprevQuestionSGQA'] != '') { $aViewUrls['output'] .= "\tdocument.getElementById('prevQuestionSGQA').value='" . HTMLEscape($_POST['EDITprevQuestionSGQA']) . "';\n"; $aViewUrls['output'] .= "\tdocument.getElementById('editTargetTab').value='#PREVQUESTIONS';\n"; } elseif (isset($_POST['EDITtokenAttr']) && $_POST['EDITtokenAttr'] != '') { $aViewUrls['output'] .= "\tdocument.getElementById('tokenAttr').value='" . HTMLEscape($_POST['EDITtokenAttr']) . "';\n"; $aViewUrls['output'] .= "\tdocument.getElementById('editTargetTab').value='#TOKENATTRS';\n"; } elseif (isset($_POST['EDITConditionRegexp']) && $_POST['EDITConditionRegexp'] != '') { // In order to avoid issues with backslash escaping, I don't use javascript to set the value // Thus the value is directly set when creating the Textarea element //$aViewUrls['output'] .= "\tdocument.getElementById('ConditionRegexp').value='".HTMLEscape($_POST['EDITConditionRegexp'])."';\n"; $aViewUrls['output'] .= "\tdocument.getElementById('editTargetTab').value='#REGEXP';\n"; } elseif (isset($_POST['EDITcanswers']) && is_array($_POST['EDITcanswers'])) { // was a predefined answers post $aViewUrls['output'] .= "\tdocument.getElementById('editTargetTab').value='#CANSWERSTAB';\n"; $aViewUrls['output'] .= "\t\$('#canswersToSelect').val('" . $_POST['EDITcanswers'][0] . "');\n"; } if (isset($_POST['csrctoken']) && $_POST['csrctoken'] != '') { $aViewUrls['output'] .= "\tdocument.getElementById('csrctoken').value='" . HTMLEscape($_POST['csrctoken']) . "';\n"; $aViewUrls['output'] .= "\tdocument.getElementById('editSourceTab').value='#SRCTOKENATTRS';\n"; } else { if (isset($_POST['cquestions']) && $_POST['cquestions'] != '') { $aViewUrls['output'] .= "\tdocument.getElementById('cquestions').value='" . HTMLEscape($_POST['cquestions']) . "';\n"; $aViewUrls['output'] .= "\tdocument.getElementById('editSourceTab').value='#SRCPREVQUEST';\n"; } } } else { // in other modes, for the moment we do the same as for edit mode if (isset($_POST['ConditionConst']) && $_POST['ConditionConst'] != '') { // In order to avoid issues with backslash escaping, I don't use javascript to set the value // Thus the value is directly set when creating the Textarea element //$aViewUrls['output'] .= "\tdocument.getElementById('ConditionConst').value='".HTMLEscape($_POST['ConditionConst'])."';\n"; $aViewUrls['output'] .= "\tdocument.getElementById('editTargetTab').value='#CONST';\n"; } elseif (isset($_POST['prevQuestionSGQA']) && $_POST['prevQuestionSGQA'] != '') { $aViewUrls['output'] .= "\tdocument.getElementById('prevQuestionSGQA').value='" . HTMLEscape($_POST['prevQuestionSGQA']) . "';\n"; $aViewUrls['output'] .= "\tdocument.getElementById('editTargetTab').value='#PREVQUESTIONS';\n"; } elseif (isset($_POST['tokenAttr']) && $_POST['tokenAttr'] != '') { $aViewUrls['output'] .= "\tdocument.getElementById('tokenAttr').value='" . HTMLEscape($_POST['tokenAttr']) . "';\n"; $aViewUrls['output'] .= "\tdocument.getElementById('editTargetTab').value='#TOKENATTRS';\n"; } elseif (isset($_POST['ConditionRegexp']) && $_POST['ConditionRegexp'] != '') { // In order to avoid issues with backslash escaping, I don't use javascript to set the value // Thus the value is directly set when creating the Textarea element //$aViewUrls['output'] .= "\tdocument.getElementById('ConditionRegexp').value='".HTMLEscape($_POST['ConditionRegexp'])."';\n"; $aViewUrls['output'] .= "\tdocument.getElementById('editTargetTab').value='#REGEXP';\n"; } else { // was a predefined answers post if (isset($_POST['cquestions'])) { $aViewUrls['output'] .= "\tdocument.getElementById('cquestions').value='" . HTMLEscape($_POST['cquestions']) . "';\n"; } $aViewUrls['output'] .= "\tdocument.getElementById('editTargetTab').value='#CANSWERSTAB';\n"; } if (isset($_POST['csrctoken']) && $_POST['csrctoken'] != '') { $aViewUrls['output'] .= "\tdocument.getElementById('csrctoken').value='" . HTMLEscape($_POST['csrctoken']) . "';\n"; $aViewUrls['output'] .= "\tdocument.getElementById('editSourceTab').value='#SRCTOKENATTRS';\n"; } else { if (isset($_POST['cquestions'])) { $aViewUrls['output'] .= "\tdocument.getElementById('cquestions').value='" . javascriptEscape($_POST['cquestions']) . "';\n"; } $aViewUrls['output'] .= "\tdocument.getElementById('editSourceTab').value='#SRCPREVQUEST';\n"; } } if (isset($p_scenario)) { $aViewUrls['output'] .= "\tdocument.getElementById('scenario').value='" . $p_scenario . "';\n"; } $aViewUrls['output'] .= "-->\n" . "</script>\n"; } //END: DISPLAY THE ADD or EDIT CONDITION FORM $conditionsoutput = $aViewUrls['output']; $aData['conditionsoutput'] = $conditionsoutput; $this->_renderWrappedTemplate('conditions', $aViewUrls, $aData); // TMSW Condition->Relevance: Must call LEM->ConvertConditionsToRelevance() whenever Condition is added or updated - what is best location for that action? }
/** * Return the question text part without any subquestion * * @param Survey $oSurvey * @param FormattingOptions $oOptions * @param string $fieldName * @return string */ public function getFullQuestionHeading(SurveyObj $oSurvey, FormattingOptions $oOptions, $fieldName) { if (isset($oSurvey->fieldMap[$fieldName])) { $aField = $oSurvey->fieldMap[$fieldName]; return viewHelper::flatEllipsizeText($aField['question'], true, $oOptions->headingTextLength, ".. "); } return false; }
/** * displayResults builds html output to display the actual results from a survey * * @param mixed $outputs * @param INT $results The number of results being displayed overall * @param mixed $rt * @param mixed $outputType * @param mixed $surveyid * @param mixed $sql * @param mixed $usegraph * * */ protected function displayResults($outputs, $results, $rt, $outputType, $surveyid, $sql, $usegraph, $browse, $sLanguage) { /* Set up required variables */ $TotalCompleted = 0; //Count of actually completed answers $statisticsoutput = ""; $sDatabaseType = Yii::app()->db->getDriverName(); $tempdir = Yii::app()->getConfig("tempdir"); $tempurl = Yii::app()->getConfig("tempurl"); $firstletter = substr($rt, 0, 1); $astatdata = array(); if ($usegraph == 1 && $outputType != 'html') { //for creating graphs we need some more scripts which are included here require_once APPPATH . '/third_party/pchart/pchart/pChart.class'; require_once APPPATH . '/third_party/pchart/pchart/pData.class'; require_once APPPATH . '/third_party/pchart/pchart/pCache.class'; $MyCache = new pCache($tempdir . '/'); } switch ($outputType) { case 'xls': $xlsTitle = sprintf(gT("Field summary for %s"), html_entity_decode($outputs['qtitle'], ENT_QUOTES, 'UTF-8')); $xlsDesc = html_entity_decode($outputs['qquestion'], ENT_QUOTES, 'UTF-8'); $this->xlsRow++; $this->xlsRow++; $this->xlsRow++; $this->sheet->write($this->xlsRow, 0, $xlsTitle); $this->xlsRow++; $this->sheet->write($this->xlsRow, 0, $xlsDesc); $footXLS = array(); break; case 'pdf': $sPDFQuestion = flattenText($outputs['qquestion'], false, true); $pdfTitle = $this->pdf->delete_html(sprintf(gT("Field summary for %s"), html_entity_decode($outputs['qtitle'], ENT_QUOTES, 'UTF-8'))); $titleDesc = $sPDFQuestion; $this->pdf->AddPage('P', 'A4'); $this->pdf->Bookmark($sPDFQuestion, 1, 0); $this->pdf->titleintopdf($pdfTitle, $sPDFQuestion); $tablePDF = array(); $footPDF = array(); break; case 'html': // output now generated in subview _statisticsoutuput_header break; default: break; } //loop though the array which contains all answer data $ColumnName_RM = array(); //echo '<pre>'; var_dump($outputs['alist']); echo '</pre>';die; foreach ($outputs['alist'] as $al) { //picks out answer list ($outputs['alist']/$al)) that come from the multiple list above if (isset($al[2]) && $al[2]) { //handling for "other" option if ($al[0] == gT("Other")) { if ($outputs['qtype'] == '!' || $outputs['qtype'] == 'L') { // It is better for single choice question types to filter on the number of '-oth-' entries, than to // just count the number of 'other' values - that way with failing Javascript the statistics don't get messed up /* This query selects a count of responses where "other" has been selected */ $query = "SELECT count(*) FROM {{survey_{$surveyid}}} WHERE " . Yii::app()->db->quoteColumnName(substr($al[2], 0, strlen($al[2]) - 5)) . "='-oth-'"; } else { //get data - select a count of responses where no answer is provided $query = "SELECT count(*) FROM {{survey_{$surveyid}}} WHERE "; $query .= $sDatabaseType == "mysql" ? Yii::app()->db->quoteColumnName($al[2]) . " != ''" : "NOT (" . Yii::app()->db->quoteColumnName($al[2]) . " LIKE '')"; } } elseif ($outputs['qtype'] == "U" || $outputs['qtype'] == "T" || $outputs['qtype'] == "S" || $outputs['qtype'] == "Q" || $outputs['qtype'] == ";") { $sDatabaseType = Yii::app()->db->getDriverName(); //free text answers if ($al[0] == "Answer") { $query = "SELECT count(*) FROM {{survey_{$surveyid}}} WHERE "; $query .= $sDatabaseType == "mysql" ? Yii::app()->db->quoteColumnName($al[2]) . " != ''" : "NOT (" . Yii::app()->db->quoteColumnName($al[2]) . " LIKE '')"; } elseif ($al[0] == "NoAnswer") { $query = "SELECT count(*) FROM {{survey_{$surveyid}}} WHERE ( "; $query .= $sDatabaseType == "mysql" ? Yii::app()->db->quoteColumnName($al[2]) . " = '')" : " (" . Yii::app()->db->quoteColumnName($al[2]) . " LIKE ''))"; } } elseif ($outputs['qtype'] == "O") { $query = "SELECT count(*) FROM {{survey_{$surveyid}}} WHERE ( "; $query .= $sDatabaseType == "mysql" ? Yii::app()->db->quoteColumnName($al[2]) . " <> '')" : " (" . Yii::app()->db->quoteColumnName($al[2]) . " NOT LIKE ''))"; // all other question types } else { $query = "SELECT count(*) FROM {{survey_{$surveyid}}} WHERE " . Yii::app()->db->quoteColumnName($al[2]) . " ="; //ranking question? if (substr($rt, 0, 1) == "R") { $query .= " '{$al['0']}'"; } else { $query .= " 'Y'"; } } } else { if ($al[0] != "") { //get more data $sDatabaseType = Yii::app()->db->getDriverName(); if ($sDatabaseType == 'mssql' || $sDatabaseType == 'sqlsrv' || $sDatabaseType == 'dblib') { // mssql cannot compare text blobs so we have to cast here $query = "SELECT count(*) FROM {{survey_{$surveyid}}} WHERE cast(" . Yii::app()->db->quoteColumnName($rt) . " as varchar)= '{$al['0']}'"; } else { $query = "SELECT count(*) FROM {{survey_{$surveyid}}} WHERE " . Yii::app()->db->quoteColumnName($rt) . " = '{$al['0']}'"; } } else { // This is for the 'NoAnswer' case // We need to take into account several possibilities // * NoAnswer cause the participant clicked the NoAnswer radio // ==> in this case value is '' or ' ' // * NoAnswer in text field // ==> value is '' // * NoAnswer due to conditions, or a page not displayed // ==> value is NULL if ($sDatabaseType == 'mssql' || $sDatabaseType == 'sqlsrv' || $sDatabaseType == 'dblib') { // mssql cannot compare text blobs so we have to cast here //$query = "SELECT count(*) FROM {{survey_$surveyid}} WHERE (".sanitize_int($rt)." IS NULL " $query = "SELECT count(*) FROM {{survey_{$surveyid}}} WHERE ( " . "cast(" . Yii::app()->db->quoteColumnName($rt) . " as varchar) = '' " . "OR cast(" . Yii::app()->db->quoteColumnName($rt) . " as varchar) = ' ' )"; } elseif ($sDatabaseType == 'pgsql') { $query = "SELECT count(*) FROM {{survey_{$surveyid}}} WHERE ( " . " " . Yii::app()->db->quoteColumnName($rt) . "::text = '' " . "OR " . Yii::app()->db->quoteColumnName($rt) . "::text = ' ') "; } else { $query = "SELECT count(*) FROM {{survey_{$surveyid}}} WHERE ( " . " " . Yii::app()->db->quoteColumnName($rt) . " = '' " . "OR " . Yii::app()->db->quoteColumnName($rt) . " = ' ') "; } } } //check filter option if (incompleteAnsFilterState() == "incomplete") { $query .= " AND submitdate is null"; } elseif (incompleteAnsFilterState() == "complete") { $query .= " AND submitdate is not null"; } //check for any "sql" that has been passed from another script if (!empty($sql)) { $query .= " AND {$sql}"; } //get data $row = Yii::app()->db->createCommand($query)->queryScalar(); //store temporarily value of answer count of question type '5' and 'A'. $tempcount = -1; //count can't be less han zero //increase counter $TotalCompleted += $row; //"no answer" handling if ($al[0] === "") { $fname = gT("No answer"); } elseif ($al[0] === gT("Other") || $al[0] === "Answer" || $outputs['qtype'] === "O" && $al[0] === gT("Comments") || $outputs['qtype'] === "P") { if ($outputs['qtype'] == "P") { $sColumnName = $al[2] . "comment"; } else { $sColumnName = $al[2]; } $ColumnName_RM[] = $sColumnName; if ($outputs['qtype'] == 'O') { $TotalCompleted -= $row; } $fname = "{$al['1']}"; if ($browse === true) { $fname .= " <input type='button' class='statisticsbrowsebutton btn btn-default btn-large' value='" . gT("Browse") . "' id='{$sColumnName}' />"; } if ($browse === true && isset($_POST['showtextinline']) && $outputType == 'pdf') { $headPDF2 = array(); $headPDF2[] = array(gT("ID"), gT("Response")); $tablePDF2 = array(); $result2 = $this->_listcolumn($surveyid, $sColumnName); foreach ($result2 as $row2) { $tablePDF2[] = array($row2['id'], $row2['value']); } } if ($browse === true && isset($_POST['showtextinline']) && $outputType == 'xls') { $headXLS = array(); $tableXLS = array(); $headXLS[] = array(gT("ID"), gT("Response")); $result2 = $this->_listcolumn($surveyid, $sColumnName); foreach ($result2 as $row2) { $tableXLS[] = array($row2['id'], $row2['value']); } } } elseif ($outputs['qtype'] == "S" || $outputs['qtype'] == "U" || $outputs['qtype'] == "T" || $outputs['qtype'] == "Q") { $headPDF = array(); $headPDF[] = array(gT("Answer"), gT("Count"), gT("Percentage")); //show free text answers if ($al[0] == "Answer") { $fname = "{$al['1']}"; if ($browse === true) { $fname .= " <input type='button' class='statisticsbrowsebutton btn btn-default btn-large' value='" . gT("Browse") . "' id='{$sColumnName}' />"; } } elseif ($al[0] == "NoAnswer") { $fname = "{$al['1']}"; } $bShowCount = true; $bShowPercentage = true; $bAnswer = true; // For view $bSum = false; if ($browse === true && isset($_POST['showtextinline']) && $outputType == 'pdf') { $headPDF2 = array(); $headPDF2[] = array(gT("ID"), gT("Response")); $tablePDF2 = array(); $result2 = $this->_listcolumn($surveyid, $sColumnName); foreach ($result2 as $row2) { $tablePDF2[] = array($row2['id'], $row2['value']); } } } elseif (Yii::app()->getConfig('showaggregateddata') == 1) { if (!isset($showheadline) || $showheadline != false) { if ($outputs['qtype'] == "5" || $outputs['qtype'] == "A") { switch ($outputType) { case 'xls': $this->xlsRow++; $this->sheet->write($this->xlsRow, 0, gT("Answer")); $this->sheet->write($this->xlsRow, 1, gT("Count")); $this->sheet->write($this->xlsRow, 2, gT("Percentage")); $this->sheet->write($this->xlsRow, 3, gT("Sum")); break; case 'pdf': $headPDF = array(); $headPDF[] = array(gT("Answer"), gT("Count"), gT("Percentage"), gT("Sum")); break; case 'html': //four columns $bShowCount = true; $bShowPercentage = true; $bAnswer = true; $bSum = true; break; default: break; } $showheadline = false; } else { switch ($outputType) { case 'xls': $this->xlsRow++; $this->sheet->write($this->xlsRow, 0, gT("Answer")); $this->sheet->write($this->xlsRow, 1, gT("Count")); $this->sheet->write($this->xlsRow, 2, gT("Percentage")); break; case 'pdf': $headPDF = array(); $headPDF[] = array(gT("Answer"), gT("Count"), gT("Percentage")); break; case 'html': //three columns $bAnswer = true; // For view $bSum = false; $bShowCount = true; $bShowPercentage = true; break; default: break; } $showheadline = false; } } //text for answer column is always needed $fname = "{$al['1']} ({$al['0']})"; } else { if (!isset($showheadline) || $showheadline != false) { switch ($outputType) { case 'xls': $this->xlsRow++; $this->sheet->write($this->xlsRow, 0, gT("Answer")); $this->sheet->write($this->xlsRow, 1, gT("Count")); $this->sheet->write($this->xlsRow, 2, gT("Percentage")); break; case 'pdf': $headPDF = array(); $headPDF[] = array(gT("Answer"), gT("Count"), gT("Percentage")); break; case 'html': //three columns $bAnswer = true; // For view $bSum = false; $bShowCount = true; $bShowPercentage = true; break; default: break; } $showheadline = false; } //answer text $fname = "{$al['1']} ({$al['0']})"; } //are there some results to play with? if ($results > 0) { //calculate percentage $gdata[] = $row / $results * 100; } else { //no data! $gdata[] = "N/A"; } //put absolute data into array $grawdata[] = $row; if (!(in_array('is_comment', $al) || in_array('is_no_answer', $al))) { $grawdata_percents[] = $row; } //var_dump($grawdata); die(); //put question title and code into array $label[] = $fname; //put only the code into the array $justcode[] = $al[0]; //edit labels and put them into antoher array //first check if $tempcount is > 0. If yes, $row has been modified and $tempcount has the original count. if ($tempcount > -1) { $flatLabel = wordwrap(FlattenText("{$al['1']}"), 25, "\n"); // If the flatten label is empty (like for picture, or HTML, etc.) // We replace it by the subquestion code if ($flatLabel == '') { $flatLabel = $al[0]; } // For legend $lbl[$flatLabel] = $tempcount; } else { $flatLabel = wordwrap(FlattenText("{$al['1']}"), 25, "\n"); // If the flatten label is empty (like for picture, or HTML, etc.) // We replace it by the subquestion code if ($flatLabel == '') { $flatLabel = $al[0]; } $lbl[$flatLabel] = $row; } // For Graph labels switch ($_POST['graph_labels']) { case 'qtext': $aGraphLabels[] = $sFlatLabel = $flatLabel; break; case 'both': $aGraphLabels[] = $sFlatLabel = $al[0] . ': ' . $flatLabel; break; default: $aGraphLabels[] = $sFlatLabel = $al[0]; break; } if (!(in_array('is_comment', $al) || in_array('is_no_answer', $al))) { $aGraphLabelsPercent[] = $sFlatLabel; $lblPercent[$flatLabel] = $lbl[$flatLabel]; } } //end foreach -> loop through answer data //no filtering of incomplete answers and NO multiple option questions //if ((incompleteAnsFilterState() != "complete") and ($outputs['qtype'] != "M") and ($outputs['qtype'] != "P")) //error_log("TIBO ".print_r($showaggregated_indice_table,true)); if ($outputs['qtype'] != "M" and $outputs['qtype'] != "P") { //is the checkbox "Don't consider NON completed responses (only works when Filter incomplete answers is Disable)" checked? //if (isset($_POST[''noncompleted']) and ($_POST['noncompleted'] == 1) && (isset(Yii::app()->getConfig('showaggregateddata')) && Yii::app()->getConfig('showaggregateddata') == 0)) // TIBO: TODO WE MUST SKIP THE FOLLOWING SECTION FOR TYPE A and 5 when // showaggreagated data is set and set to 1 if (isset($_POST['noncompleted']) and $_POST['noncompleted'] == 1) { //counter $i = 0; while (isset($gdata[$i])) { if (isset($showaggregated_indice_table[$i]) && $showaggregated_indice_table[$i] == "aggregated") { // do nothing, we don't rewrite aggregated results // or at least I don't know how !!! (lemeur) } else { //we want to have some "real" data here if ($gdata[$i] != "N/A") { //calculate percentage $gdata[$i] = $grawdata[$i] / $TotalCompleted * 100; } } //increase counter $i++; } //end while (data available) } else { //calculate total number of incompleted records $TotalIncomplete = $results - $TotalCompleted; //output if (incompleteAnsFilterState() != "complete") { $fname = gT("Not completed or Not displayed"); } else { $fname = gT("Not displayed"); } //we need some data if ($results > 0) { //calculate percentage $gdata[] = $TotalIncomplete / $results * 100; } else { $gdata[] = "N/A"; } //put data of incompleted records into array $grawdata[] = $TotalIncomplete; //put question title ("Not completed") into array $label[] = $fname; //put the code ("Not completed") into the array $justcode[] = $fname; //edit labels and put them into another array if (incompleteAnsFilterState() != "complete") { $flatLabel = gT("Not completed or Not displayed"); // If the flatten label is empty (like for picture, or HTML, etc.) // We replace it by the subquestion code if ($flatLabel == '') { $flatLabel = $al[0]; } $lbl[$flatLabel] = $TotalIncomplete; } else { $flatLabel = gT("Not displayed"); // If the flatten label is empty (like for picture, or HTML, etc.) // We replace it by the subquestion code if ($flatLabel == '') { $flatLabel = $al[0]; } $lbl[$flatLabel] = $TotalIncomplete; } } //end else -> noncompleted NOT checked } // For multi question type, we have to check non completed with ALL sub question set to NULL if ($outputs['qtype'] == "M" or $outputs['qtype'] == "P") { $criteria = new CDbCriteria(); foreach ($outputs['alist'] as $al) { $criteria->addCondition(Yii::app()->db->quoteColumnName($al[2]) . " IS NULL"); } if (incompleteAnsFilterState() == "incomplete") { $criteria->addCondition("submitdate IS NULL"); } elseif (incompleteAnsFilterState() == "complete") { $criteria->addCondition("submitdate IS NOT NULL"); } $multiNotDisplayed = SurveyDynamic::model($surveyid)->count($criteria); if (isset($_POST['noncompleted']) and $_POST['noncompleted'] == 1) { //counter $i = 0; while (isset($gdata[$i])) { //we want to have some "real" data here if ($gdata[$i] != "N/A") { //calculate percentage if ($results > $multiNotDisplayed) { $gdata[$i] = $grawdata[$i] / ($results - $multiNotDisplayed) * 100; } else { $gdata[$i] = "N/A"; } } $i++; } } else { // Add a line with not displayed % if ($multiNotDisplayed > 0) { if (incompleteAnsFilterState() != "complete") { $fname = gT("Not completed or Not displayed"); } else { $fname = gT("Not displayed"); } $label[] = $fname; $lbl[$fname] = $multiNotDisplayed; //we need some data if ($results > 0) { //calculate percentage $gdata[] = $multiNotDisplayed / $results * 100; } else { $gdata[] = "N/A"; } //put data of incompleted records into array $grawdata[] = $multiNotDisplayed; } } } // Columns $statsColumns = $_POST['stats_columns']; switch ($statsColumns) { case "1": $nbcols = "12"; $canvaWidth = "1150"; $canvaHeight = "800"; break; case "3": $nbcols = "4"; $canvaWidth = "333"; $canvaHeight = "500"; break; default: $nbcols = "6"; $canvaWidth = "500"; $canvaHeight = "500"; break; } // //counter $i = 0; //we need to know which item we are editing $itemcounter = 1; $aData['nbcols'] = $nbcols; $aData['canvaWidth'] = $canvaWidth; $aData['canvaHeight'] = $canvaHeight; $aData['outputs'] = isset($outputs) ? $outputs : ''; $aData['bSum'] = isset($bSum) ? $bSum : false; $aData['bAnswer'] = isset($bAnswer) ? $bAnswer : false; $aData['bShowCount'] = isset($bShowCount) ? $bShowCount : false; $aData['bShowPercentage'] = isset($bShowPercentage) ? $bShowPercentage : false; $statisticsoutput = Yii::app()->getController()->renderPartial('/admin/export/generatestats/_statisticsoutput_header', $aData, true); //loop through all available answers //// while (isset($gdata[$i])) { $aData['i'] = $i; ///// We'll render at the end of this loop statisticsoutput_answer //repeat header (answer, count, ...) for each new question unset($showheadline); /* * there are 3 colums: * * 1 (50%) = answer (title and code in brackets) * 2 (25%) = count (absolute) * 3 (25%) = percentage */ /* * If there is a "browse" button in this label, let's make sure there's an extra row afterwards * to store the columnlist * * */ if (strpos($label[$i], "statisticsbrowsebutton")) { $extraline = "<tr><td class='statisticsbrowsecolumn' colspan='3' style='display: none'>"; if ($outputs['qtype'] == 'P') { $extraline .= "<div class='statisticsbrowsecolumn' id='columnlist_{$ColumnName_RM[$i]}'></div></td></tr>\n"; $sColumnNameForView = $ColumnName_RM[$i]; } else { $extraline .= "<div class='statisticsbrowsecolumn' id='columnlist_{$sColumnName}'></div></td></tr>\n"; $sColumnNameForView = $sColumnName; } } //no data if ($gdata[$i] === "N/A") { switch ($outputType) { case 'xls': $label[$i] = flattenText($label[$i]); $this->xlsRow++; $this->sheet->write($this->xlsRow, 0, $label[$i]); $this->sheet->writeNumber($this->xlsRow, 1, $grawdata[$i]); $this->sheet->writeNumber($this->xlsRow, 2, $gdata[$i] / 100, $this->xlsPercents); break; case 'pdf': $tablePDF[] = array(flattenText($label[$i]), $grawdata[$i], sprintf("%01.2f", $gdata[$i]) . "%", ""); break; case 'html': //output when having no data /// _statisticsoutput_answer $bNAgData = true; if (isset($extraline)) { $bNAgDataExtraLine = $extraline; } break; default: break; } } else { //check if data should be aggregated if (Yii::app()->getConfig('showaggregateddata') == 1 && ($outputs['qtype'] == "5" || $outputs['qtype'] == "A")) { //mark that we have done soemthing special here $aggregated = true; if ($results - $grawdata[5] > 0) { $percentage = $grawdata[$i] / ($results - $grawdata[5]) * 100; // Only answered } else { $percentage = 0; } switch ($itemcounter) { case 1: if ($results - $grawdata[5] > 0) { $aggregatedPercentage = ($grawdata[0] + $grawdata[1]) / ($results - $grawdata[5]) * 100; } else { $aggregatedPercentage = 0; } break; case 3: $aggregatedPercentage = $percentage; break; case 5: if ($results - $grawdata[5] > 0) { $aggregatedPercentage = ($grawdata[3] + $grawdata[4]) / ($results - $grawdata[5]) * 100; } else { $aggregatedPercentage = 0; } break; case 6: case 7: if ($results - $grawdata[5] > 0) { $percentage = $grawdata[$i] / $results * 100; // All results } else { $percentage = 0; } default: $aggregatedPercentage = 'na'; break; } switch ($outputType) { case 'xls': $label[$i] = flattenText($label[$i]); $this->xlsRow++; $this->sheet->write($this->xlsRow, 0, $label[$i]); $this->sheet->writeNumber($this->xlsRow, 1, $grawdata[$i]); $this->sheet->writeNumber($this->xlsRow, 2, $percentage / 100, $this->xlsPercents); if ($aggregatedPercentage !== 'na') { $this->sheet->writeNumber($this->xlsRow, 3, $aggregatedPercentage / 100, $this->xlsPercents); } break; case 'pdf': $label[$i] = flattenText($label[$i]); if ($aggregatedPercentage !== 'na') { $tablePDF[] = array($label[$i], $grawdata[$i], sprintf("%01.2f", $percentage) . "%", sprintf("%01.2f", $aggregatedPercentage) . "%"); } else { $tablePDF[] = array($label[$i], $grawdata[$i], sprintf("%01.2f", $percentage) . "%", ""); } break; case 'html': //output percentage $bNAgData = true; if ($aggregatedPercentage !== 'na') { $showAggregatedPercentage = true; } else { $showEmptyAggregatedPercentage = true; } break; default: break; } if ($itemcounter == 5) { // new row "sum" //calculate sum of items 1-5 $sumitems = $grawdata[0] + $grawdata[1] + $grawdata[2] + $grawdata[3] + $grawdata[4]; //special treatment for zero values if ($sumitems > 0) { $sumpercentage = "100.00"; } else { $sumpercentage = "0"; } //special treatment for zero values if ($TotalCompleted > 0) { $casepercentage = "100.00"; } else { $casepercentage = "0"; } switch ($outputType) { case 'xls': $footXLS[] = array(gT("Sum") . " (" . gT("Answers") . ")", $sumitems, $sumpercentage . "%", $sumpercentage . "%"); $footXLS[] = array(gT("Number of cases"), $TotalCompleted, $casepercentage . "%", ""); $this->xlsRow++; $this->sheet->write($this->xlsRow, 0, gT("Sum") . " (" . gT("Answers") . ")"); $this->sheet->writeNumber($this->xlsRow, 1, $sumitems); $this->sheet->writeNumber($this->xlsRow, 2, $sumpercentage / 100, $this->xlsPercents); $this->sheet->writeNumber($this->xlsRow, 3, $sumpercentage / 100, $this->xlsPercents); $this->xlsRow++; $this->sheet->write($this->xlsRow, 0, gT("Number of cases")); $this->sheet->writeNumber($this->xlsRow, 1, $TotalCompleted); $this->sheet->writeNumber($this->xlsRow, 2, $casepercentage / 100, $this->xlsPercents); break; case 'pdf': $footPDF[] = array(gT("Sum") . " (" . gT("Answers") . ")", $sumitems, $sumpercentage . "%", $sumpercentage . "%"); $footPDF[] = array(gT("Number of cases"), $TotalCompleted, $casepercentage . "%", ""); break; case 'html': $bShowSumAnswer = true; break; default: break; } } } else { switch ($outputType) { case 'xls': $label[$i] = flattenText($label[$i]); $this->xlsRow++; $this->sheet->write($this->xlsRow, 0, $label[$i]); $this->sheet->writeNumber($this->xlsRow, 1, $grawdata[$i]); $this->sheet->writeNumber($this->xlsRow, 2, $gdata[$i] / 100, $this->xlsPercents); break; case 'pdf': $label[$i] = flattenText($label[$i]); $tablePDF[] = array($label[$i], $grawdata[$i], sprintf("%01.2f", $gdata[$i]) . "%", ""); break; case 'html': //output percentage $bNAgData = true; if (isset($extraline)) { $bNAgDataExtraLine = $extraline; } break; default: break; } } } //end else -> $gdata[$i] != "N/A" //increase counter $i++; $itemcounter++; //Clear extraline unset($extraline); // Convert grawdata_percent to percent if (isset($grawdata_percents)) { $pTotal = array_sum($grawdata_percents); if ($pTotal > 0) { foreach ($grawdata_percents as $key => $data) { $grawdata_percents[$key] = round($data / $pTotal * 100, 2); } } } else { $grawdata_percents = array(); } ///// HERE RENDER statisticsoutput_answer $aData['label'] = $label; $aData['grawdata'] = $grawdata; $aData['grawdata_percent'] = $grawdata_percents; $aData['gdata'] = $gdata; $aData['extraline'] = isset($extraline) ? $extraline : false; $aData['aggregated'] = isset($aggregated) ? $aggregated : false; $aData['aggregatedPercentage'] = isset($aggregatedPercentage) ? $aggregatedPercentage : false; $aData['sumitems'] = isset($sumitems) ? $sumitems : false; $aData['sumpercentage'] = isset($sumpercentage) ? $sumpercentage : false; $aData['TotalCompleted'] = isset($TotalCompleted) ? $TotalCompleted : false; $aData['casepercentage'] = isset($casepercentage) ? $casepercentage : false; $aData['bNAgData'] = isset($bNAgData) ? $bNAgData : false; $aData['bNAgDataExtraLine'] = isset($bNAgDataExtraLine) ? $bNAgDataExtraLine : false; $aData['showAggregatedPercentage'] = isset($showAggregatedPercentage) ? $showAggregatedPercentage : false; $aData['showEmptyAggregatedPercentage'] = isset($showEmptyAggregatedPercentage) ? $showEmptyAggregatedPercentage : false; $aData['bShowSumAnswer'] = isset($bShowSumAnswer) ? $bShowSumAnswer : false; // Generate answer // _statisticsoutput_answer $statisticsoutput .= Yii::app()->getController()->renderPartial('/admin/export/generatestats/_statisticsoutput_answer', $aData, true); $extraline = false; $aggregated = false; $aggregatedPercentage = false; $sumitems = false; $sumpercentage = false; $TotalCompleted = false; $casepercentage = false; $bNAgData = false; $bNAgDataExtraLine = false; $showAggregatedPercentage = false; $showEmptyAggregatedPercentage = false; $bShowSumAnswer = false; } //end while $aData['showaggregateddata'] = false; //only show additional values when this setting is enabled if (Yii::app()->getConfig('showaggregateddata') == 1) { //it's only useful to calculate standard deviation and arithmetic means for question types //5 = 5 Point Scale //A = Array (5 Point Choice) if ($outputs['qtype'] == "5" || $outputs['qtype'] == "A") { $stddev = 0; $stddevarray = array_slice($grawdata, 0, 5, true); $am = 0; //calculate arithmetic mean if (isset($sumitems) && $sumitems > 0) { //calculate and round results //there are always 5 items for ($x = 0; $x < 5; $x++) { //create product of item * value $am += ($x + 1) * $stddevarray[$x]; } //prevent division by zero if (isset($stddevarray) && array_sum($stddevarray) > 0) { $am = round($am / array_sum($stddevarray), 2); } else { $am = 0; } //calculate standard deviation -> loop through all data /* * four steps to calculate the standard deviation * 1 = calculate difference between item and arithmetic mean and multiply with the number of elements * 2 = create sqaure value of difference * 3 = sum up square values * 4 = multiply result with 1 / (number of items) * 5 = get root */ for ($j = 0; $j < 5; $j++) { //1 = calculate difference between item and arithmetic mean $diff = $j + 1 - $am; //2 = create square value of difference $squarevalue = square($diff); //3 = sum up square values and multiply them with the occurence //prevent divison by zero if ($squarevalue != 0 && $stddevarray[$j] != 0) { $stddev += $squarevalue * $stddevarray[$j]; } } //4 = multiply result with 1 / (number of items (=5)) //There are two different formulas to calculate standard derivation //$stddev = $stddev / array_sum($stddevarray); //formula source: http://de.wikipedia.org/wiki/Standardabweichung //prevent division by zero if (array_sum($stddevarray) - 1 != 0 && $stddev != 0) { $stddev = $stddev / (array_sum($stddevarray) - 1); //formula source: http://de.wikipedia.org/wiki/Empirische_Varianz } else { $stddev = 0; } //5 = get root $stddev = sqrt($stddev); $stddev = round($stddev, 2); } switch ($outputType) { case 'xls': $this->xlsRow++; $this->sheet->write($this->xlsRow, 0, gT("Arithmetic mean")); $this->sheet->writeNumber($this->xlsRow, 1, $am); $this->xlsRow++; $this->sheet->write($this->xlsRow, 0, gT("Standard deviation")); $this->sheet->writeNumber($this->xlsRow, 1, $stddev); break; case 'pdf': $tablePDF[] = array(gT("Arithmetic mean"), $am, '', ''); $tablePDF[] = array(gT("Standard deviation"), $stddev, '', ''); break; case 'html': //calculate standard deviation $aData['am'] = $am; $aData['stddev'] = $stddev; $statisticsoutput .= Yii::app()->getController()->renderPartial('/admin/export/generatestats/_statisticsoutput_arithmetic', $aData, true); break; default: break; } } } if ($outputType == 'pdf') { //$tablePDF = array(); $tablePDF = array_merge_recursive($tablePDF, $footPDF); if (!isset($headPDF)) { // TODO: Why is $headPDF sometimes undefined here? $headPDF = array(); } $this->pdf->headTable($headPDF, $tablePDF); //$this->pdf->tableintopdf($tablePDF); // if(isset($footPDF)) // foreach($footPDF as $foot) // { // $footA = array($foot); // $this->pdf->tablehead($footA); // } if (isset($headPDF2)) { $this->pdf->headTable($headPDF2, $tablePDF2); } } if ($outputType == 'xls' && (isset($headXLS) || isset($tableXLS))) { if (isset($headXLS)) { $this->xlsRow++; $this->xlsRow++; foreach ($headXLS as $aRow) { $this->xlsRow++; $iColumn = 0; foreach ($aRow as $sValue) { $this->sheet->write($this->xlsRow, $iColumn, $sValue, $this->formatBold); $iColumn++; } } } if (isset($tableXLS)) { foreach ($tableXLS as $aRow) { $this->xlsRow++; $iColumn = 0; foreach ($aRow as $sValue) { $this->sheet->write($this->xlsRow, $iColumn, $sValue); $iColumn++; } } } } if ($outputType == 'html') { } // _statisticsoutput_graphs.php //-------------------------- PCHART OUTPUT ---------------------------- list($qsid, $qgid, $qqid) = explode("X", $rt, 3); $qsid = $surveyid; $aattr = getQuestionAttributeValues($outputs['parentqid'], substr($rt, 0, 1)); //PCHART has to be enabled and we need some data // if ($usegraph == 1) { $bShowGraph = $aattr["statistics_showgraph"] == "1"; $bAllowPieChart = $outputs['qtype'] != "M" && $outputs['qtype'] != "P"; $bAllowMap = isset($aattr["location_mapservice"]) && $aattr["location_mapservice"] == "1"; $bShowMap = $bAllowMap && $aattr["statistics_showmap"] == "1"; $bShowPieChart = $bAllowPieChart && (isset($aattr["statistics_graphtype"]) && $aattr["statistics_graphtype"] == "1"); $astatdata[$rt] = array('id' => $rt, 'sg' => $bShowGraph, 'ap' => $bAllowPieChart, 'am' => $bAllowMap, 'sm' => $bShowMap, 'sp' => $bShowPieChart); $stats = Yii::app()->session['stats']; $stats[$rt] = array('lbl' => $lbl, 'gdata' => $gdata, 'grawdata' => $grawdata); Yii::app()->session['stats'] = $stats; if ($bShowGraph == true) { $cachefilename = ''; if ($outputType == 'xls' || $outputType == 'pdf') { $cachefilename = createChart($qqid, $qsid, $bShowPieChart, $lbl, $gdata, $grawdata, $MyCache, $sLanguage, $outputs['qtype']); } if ($cachefilename || $outputType == 'html') { //introduce new counter if (!isset($ci)) { $ci = 0; } //increase counter, start value -> 1 $ci++; switch ($outputType) { case 'xls': /** * No Image for Excel... */ break; case 'pdf': $this->pdf->AddPage('P', 'A4'); $this->pdf->titleintopdf($pdfTitle, $titleDesc); $this->pdf->Image($tempdir . "/" . $cachefilename, 0, 70, 180, 0, '', Yii::app()->getController()->createUrl("admin/survey/sa/view/surveyid/" . $surveyid), 'B', true, 150, 'C', false, false, 0, true); break; case 'html': if (isset($aattr["statistics_graphtype"])) { $req_chart_type = $aattr["statistics_graphtype"]; } //// If user forced the chartype from statistics_view if (isset($_POST['charttype']) && $_POST['charttype'] != 'default') { $req_chart_type = $_POST['charttype']; } //// The value of the select box in the question advanced setting is numerical. So we need to translate it. if (isset($req_chart_type)) { switch ($req_chart_type) { case '1': $charttype = "Pie"; break; case '2': $charttype = "Radar"; break; case '3': $charttype = "Line"; break; case '4': $charttype = "PolarArea"; break; case '5': $charttype = "Doughnut"; break; default: $charttype = "Bar"; break; } } //// Here the 72 colors of the original limesurvey palette. //// This could be change by some user palette coming from database. $COLORS_FOR_SURVEY = array('20,130,200', '232,95,51', '34,205,33', '210,211,28', '134,179,129', '201,171,131', '251,231,221', '23,169,161', '167,187,213', '211,151,213', '147,145,246', '147,39,90', '250,250,201', '201,250,250', '94,0,94', '250,125,127', '0,96,201', '201,202,250', '0,0,127', '250,0,250', '250,250,0', '0,250,250', '127,0,127', '127,0,0', '0,125,127', '0,0,250', '0,202,250', '201,250,250', '201,250,201', '250,250,151', '151,202,250', '251,149,201', '201,149,250', '250,202,151', '45,96,250', '45,202,201', '151,202,0', '250,202,0', '250,149,0', '250,96,0', '184,230,115', '102,128,64', '220,230,207', '134,191,48', '184,92,161', '128,64,112', '230,207,224', '191,48,155', '230,138,115', '128,77,64', '230,211,207', '191,77,48', '80,161,126', '64,128,100', '207,230,220', '48,191,130', '25,25,179', '18,18,125', '200,200,255', '145,145,255', '255,178,0', '179,125,0', '255,236,191', '255,217,128', '255,255,0', '179,179,0', '255,255,191', '255,255,128', '102,0,153', '71,0,107', '234,191,255', '213,128,255'); //// $lbl is generated somewhere upthere by the original code. We translate it for chartjs. $labels = array(); foreach ($lbl as $name => $lb) { $labels[] = $name; } if (isset($lblPercent)) { foreach ($lblPercent as $name => $lb) { $labels_percent[] = $name; } } else { $labels_percent = array(); } break; default: break; } } } } //close table/output if ($outputType == 'html') { // show this block only when we show graphs and are not in the public statics controller if ($usegraph == 1 && $bShowGraph && get_class(Yii::app()->getController()) !== 'Statistics_userController') { // We clean the labels $iMaxLabelLength = 0; // We clean the labels // Labels for graphs $iMaxLabelLength = 0; foreach ($aGraphLabels as $key => $label) { $cleanLabel = $label; $cleanLabel = viewHelper::flatEllipsizeText($cleanLabel, true, 20); $graph_labels[$key] = $cleanLabel; $iMaxLabelLength = strlen($cleanLabel) > $iMaxLabelLength ? strlen($cleanLabel) : $iMaxLabelLength; } if (isset($aGraphLabelsPercent)) { foreach ($aGraphLabelsPercent as $key => $label) { $cleanLabel = $label; $cleanLabel = viewHelper::flatEllipsizeText($cleanLabel, true, 20); $graph_labels_percent[$key] = $cleanLabel; } } else { $graph_labels_percent = array(); } $iCanvaHeight = $iMaxLabelLength * 3; $aData['iCanvaHeight'] = $iCanvaHeight > 150 ? $iCanvaHeight : 150; $qqid = str_replace('#', '_', $qqid); $aData['rt'] = $rt; $aData['qqid'] = $qqid; $aData['graph_labels'] = $graph_labels; $aData['graph_labels_percent'] = $labels_percent; $aData['labels'] = $labels; //$aData['COLORS_FOR_SURVEY'] = COLORS_FOR_SURVEY; $aData['charttype'] = isset($charttype) ? $charttype : 'Bar'; $aData['sChartname'] = ''; $aData['grawdata'] = $grawdata; $aData['color'] = rand(0, 70); $aData['COLORS_FOR_SURVEY'] = $COLORS_FOR_SURVEY; $aData['lbl'] = $lbl; /// $statisticsoutput .= Yii::app()->getController()->renderPartial('/admin/export/generatestats/_statisticsoutput_graphs', $aData, true); } $statisticsoutput .= "</table></div> <!-- in statistics helper --> \n"; } return array("statisticsoutput" => $statisticsoutput, "pdf" => $this->pdf, "astatdata" => $astatdata); }
/** * Show side menu for survey view * @param array $aData all the needed data */ function _surveysidemenu($aData) { $iSurveyID = $aData['surveyid']; // TODO : create subfunctions $sumresult1 = Survey::model()->with(array('languagesettings' => array('condition' => 'surveyls_language=language')))->find('sid = :surveyid', array(':surveyid' => $aData['surveyid'])); //$sumquery1, 1) ; //Checked if (Permission::model()->hasSurveyPermission($iSurveyID, 'surveycontent', 'read')) { $aData['permission'] = true; } else { $aData['gid'] = $gid = null; $qid = null; $aData['permission'] = false; } if (!is_null($sumresult1)) { $surveyinfo = $sumresult1->attributes; $surveyinfo = array_merge($surveyinfo, $sumresult1->defaultlanguage->attributes); $surveyinfo = array_map('flattenText', $surveyinfo); $aData['activated'] = $surveyinfo['active'] == 'Y'; // Tokens $bTokenExists = tableExists('{{tokens_' . $iSurveyID . '}}'); if (!$bTokenExists) { $aData['tokenmanagement'] = Permission::model()->hasSurveyPermission($iSurveyID, 'surveysettings', 'update') || Permission::model()->hasSurveyPermission($iSurveyID, 'tokens', 'create'); } else { $aData['tokenmanagement'] = Permission::model()->hasSurveyPermission($iSurveyID, 'surveysettings', 'update') || Permission::model()->hasSurveyPermission($iSurveyID, 'tokens', 'create') || Permission::model()->hasSurveyPermission($iSurveyID, 'tokens', 'read') || Permission::model()->hasSurveyPermission($iSurveyID, 'tokens', 'export') || Permission::model()->hasSurveyPermission($iSurveyID, 'tokens', 'import'); // and export / import ? } // Question explorer $aGroups = QuestionGroup::model()->findAllByAttributes(array('sid' => $iSurveyID, "language" => $sumresult1->defaultlanguage->surveyls_language), array('order' => 'group_order ASC')); if (count($aGroups)) { foreach ($aGroups as $group) { $group->aQuestions = Question::model()->findAllByAttributes(array("sid" => $iSurveyID, "gid" => $group['gid'], "language" => $sumresult1->defaultlanguage->surveyls_language), array('order' => 'question_order ASC')); foreach ($group->aQuestions as $question) { if (is_object($question)) { $question->question = viewHelper::flatEllipsizeText($question->question, true, 60, '[...]', 0.5); } } } } $aData['aGroups'] = $aGroups; $aData['surveycontent'] = Permission::model()->hasSurveyPermission($aData['surveyid'], 'surveycontent', 'read'); $this->getController()->renderPartial("/admin/super/sidemenu", $aData); } else { Yii::app()->session['flashmessage'] = gT("Invalid survey ID"); $this->getController()->redirect(array("admin/index")); } }
/** * Delete multiple questions. * Called by ajax from question list. * Permission check is done by questions::delete() * @return HTML */ public function deleteMultiple() { $aQidsAndLang = json_decode(Yii::app()->request->getPost('sItems')); $aResults = array(); foreach ($aQidsAndLang as $sQidAndLang) { $aQidAndLang = explode(',', $sQidAndLang); $iQid = $aQidAndLang[0]; $sLanguage = $aQidAndLang[1]; $oQuestion = Question::model()->find('qid=:qid and language=:language', array(":qid" => $iQid, ":language" => $sLanguage)); if (is_object($oQuestion)) { $aResults[$iQid]['question'] = viewHelper::flatEllipsizeText($oQuestion->question, true, 0); $aResults[$iQid]['result'] = $this->delete($oQuestion->sid, $oQuestion->gid, $iQid, true); } } Yii::app()->getController()->renderPartial('/admin/survey/Question/massive_actions/_delete_results', array('aResults' => $aResults)); }
<?php } ?> <?php if ($showLastQuestion) { ?> <span id="last_question" class="rotateHidden"> <?php eT("Last visited question:"); ?> <a href="<?php echo $last_question_link; ?> " class=""><?php echo viewHelper::flatEllipsizeText($last_question_name, true, 60); ?> </a> </span> <?php } ?> </div> <br/><br/> </div> </div> <?php } ?> <!-- Rendering all boxes in database -->