Skip to content

Instantly share code, notes, and snippets.

@touol
Last active April 14, 2020 19:48
Show Gist options
  • Save touol/9d315bb613ab830d0d46c73aeb5dc81a to your computer and use it in GitHub Desktop.
Save touol/9d315bb613ab830d0d46c73aeb5dc81a to your computer and use it in GitHub Desktop.
UserTest
<?php
/** @var modX $modx */
/** @var array $scriptProperties */
/** @var UserTest $UserTest */
$tplError = $modx->getOption('tplError', $scriptProperties, 'tpl.UserTest.error');
$AjaxMode = $modx->getOption('AjaxMode', $scriptProperties, '1');
$frontend_js = $modx->getOption('frontend_js', $scriptProperties, 'components/usertest/js/web/default.js');
$frontend_css = $modx->getOption('frontend_css', $scriptProperties, 'components/usertest/css/web/default.css');
$pdoFetch = $modx->getService('pdoFetch');
$pdoFetch->setConfig($scriptProperties);
$pdoFetch->addTime('pdoTools loaded');
if (!$UserTest = $modx->getService('usertest', 'UserTest', $modx->getOption('usertest_core_path', null,
$modx->getOption('core_path') . 'components/usertest/') . 'model/usertest/', $scriptProperties)
) {
return $pdoFetch->getChunk($tplError, array('error'=>'Could not load UserTest class!'));
}
$tpl = $modx->getOption('tpl', $scriptProperties, 'tpl.UserTest.main');
$id = $modx->getOption('id', $scriptProperties, 0);
//$tpl = 'tpl.UserTest.main2';
$answer_page_id = $modx->getOption('answer_page_id', $scriptProperties, 0);
//load js and css
$modx->regClientCSS($modx->getOption('assets_url').$frontend_css);
$actionUrl = $modx->getOption('assets_url') . 'components/usertest/action.php';
$modx->regClientScript($modx->getOption('assets_url'). "components/usertest/js/web/Sortable.min.js");
$modx->regClientScript($modx->getOption('assets_url'). "components/usertest/js/web/jquery.countdown.min.js");
if($AjaxMode){
$modx->regClientScript($modx->getOption('assets_url').$frontend_js);
$modx->regClientScript(
"<script type=\"text/javascript\">UserTestActionUrl = '{$actionUrl}'; UserTestActionTpl = '{$tpl}';UserTestActiontplError = '{$tplError}';</script>", true
);
}
$check_ajax = $modx->getOption('check_ajax', $scriptProperties, 0);
$answer_step = $_POST['answer_step'];
unset($_POST['answer_step']);
if(!$id){
if(isset($_POST['test_id'])){
$_GET['test_id'] = $_POST['test_id'];
}
if(isset($_GET['test_id'])){
$id = $_GET['test_id'];
}else{
return $pdoFetch->getChunk($tplError, array('error'=>"Нет номера теста!"));
}
}
unset($_POST['test_id']);
if(!$test = $modx->getObject('UserTestTests',$id)){
return $pdoFetch->getChunk($tplError, array('error'=>"Нет найден тест!"));
}
if($test->test_type == 2) $modx->regClientScript($modx->getOption('assets_url'). "components/usertest/canvasjs/jquery.canvasjs.min.js");
if($test->use_category){
$modx->regClientScript($modx->getOption('assets_url'). "components/usertest/pie_chart/Chart.bundle.js");
$modx->regClientScript($modx->getOption('assets_url'). "components/usertest/pie_chart/utils.js");
}
//echo $test->pub_date.' '.time();
if($test->pub_date and $test->pub_date > time()){
return $pdoFetch->getChunk($tplError, array('error'=>"Тест еще не опубликован!"));
}
if($test->unpub_date and $test->unpub_date < time()){
return $pdoFetch->getChunk($tplError, array('error'=>"Закончилось время публикации теста!"));
}
$user_id = $modx->user->get('id');
if($user_id > 0){
if($test->count_test_answer > 0){
$ResultCount = $modx->getCount('UserTestResults', array('user_id'=>$user_id,'test_id'=>$test->id, 'status_id:IN'=>array(2,3)));
if($ResultCount >= $test->count_test_answer){
return $pdoFetch->getChunk($tplError, array('error'=>"Закончилось кол-во попыток пройти тест!"));
}
}
}
if(isset($_POST['step'])){
$_GET['step'] = $_POST['step'];
unset($_POST['step']);
}
if(isset($_GET['step'])){
if($_GET['step'] == "start"){
$curStep = 1;
}else{
$curStep = $_GET['step'];
}
}else{
$curStep = "start";
}
$block_q_number = false;
//загрузка сохраненного теста
if(isset($_GET['result_id']) and !isset($_GET['reset'])){
if($Result = $modx->getObject('UserTestResults',$_GET['result_id'])){
if($Result->status_id != 1) return $pdoFetch->getChunk($tplError, array('error'=>"Тест завершён!"));
$_SESSION['UserTest'][$id] = json_decode($Result->session, true);
if(!isset($_SESSION['UserTest'][$id]['result_id'])){
$_SESSION['UserTest'][$id]['result_id'] = $_GET['result_id'];
}
if(isset($_SESSION['UserTest'][$id]['curStep'])){
$curStep = $_SESSION['UserTest'][$id]['curStep'];
$skip_save = true;
}
}
}
$curStep2 = $curStep;
//Сброс теста
if(isset($_GET['reset'])){
unset($_SESSION['UserTest'][$id]);
}
//ссылка для возврата к тесту
if($modx->resource){
$_SESSION['UserTestUrl'][$id]['test_url_id'] = $modx->resource->id;
}
//ссылка на ответы теста
if($answer_page_id){
$_SESSION['UserTestUrl'][$id]['answer_page_id'] = $answer_page_id;
}
//Занесение вопросов в сессию. подготовка
if($curStep == 1 and !isset($_SESSION['UserTest'][$id]['steps'])){
$c = $modx->newQuery('UserTestQuestions');
$c->leftJoin('UserTestTestQuestionLink','UserTestTestQuestionLink', '`UserTestTestQuestionLink`.`question_id` = `UserTestQuestions`.`id`');
$c->select($modx->getSelectColumns('UserTestQuestions','UserTestQuestions','',array(
'id',
'parent',
'category_id',
'question',
'type',
'type_file',
'file',
'extended',
'max_point'
)));
$c->select($modx->getSelectColumns('UserTestTestQuestionLink','UserTestTestQuestionLink','',array(
'menuindex',
'test_id',
)));
if($test->count_questions > 0){
$c->sortby('RAND()');
$c->limit($test->count_questions);
}else{
$c->sortby('`UserTestTestQuestionLink`.`menuindex`', 'ASC');
}
$c->where(array('`UserTestTestQuestionLink`.`test_id`'=>$id,'`UserTestQuestions`.`parent`'=>0));
$Questions = $modx->getCollection('UserTestQuestions', $c);
$countQ = $modx->getCount('UserTestQuestions', $c);
$step = 1;
$n = 1;
$numberQ = 1;
$steps = array();
$steps[0] = array('id'=>"start", 'question_ids'=>array());
$question_ids = array();
$q_ids = array();
foreach($Questions as $q){
$question_ids[$n]=array('id'=>$q->id, 'ans'=>0, 'numberQ'=>$numberQ);
$q_ids[] = $q->id;
$n++; $numberQ++;
if($test->count_questions_on_page > 0 and $n > $test->count_questions_on_page){
$steps[] = array('id'=>$step, 'question_ids'=>$question_ids);
$question_ids = array();
$step++;
$n = 1;
}
}
if(count($question_ids)>0){
$steps[$step] = array('id'=>$step, 'question_ids'=>$question_ids);
$steps[$step+1] = array('id'=>"finish", 'question_ids'=>array());
}else{
$steps[$step] = array('id'=>"finish", 'question_ids'=>array());
}
$_SESSION['UserTest'][$id]['steps'] = $steps;
$_SESSION['UserTest'][$id]['countQ'] = $countQ;
$_SESSION['UserTest'][$id]['q_ids'] = $q_ids;
if(!isset($_SESSION['UserTest'][$id]['result_id'])){
if($Result = $modx->newObject('UserTestResults')){
if($modx->user->get('id') > 0){
$Result->user_id = $modx->user->get('id');
$profile = $modx->user->getOne('Profile');
$Result->user_name = $profile->get('fullname');
$Result->user_email = $profile->get('email');
}
$Result->test_id = $id;
$Result->status_id = 1;
$Result->date = strftime('%Y-%m-%d %H:%M:%S');
$Result->save();
$_SESSION['UserTest'][$id]['result_id'] = $Result->id;
}
}
$_SESSION['UserTest'][$id]['test_time_start'] = time();
}
if(!isset($_SESSION['UserTest'][$id]) and $curStep != "start"){
return $pdoFetch->getChunk($tplError, array('error'=>"Тест завершился. Попробуйте пройти заново."));
}
//подготовка вопросов и ответов на вывод
if($curStep != "start" and $curStep != "finish"){
$steps = $_SESSION['UserTest'][$id]['steps'];
//print_r($steps);
$prevStep = $steps[$curStep-1]['id'];
$nextStep = $steps[$curStep+1]['id'];
$question_ids = $steps[$curStep]['question_ids'];
$questions = array();
foreach($question_ids as $q_id1 => $q_id){
if($q = $modx->getObject('UserTestQuestions', $q_id['id'])){
$question = $q->toArray();
$question['numberQ'] = $q_id['numberQ'];
$question['countQ'] = $_SESSION['UserTest'][$id]['countQ'];
switch($q->type){
case 1: //Одиночный выбор
case 12: //Опросник САН
$c = $modx->newQuery('UserTestAnswers');
if($q->random_answer){
$c->sortby('RAND()');
}else{
$c->sortby('menuindex', 'ASC');
}
$c->where(array('question_id'=>$q_id['id']));
$Answers = $modx->getIterator('UserTestAnswers', $c);
$Ans = array();
foreach($Answers as $a){
$Ans[] = $a->toArray();
}
$question['answers'] = $Ans;
$question['answer_id'] = $q_id['ans'];
$questions[] = $question;
break;
case 2: //Множественный выбор
$c = $modx->newQuery('UserTestAnswers');
if($q->random_answer){
$c->sortby('RAND()');
}else{
$c->sortby('menuindex', 'ASC');
}
$c->where(array('question_id'=>$q_id['id']));
$Answers = $modx->getIterator('UserTestAnswers', $c);
$Ans = array();
foreach($Answers as $a){
$a1 = $a->toArray();
if (in_array($a->id, $q_id['ans'])) {
$a1['check'] = 1;
}else{
$a1['check'] = 0;
}
$Ans[] = $a1;
}
$question['answers'] = $Ans;
$questions[] = $question;
break;
case 3: //Простой текст
$question['answer'] = "";
if($q_id['ans']){
$question['answer'] = $q_id['ans'];
}
$questions[] = $question;
break;
case 4: //Открытый вопрос
$question['answer'] = "";
if($q_id['ans']){
$question['answer'] = $q_id['ans'];
}
$questions[] = $question;
break;
case 5: //На сопоставление. Простой
$ext = json_decode($question['extended'], 1);
$question['q'] = $ext['q'];
$a = $ext['a'];
if(!$q_id['ans']){
//сортировка массива в случайном порядке
$key = array_keys($a);
shuffle($key);
$_SESSION['UserTest'][$id]['steps'][$curStep]['question_ids'][$q_id1]['key'] = $key;
//print_r($_SESSION['UserTest'][$id]['steps'][$curStep]['question_ids'][$q_id1]);
$q_id['key'] = $key;
$q_id['ans'] = array_keys($key);
}
$key = $q_id['key'];
$a1 = array();
foreach($q_id['ans'] as $k => $v){
$a1[$v] = $a[$key[$v]];
}
$question['a'] = $a1;
$question['answer'] = implode('|',$q_id['ans']);
$questions[] = $question;
//print_r($q_id);
break;
case 6: //Комбинированный вариант
$c = $modx->newQuery('UserTestAnswers');
if($q->random_answer){
$c->sortby('RAND()');
}else{
$c->sortby('menuindex', 'ASC');
}
$c->where(array('question_id'=>$q_id['id']));
$Answers = $modx->getIterator('UserTestAnswers', $c);
$Ans = array();
foreach($Answers as $a){
$a1 = $a->toArray();
if (in_array($a->id, $q_id['ans'])) {
$a1['check'] = 1;
}else{
$a1['check'] = 0;
}
$Ans[] = $a1;
}
$question['answers'] = $Ans;
if(isset($q_id['ans_add'])){
$question['answers_add'] = $q_id['ans_add'];
}else{
$question['answers_add'] = array(
'check' => 0,
'ans' => "",
);
}
$questions[] = $question;
break;
case 7: //Таблица чек-боксов
$q_childs = $modx->getIterator('UserTestQuestions', array('parent' =>$q_id['id']));
foreach($q_childs as $k_child=>$q_child){
$c = $modx->newQuery('UserTestAnswers');
$c->sortby('menuindex', 'ASC');
$c->where(array('question_id'=>$q_child->id));
$Answers = $modx->getIterator('UserTestAnswers', $c);
$Ans_header = array();
$Ans_header[] = "";
if($k_child == 1){
foreach($Answers as $a){
$Ans_header[] = $a->answer;
}
}
$Ans = array();
foreach($Answers as $a){
$a1 = $a->toArray();
if (in_array($a->id, $q_id['ans'][$q_child->id])) {
$a1['check'] = 1;
}else{
$a1['check'] = 0;
}
$Ans[] = $a1;
}
$question['header'] = $Ans_header;
$qc = $q_child->toArray();
$qc['answers'] = $Ans;
$question['q_childs'][] = $qc;
//$question['answers'] = $Ans;
}
$questions[] = $question;
break;
case 8: //Таблица текстовых полей
$q_childs = $modx->getIterator('UserTestQuestions', array('parent' =>$q_id['id']));
foreach($q_childs as $k_child=>$q_child){
$c = $modx->newQuery('UserTestAnswers');
$c->sortby('menuindex', 'ASC');
$c->where(array('question_id'=>$q_child->id));
$Answers = $modx->getIterator('UserTestAnswers', $c);
$Ans_header = array();
$Ans_header[] = "";
if($k_child = 1){
foreach($Answers as $a){
$Ans_header[] = $a->answer;
}
}
$Ans = array();
foreach($Answers as $a){
$a1 = $a->toArray();
if(isset($q_id['ans'][$q_child->id][$a->id])) $a1['ac'] = $q_id['ans'][$q_child->id][$a->id];
$Ans[] = $a1;
}
$question['header'] = $Ans_header;
$qc = $q_child->toArray();
$qc['answers'] = $Ans;
$question['q_childs'][] = $qc;
$question['answers'] = $Ans;
}
$questions[] = $question;
break;
case 9: //Селекты в тексте
$q_childs = $modx->getIterator('UserTestQuestions', array('parent' =>$q_id['id']));
$q_str = $q->question;
foreach($q_childs as $k_child=>$q_child){
$c = $modx->newQuery('UserTestAnswers');
if($q->random_answer){
$c->sortby('RAND()');
}else{
$c->sortby('menuindex', 'ASC');
}
$c->where(array('question_id'=>$q_child->id));
$Answers = $modx->getIterator('UserTestAnswers', $c);
$opt = "";
$opt .= $pdoFetch->getChunk('@INLINE <option value="{$id}">{$answer}</option>', array(
'id'=>0,
'answer'=>"Выбрать",
));
foreach($Answers as $a){
if(isset($q_id['ans'][$q_child->id]) and $q_id['ans'][$q_child->id] == $a->id){
$opt .= $pdoFetch->getChunk('@INLINE <option value="{$id}" selected>{$answer}</option>', array(
'id'=>$a->id,
'answer'=>$a->answer,
));
}else{
$opt .= $pdoFetch->getChunk('@INLINE <option value="{$id}">{$answer}</option>', array(
'id'=>$a->id,
'answer'=>$a->answer,
));
}
}
$sel = $pdoFetch->getChunk('@INLINE <select class="select-in-text" name="question[{$q_id}][{$qc_id}]">{$opt}</select>', array(
'q_id'=>$q_id['id'],
'qc_id'=>$q_child->id,
'opt'=>$opt,
));
//echo $sel.' '.$q_str;
$q_str = str_replace('[['.$q_child->question.']]',$sel,$q_str);
}
$question['q_str'] = $q_str;
$questions[] = $question;
break;
case 10: //Комбинированный одиночный выбор
//print_r($q_id);
$c = $modx->newQuery('UserTestAnswers');
if($q->random_answer){
$c->sortby('RAND()');
}else{
$c->sortby('menuindex', 'ASC');
}
$c->where(array('question_id'=>$q_id['id']));
$Answers = $modx->getIterator('UserTestAnswers', $c);
$Ans = array();
foreach($Answers as $a){
$a1 = $a->toArray();
if ($a->id == $q_id['ans']['ans']) {
$a1['check'] = 1;
}else{
$a1['check'] = 0;
}
$Ans[] = $a1;
}
$question['answers'] = $Ans;
if($q_id['ans']['ans']=="ans_add"){
$question['answers_add'] = $q_id['ans_add'];
}else{
$question['answers_add'] = array(
'check' => 0,
'ans' => "",
);
}
$questions[] = $question;
break;
}
}
}
}
$test_point = 0;
//сохранение ответов теста в сессию и базу
if($answer_step != "start" and !$skip_save){
$questions_post = $_POST['question'];
$result_id = $_SESSION['UserTest'][$id]['result_id'];
$steps = $_SESSION['UserTest'][$id]['steps'];
$resStep = $answer_step;
//echo $resStep;
if($Result = $modx->getObject('UserTestResults',$result_id)){
//print_r($_POST);
//print_r($steps[$resStep]);
foreach($questions_post as $q_id=>$a_id){
if(!$q = $modx->getObject('UserTestQuestions', $q_id)){
$params = array(
'test_id'=>$id,
'reset'=>1,
);
$reset_url = $modx->getOption('site_url').$modx->makeUrl($_SESSION['UserTestUrl'][$id]['test_url_id'],'',$params);
return $pdoFetch->getChunk($tplError, array('error'=>"Вопрос не найден. q_id=".$q_id,'reset_url'=>$reset_url));
}
switch($q->type){
case 1: //Одиночный выбор
case 12: //Опросник САН
foreach($steps[$resStep]['question_ids'] as $s_id=>$v){
if($v['id'] == $q_id){
$steps[$resStep]['question_ids'][$s_id]['ans'] = $a_id;
}
}
if(!$resAns = $modx->getObject('UserTestResultAnswers', array('result_id'=>$result_id, 'question_id'=>$q_id))){
$resAns = $modx->newObject('UserTestResultAnswers');
}
$resAns->result_id = $result_id;
$resAns->question_id = $q_id;
$resAns->answer_id = $a_id;
$point = 0;
if($a = $modx->getObject('UserTestAnswers',$a_id)){
$answer = $a->answer;
$point = $a->point;
}
$resAns->answer = $answer;
$resAns->point = $point;
$resAns->save();
break;
case 2: //Множественный выбор
foreach($steps[$resStep]['question_ids'] as $s_id=>$v){
if($v['id'] == $q_id){
$steps[$resStep]['question_ids'][$s_id]['ans'] = $a_id;
}
}
if(!$resAns = $modx->getObject('UserTestResultAnswers', array('result_id'=>$result_id, 'question_id'=>$q_id))){
$resAns = $modx->newObject('UserTestResultAnswers');
}
$resAns->result_id = $result_id;
$resAns->question_id = $q_id;
$resAns->answer_ids = implode(',', $a_id);
$answer = array(); $point = 0; $right = true;
foreach($a_id as $a_id1){
if($a = $modx->getObject('UserTestAnswers',$a_id1)){
$answer[] = $a->answer;
$point += $a->point;
if(!$a->right) $right = false;
}
}
$resAns->answer = implode(', ', $answer);
if(!$right) $point = 0;
$resAns->point = $point;
$resAns->save();
break;
case 3: //Простой текст
foreach($steps[$resStep]['question_ids'] as $s_id=>$v){
if($v['id'] == $q_id){
$steps[$resStep]['question_ids'][$s_id]['ans'] = $a_id;
}
}
if(!$resAns = $modx->getObject('UserTestResultAnswers', array('result_id'=>$result_id, 'question_id'=>$q_id))){
$resAns = $modx->newObject('UserTestResultAnswers');
}
$resAns->result_id = $result_id;
$resAns->question_id = $q_id;
$c = $modx->newQuery('UserTestAnswers');
$c->sortby('menuindex', 'ASC');
$c->where(array('question_id'=>$q_id));
$Answers = $modx->getIterator('UserTestAnswers', $c);
$point = 0; $ans_id = 0;
foreach($Answers as $a){
if($a_id == $a->answer){
$point = $a->point;
$ans_id = $a->id;
break;
}
}
$resAns->answer_id = $ans_id;
$resAns->answer = $a_id;
$resAns->point = $point;
$resAns->save();
break;
case 4: //Открытый вопрос
foreach($steps[$resStep]['question_ids'] as $s_id=>$v){
if($v['id'] == $q_id){
$steps[$resStep]['question_ids'][$s_id]['ans'] = $a_id;
}
}
if(!$resAns = $modx->getObject('UserTestResultAnswers', array('result_id'=>$result_id, 'question_id'=>$q_id))){
$resAns = $modx->newObject('UserTestResultAnswers');
}
$resAns->result_id = $result_id;
$resAns->question_id = $q_id;
$resAns->answer = $a_id;
$resAns->save();
break;
case 5: //На сопоставление. Простой
$ans = explode('|', $a_id); $key = array(); $point = 0;
foreach($steps[$resStep]['question_ids'] as $s_id=>$v){
if($v['id'] == $q_id){
$steps[$resStep]['question_ids'][$s_id]['ans'] = $ans;
$key = $steps[$resStep]['question_ids'][$s_id]['key'];
}
}
if (!empty($key)){
$ext = json_decode($q->extended, 1);
$q1 = $ext['q'];
$a1 = $ext['a'];
//$type_point = $ext['type_point']; //0 за правильный ответ. 1 за совпадения.
$result_ans = array(); $check = true; $ids = array();
foreach($ans as $k=>$a){
$result_ans[] = $q1[$k]." -> ". $a1[$key[$a]];
$ids[] = $key[$a];
if($k == $key[$a]){
$point += $ext['point'];
}else{
$check = false;
}
}
}
if($ext['type_point'] == 0){
if($check){
$point = $ext['point'];
}else{
$point = 0;
}
}
//echo implode('<br>', $result_ans);
if(!$resAns = $modx->getObject('UserTestResultAnswers', array('result_id'=>$result_id, 'question_id'=>$q_id))){
$resAns = $modx->newObject('UserTestResultAnswers');
}
$resAns->result_id = $result_id;
$resAns->question_id = $q_id;
$resAns->answer_ids = implode(',', $ids);
$resAns->answer = implode("\r\n", $result_ans);
$resAns->point = $point;
$resAns->save();
break;
case 6: //Комбинированный вариант
foreach($steps[$resStep]['question_ids'] as $s_id=>$v){
if($v['id'] == $q_id){
if(isset($a_id['ans_add'])){
$steps[$resStep]['question_ids'][$s_id]['ans_add'] = array(
'check' => 1,
'ans' => $a_id['ans_add_ans'],
);
}else{
$steps[$resStep]['question_ids'][$s_id]['ans_add'] = array(
'check' => 0,
'ans' => "",
);
}
$a_id_add = $steps[$resStep]['question_ids'][$s_id]['ans_add'];
unset($a_id['ans_add']);
unset($a_id['ans_add_ans']);
$steps[$resStep]['question_ids'][$s_id]['ans'] = $a_id;
}
}
if(!$resAns = $modx->getObject('UserTestResultAnswers', array('result_id'=>$result_id, 'question_id'=>$q_id))){
$resAns = $modx->newObject('UserTestResultAnswers');
}
$resAns->result_id = $result_id;
$resAns->question_id = $q_id;
$resAns->answer_ids = implode(',', $a_id);
$answer = array(); $point = 0;
foreach($a_id as $a_id1){
if($a = $modx->getObject('UserTestAnswers',$a_id1)){
$answer[] = $a->answer;
$point += $a->point;
}
}
if($a_id_add['check']) $answer[] = $a_id_add['ans'];
$resAns->answer = implode(', ', $answer);
$resAns->point = $point;
if($resAns->answer){
$resAns->save();
}
break;
case 7: //Таблица чек-боксов
//print_r($a_id);
foreach($steps[$resStep]['question_ids'] as $s_id=>$v){
if($v['id'] == $q_id){
$steps[$resStep]['question_ids'][$s_id]['ans'] = $a_id;
}
}
if(!$resAns = $modx->getObject('UserTestResultAnswers', array('result_id'=>$result_id, 'question_id'=>$q_id))){
$resAns = $modx->newObject('UserTestResultAnswers');
}
$resAns->result_id = $result_id;
$resAns->question_id = $q_id;
$resAns->point = 0;
$answer = "";
foreach($a_id as $qc_id=>$ac){
if(!$resAnsc = $modx->getObject('UserTestResultAnswers', array('result_id'=>$result_id, 'question_id'=>$qc_id))){
$resAnsc = $modx->newObject('UserTestResultAnswers');
}
$resAnsc->result_id = $result_id;
$resAnsc->question_id = $qc_id;
$resAnsc->answer_ids = implode(',', $ac);
$answerc = array(); $point = 0;
foreach($ac as $a_id1){
if($a = $modx->getObject('UserTestAnswers',$a_id1)){
$answerc[] = $a->answer;
$point += $a->point;
}
}
$resAnsc->answer = implode('# ', $answerc);
$resAnsc->point = $point;
$resAns->point += $point;
//$resAnsc->save();
if($q_child = $modx->getObject('UserTestQuestions', $qc_id)){
$answer .= $q_child->question."[".$q_child->id."]"."->".$resAnsc->answer."\r\n";
}
}
$resAns->answer = $answer;
$resAns->save();
break;
case 8: //Таблица текстовых полей
//print_r($a_id);
foreach($steps[$resStep]['question_ids'] as $s_id=>$v){
if($v['id'] == $q_id){
$steps[$resStep]['question_ids'][$s_id]['ans'] = $a_id;
}
}
if(!$resAns = $modx->getObject('UserTestResultAnswers', array('result_id'=>$result_id, 'question_id'=>$q_id))){
$resAns = $modx->newObject('UserTestResultAnswers');
}
$resAns->result_id = $result_id;
$resAns->question_id = $q_id;
$resAns->point = 0;
$answer = "";
foreach($a_id as $qc_id=>$ac){
if(!$resAnsc = $modx->getObject('UserTestResultAnswers', array('result_id'=>$result_id, 'question_id'=>$qc_id))){
$resAnsc = $modx->newObject('UserTestResultAnswers');
}
$resAnsc->result_id = $result_id;
$resAnsc->question_id = $qc_id;
//$resAns->answer_ids = implode(',', $ac);
$answerc = array(); $point = 0;
foreach($ac as $a_id1=>$ac_v){
if($a = $modx->getObject('UserTestAnswers',$a_id1) and $ac_v){
$answerc[] = $a->answer.'#'.$ac_v;
}
}
$resAnsc->answer = implode('# ', $answerc);
$resAnsc->point = $point;
if($resAnsc->answer){
//$resAnsc->save();
}
if($q_child = $modx->getObject('UserTestQuestions', $qc_id)){
$answer .= $q_child->question."[".$q_child->id."]"."->".$resAnsc->answer."\r\n";
}
}
$resAns->answer = $answer;
$resAns->save();
break;
case 9: //Селекты в тексте
foreach($steps[$resStep]['question_ids'] as $s_id=>$v){
if($v['id'] == $q_id){
$steps[$resStep]['question_ids'][$s_id]['ans'] = $a_id;
}
}
$all_point = 0;
$a_str = $q->question;
foreach($a_id as $qc_id=>$ac){
if(!$resAns = $modx->getObject('UserTestResultAnswers', array('result_id'=>$result_id, 'question_id'=>$qc_id))){
$resAns = $modx->newObject('UserTestResultAnswers');
}
$resAns->result_id = $result_id;
$resAns->question_id = $qc_id;
$resAns->answer_ids = implode(',', $ac);
$answer = ""; $point = 0;
if($a = $modx->getObject('UserTestAnswers',$ac)){
$answer = $a->answer;
$point += $a->point;
}
$resAns->answer = $answer;
$resAns->point = $point;
//$resAns->save();
$all_point += $point;
if($q_child = $modx->getObject('UserTestQuestions', $qc_id)){
$a_str = str_replace('[['.$q_child->question.']]',$answer,$a_str);
}
}
if(!$resAns = $modx->getObject('UserTestResultAnswers', array('result_id'=>$result_id, 'question_id'=>$q_id))){
$resAns = $modx->newObject('UserTestResultAnswers');
}
$resAns->result_id = $result_id;
$resAns->question_id = $q_id;
$resAns->answer = $a_str;
$resAns->point = $all_point;
$resAns->save();
break;
case 10: //Комбинированный одиночный выбор
foreach($steps[$resStep]['question_ids'] as $s_id=>$v){
if($v['id'] == $q_id){
if($a_id['ans']=="ans_add"){
$steps[$resStep]['question_ids'][$s_id]['ans_add'] = array(
'check' => 1,
'ans' => $a_id['ans_add_ans'],
);
}else{
$steps[$resStep]['question_ids'][$s_id]['ans_add'] = array(
'check' => 0,
'ans' => "",
);
}
$a_id_add = $steps[$resStep]['question_ids'][$s_id]['ans_add'];
//unset($a_id['ans_add']);
//unset($a_id['ans_add_ans']);
$steps[$resStep]['question_ids'][$s_id]['ans'] = $a_id;
}
}
//print_r($a_id);
if(!$resAns = $modx->getObject('UserTestResultAnswers', array('result_id'=>$result_id, 'question_id'=>$q_id))){
$resAns = $modx->newObject('UserTestResultAnswers');
}
$resAns->result_id = $result_id;
$resAns->question_id = $q_id;
$answer = ""; $point = 0;
if($a_id["ans"] == "ans_add"){
$resAns->answer_id = 0;
$answer = $a_id['ans_add_ans'];
if($answer){
$answer = "Другое->".$answer;
}
}else{
$resAns->answer_id = $a_id["ans"];
if($a = $modx->getObject('UserTestAnswers',$a_id["ans"])){
$answer = $a->answer;
$point = $a->point;
}
}
if($answer){
$resAns->answer = $answer;
$resAns->point = $point;
$resAns->save();
}
break;
}
}
$c = $modx->newQuery('UserTestResultAnswers');
//$c->leftJoin('UserTestAnswers', 'UserTestAnswers', 'UserTestAnswers.id = UserTestResultAnswers.answer_id');
$c->select("sum(point) as sum_point");
$c->where(array('result_id'=>$result_id));
//$c->prepare();
//echo $c->toSQL();
if($object = $modx->getObject('UserTestResultAnswers', $c)){
$Result->test_point = $object->get('sum_point');
$test_time_start = $_SESSION['UserTest'][$id]['test_time_start'];// = time()
$test_time = time() - $test_time_start;
$Result->test_time = $test_time;
$test_point = $Result->test_point;
}
$_SESSION['UserTest'][$id]['steps'] = $steps;
$Result->save();
}
}
//сохранение в базу сессии для возврата к тесту
if($curStep != "start" and !$skip_save){
$result_id = $_SESSION['UserTest'][$id]['result_id'];
if($Result = $modx->getObject('UserTestResults',$result_id)){
$_SESSION['UserTest'][$id]['curStep'] = $curStep2;
$Result->session = json_encode($_SESSION['UserTest'][$id]);
$Result->save();
}
}
//ограничение времени теста
$end_test_time = 0;
if($test->time_test > 0 and isset($_SESSION['UserTest'][$id]['test_time_start'])){
$test_time_start = $_SESSION['UserTest'][$id]['test_time_start'];// = time()
$test_time = time() - $test_time_start;
$end_test_time = $test->time_test - $test_time;
if($test_time > $test->time_test){
$curStep = "finish";
}
}
//подготовка блока вопросов
if($curStep != "start" and $curStep != "finish"){
$steps = $_SESSION['UserTest'][$id]['steps'];
//print_r($steps);
//подготовка блока вопросов
if($test->use_block_q_number){
foreach($steps as $k_step => $step){
$curStepCheck = false;
if($curStep2 == $k_step){
$curStepCheck = true;
}
foreach($step['question_ids'] as $q_id){
$ansCheck = false;
if($q_id['ans']) {
if(!$q = $modx->getObject('UserTestQuestions', $q_id["id"])){
$params = array(
'test_id'=>$id,
'reset'=>1,
);
$reset_url = $modx->getOption('site_url').$modx->makeUrl($_SESSION['UserTestUrl'][$id]['test_url_id'],'',$params);
return $pdoFetch->getChunk($tplError, array('error'=>"Вопрос не найден. q_id=".$q_id,'reset_url'=>$reset_url));
}
switch($q->type){
case 9:
$ansCheck = true;
foreach($q_id["ans"] as $qc_id=>$ac_id){
if($ac_id == 0) $ansCheck = false;
}
break;
case 10:
if(isset($q_id["ans"]["ans"])) $ansCheck = true;
break;
case 8:
//print_r($q_id);
foreach($q_id["ans"] as $qc_id=>$ac_id){
foreach($ac_id as $v)
if($v) $ansCheck = true;
}
break;
default:
$ansCheck = true;
break;
}
}
$block_q_number[]=array(
'numberQ' => $q_id['numberQ'],
'curStepCheck'=>$curStepCheck,
'ansCheck'=>$ansCheck,
'step'=>$k_step,
);
}
}
}
//end подготовка блока вопросов
}
$var_id = 0;$var_result="";$max_point=0;
if($curStep == "finish"){
$block_q_number = false;
//$result_id = $_SESSION['UserTest'][$id]['result_id'];
$c = $modx->newQuery("UserTestVariants");
$c->leftJoin('UserTestTestVariantLink','UserTestTestVariantLink', '`UserTestTestVariantLink`.`variant_id` = `UserTestVariants`.`id`');
$c->select($modx->getSelectColumns('UserTestVariants','UserTestVariants','',array(
'id',
'passed',
'category_id',
'result'
)));
$c->select($modx->getSelectColumns('UserTestTestVariantLink','UserTestTestVariantLink','',array(
'menuindex',
'test_id',
)));
$c->select('IF(`UserTestTestVariantLink`.`use_custom_point` = 1, `UserTestTestVariantLink`.`start_point`, `UserTestVariants`.`start_point`) as start_point,
IF(`UserTestTestVariantLink`.`use_custom_point` = 1, `UserTestTestVariantLink`.`end_point`, `UserTestVariants`.`end_point`) as end_point');
$c->where(array('`UserTestTestVariantLink`.`test_id`'=>$id,'`UserTestVariants`.`category_id`'=>0));
//$c->prepare(); echo $c->toSQL();
$Variants = $modx->getCollection('UserTestVariants', $c);
foreach($Variants as $var){
if($test_point >= $var->start_point and $test_point <= $var->end_point){
$var_id = $var->id;
$var_result = $var->result;
$var_passed = $var->passed;
break;
}
}
//echo '$test->use_category '.$test->use_category;
$cat_email_results = "";
if($Result and ($test->use_category or $test->test_type == 2)){
$c = $modx->newQuery('UserTestResultAnswers');
$c->leftJoin('UserTestQuestions', 'UserTestQuestions', 'UserTestResultAnswers.question_id = UserTestQuestions.id');
$c->select("`UserTestQuestions`.`category_id` as cat_id, sum(`UserTestResultAnswers`.`point`) as sum_point, count(*) as count_cat");
$c->where(array('result_id'=>$result_id));
$c->groupby('`UserTestQuestions`.`category_id`');
//$c->prepare();echo $c->toSQL();
$cat_results = array();
$cat_points = $modx->getIterator('UserTestResultAnswers', $c);
foreach($cat_points as $cp){
$var_id = 0;$cat_result="";$cat_var_result='';
$Variants = $modx->getIterator('UserTestVariants', array('test_id'=>$id, 'category_id'=> $cp->cat_id));
foreach($Variants as $var){
if($cp->sum_point >= $var->start_point and $cp->sum_point <= $var->end_point){
$c_var_id = $var->id;
$cat_var_result = $var->result;
break;
}
}
if($cat_result = $modx->newObject('UserTestResultCategorys')){
$cat_result->result_id = $Result->id;
$cat_result->category_id = $cp->cat_id;
$cat_result->variant_id = $c_var_id;
$cat_result->cat_point = $cp->sum_point;
if($test->test_type == 2 and $cp->count_cat > 0) $cat_result->cat_point = $cp->sum_point/$cp->count_cat; //Для опросник САН
$cat_result->max_point = getMaxPoint($modx, $id, $cp->cat_id);
$cat_result->save();
$cr = $cat_result->toArray();
if($cat = $modx->getObject('UserTestCategorys', $cp->cat_id)){
$cr['cat_name'] = $cat->name;
}
$cr['result'] = $cat_var_result;
$cat_results[] = $cr;
$cat_email_results .=$cr['cat_name'].": ".$cr['result']." ";
}
}
}
//ссылка на правильные ответы
if(isset($_SESSION['UserTestUrl'][$id]['answer_page_id'])){
$params = array(
'result_id'=>$_SESSION['UserTest'][$id]['result_id'],
);
$answer_page_url = $modx->getOption('site_url').$modx->makeUrl($_SESSION['UserTestUrl'][$id]['answer_page_id'],'',$params);
}
unset($_SESSION['UserTest'][$id]);
unset($_SESSION['UserTestUrl'][$id]);
if($Result){
$Result->variant_id = $var_id;
if($test->type == 2){
$Result->status_id = 3;
}else{
$Result->status_id = 2;
}
$Result->max_point = getMaxPoint($modx, $id);
$Result->save();
$response = $modx->invokeEvent('OnTestCalculate', array(
'test'=>$test->toArray(),
'variants'=>$Variants,
'result'=>$Result,
'cat_results'=>$cat_results
));
if($Result = $modx->getObject('UserTestResults',$Result->id)){
$var_id = $Result->variant_id;
if($var = $modx->getObject('UserTestVariants',$var_id)){
$var_result = $var->result;
$var_passed = $var->passed;
}
$max_point = $Result->max_point;
$result_status = $Result->status_id;
$result_id = $Result->id;
$Result->session = "";
$Result->save();
$temp_result = $Result->toArray();
$temp_result['var_result'] = $var_result;
$temp_result['var_passed'] = $var_passed;
$temp_result['cat_email_results'] = $cat_email_results;
$modx->invokeEvent('OnTestComplect', array(
'test'=>$test->toArray(),
'result' => $temp_result,
));
}
unset($_POST);
}
//извлекаем историю опросов САН для построения графика
$cat_history = array();
if($test->test_type == 2){
$cch = $modx->newQuery('UserTestResultCategorys');
$cch->leftJoin('UserTestResults','UserTestResults', '`UserTestResultCategorys`.`result_id` = `UserTestResults`.`id`');
//$cch->leftJoin('UserTestCategorys','UserTestCategorys', '`UserTestResultCategorys`.`category_id` = `UserTestCategorys`.`id`');
$cch->select('`UserTestResultCategorys`.`cat_point`, `UserTestResultCategorys`.`category_id`, `UserTestResults`.`date`');
$cch->where(array(
'`UserTestResults`.`user_id`'=>$user_id,
'`UserTestResults`.`test_id`'=>$test->id,
));
$chs = $modx->getIterator('UserTestResultCategorys', $cch);
foreach($chs as $ch1){
$cat_history[$ch1->date][$ch1->category_id] = $ch1->cat_point;
}
}
}
//ссылка для возврата к тесту
if(isset($_SESSION['UserTestUrl'][$id]['test_url_id'])){
$params = array(
'test_id'=>$id,
'result_id'=>$_SESSION['UserTest'][$id]['result_id'],
);
$test_url = $modx->getOption('site_url').$modx->makeUrl($_SESSION['UserTestUrl'][$id]['test_url_id'],'',$params);
}
$cats_questions = [];
if($enable_cat_child_questions or $_SESSION['UserTestUrl'][$id]['enable_cat_child_questions']){
if($_SESSION['UserTestUrl'][$id]['enable_cat_child_questions']) $enable_cat_child_questions = true;
$_SESSION['UserTestUrl'][$id]['enable_cat_child_questions'] = true;
//echo "enable_cat_child_questions !$enable_cat_child_questions!";
$cat_questions = [];
foreach($questions as $q){
$cat_questions[$q['category_id']][] = $q;
}
$pdoFetch->setConfig([
'class'=>'UserTestCategorys',
'sortby'=>['name'=>'ASC'],
'return'=>'data'
]);
$cats = $pdoFetch->run();
$idx = 1;
foreach($cats as $cat){
if(isset($cat_questions[$cat['id']])){
$cats_questions[] = ['idx'=>$idx++,'cat'=>$cat, 'questions'=>$cat_questions[$cat['id']]];
}
}
}
return $pdoFetch->getChunk($tpl, array(
'enable_cat_child_questions'=>$enable_cat_child_questions,
'cats_questions'=>$cats_questions,
'result_id'=>$result_id,
'check_ajax'=>$check_ajax,
'test_id'=>$id,
'test'=>$test->toArray(),
'curStep'=>$curStep,
'prevStep'=>$prevStep,
'nextStep'=>$nextStep,
'questions'=>$questions,
'test_point'=>$test_point,
'max_point'=>$max_point,
'var_result'=>$var_result,
'var_passed'=>$var_passed,
'test_time'=>$test_time,
'end_test_time'=>$end_test_time,
'result_status'=>$result_status,
'catResults'=>$cat_results,
'cat_history'=>$cat_history,
'cat_email_results'=>$cat_email_results,
'block_q_number'=>$block_q_number,
'test_url'=>$test_url,
'answer_page_url'=>$answer_page_url,
));
function getMaxPoint($modx, $test_id, $category_id = 0){
$c = $modx->newQuery('UserTestQuestions');
$c->leftJoin('UserTestTestQuestionLink','UserTestTestQuestionLink', '`UserTestTestQuestionLink`.`question_id` = `UserTestQuestions`.`id`');
$c->select($modx->getSelectColumns('UserTestQuestions','UserTestQuestions','',array(
'id',
'parent',
'category_id',
'question',
'type',
'type_file',
'file',
'extended',
'max_point'
)));
$c->select($modx->getSelectColumns('UserTestTestQuestionLink','UserTestTestQuestionLink','',array(
'menuindex',
'test_id',
)));
if(isset($_SESSION['UserTest'][$test_id]['q_ids'])){
$q_ids = $_SESSION['UserTest'][$test_id]['q_ids'];
$c->where(array('`UserTestTestQuestionLink`.`test_id`'=>$test_id,'`UserTestQuestions`.`parent`'=>0,'`UserTestQuestions`.`id`:IN'=>$q_ids));
}else{
$c->where(array('`UserTestTestQuestionLink`.`test_id`'=>$test_id,'`UserTestQuestions`.`parent`'=>0));
}
if($category_id){
$c->where(array('`UserTestQuestions`.`category_id`'=>$category_id));
}
//$c->prepare();echo $c->toSQL();
$Questions = $modx->getCollection('UserTestQuestions', $c);
$maxPoint=0;
foreach($Questions as $q){
switch($q->type){
case 8: //Таблица текстовых полей
case 4: //Открытый вопрос
case 6: //Комбинированный вариант
case 10: //usertest_type_questions_combined_radiobutton
$maxPoint += $q->max_point;
break;
case 1: //Одиночный выбор
case 12: //Опросник САН
$c1 = $modx->newQuery('UserTestAnswers');
$c1->where(array('question_id'=>$q->id));
$c1->select('MAX(point) as max_point');
if($max = $modx->getObject('UserTestAnswers',$c1)){
$maxPoint += $max->max_point;
}
break;
case 2: //Множественный выбор
$c1 = $modx->newQuery('UserTestAnswers');
$c1->where(array('question_id'=>$q->id));
$c1->select('SUM(point) as max_point');
if($max = $modx->getObject('UserTestAnswers',$c1)){
$maxPoint += $max->max_point;
}
break;
case 3: //Простой текст
$c1 = $modx->newQuery('UserTestAnswers');
$c1->where(array('question_id'=>$q->id));
$c1->select('MAX(point) as max_point');
if($max = $modx->getObject('UserTestAnswers',$c1)){
$maxPoint += $max->max_point;
}
break;
case 5: //На сопоставление. Простой
$ext = json_decode($q->extended, 1);
$q1 = $ext['q'];
//$type_point = $ext['type_point']; //0 за правильный ответ. 1 за совпадения.
if($ext['type_point'] == 0){
$maxPoint += $ext['point'];
}else{
$maxPoint += $ext['point']*count($q1);
}
break;
case 7: //Таблица чек-боксов
$Q_childs = $modx->getIterator('UserTestQuestions', array('parent'=>$q->id));
foreach($Q_childs as $qc){
$c1 = $modx->newQuery('UserTestAnswers');
$c1->where(array('question_id'=>$qc->id));
$c1->select('SUM(point) as max_point');
if($max = $modx->getObject('UserTestAnswers',$c1)){
$maxPoint += $max->max_point;
}
}
break;
case 9: //Селекты в тексте
$Q_childs = $modx->getIterator('UserTestQuestions', array('parent'=>$q->id));
foreach($Q_childs as $qc){
$c1 = $modx->newQuery('UserTestAnswers');
$c1->where(array('question_id'=>$qc->id));
$c1->select('MAX(point) as max_point');
if($max = $modx->getObject('UserTestAnswers',$c1)){
$maxPoint += $max->max_point;
}
}
break;
}
}
return $maxPoint;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment