Last active
August 26, 2020 10:29
-
-
Save touol/790d35835aed28bd3134dbd7eda48fe5 to your computer and use it in GitHub Desktop.
UserTest
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$(document).ready(function() { | |
$("body").on('submit',"#UserTestForm",function(){ | |
if(validate_question() && validate_ask()){ | |
var form = $(this); | |
form.append( '<input type="hidden" name="UserTestActionTpl" value="' + UserTestActionTpl + '"/>' ); | |
form.append( '<input type="hidden" name="UserTestActiontplError" value="' + UserTestActiontplError + '"/>' ); | |
var data = form.serialize(); | |
$.ajax({ | |
type: 'POST', | |
url: UserTestActionUrl, | |
dataType: 'json', | |
data: data, | |
beforeSend: function(data) { | |
form.find('input[type="submit"]').attr('disabled', 'disabled'); | |
}, | |
success: function(data){ | |
if(data.success){ | |
$( "#testuser-main" ).replaceWith(data.html); | |
$('html, body').animate({ scrollTop: $("#testuser-main").offset().top }, 500); | |
var ctx = document.getElementById("chart-area"); | |
if(ctx){ | |
window.myPie = new Chart(ctx.getContext("2d"), config); | |
} | |
} | |
}, | |
error: function (xhr, ajaxOptions, thrownError) { | |
alert(xhr.status); | |
alert(thrownError); | |
}, | |
complete: function(data) { // сoбытиe пoслe любoгo исхoдa | |
form.find('input[type="submit"]').prop('disabled', false); | |
} | |
}); | |
} | |
return false; | |
}); | |
}); | |
function validate_question(){ | |
validate = true; | |
$(".error").remove(); | |
$('.question.validate').each(function (index, value) { | |
//console.log('div' + index + ':' + $(this).attr('id')); | |
//$("input:radio:checked") | |
switch($(this).data('type_id')){ | |
case 1: //Одиночный выбор | |
case 12: //Опросник САН | |
if($(this).find("input:radio:checked").length == 0){ | |
validate = false; | |
$(this).append('<p class="error">На этот вопрос требуется ответ!</p>'); | |
} | |
break; | |
case 7: //Таблица чекбоксов | |
$(this).find('.row').each(function(){ | |
if($(this).find("input:radio:checked").length == 0){ | |
validate = false; | |
$(this).append('<p class="error">На этот вопрос требуется ответ!</p>'); | |
} | |
}); | |
break; | |
case 2: //Множественный выбор | |
if($(this).find("input:checkbox:checked").length == 0){ | |
validate = false; | |
$(this).append('<p class="error">На этот вопрос требуется ответ!</p>'); | |
} | |
break; | |
case 3: //Простой текст | |
if($(this).find("input").val() == ""){ | |
validate = false; | |
$(this).append('<p class="error">На этот вопрос требуется ответ!</p>'); | |
} | |
break; | |
case 4: //Открытый вопрос | |
if($(this).find("input").val() == ""){ | |
validate = false; | |
$(this).append('<p class="error">На этот вопрос требуется ответ!</p>'); | |
} | |
break; | |
case 9: //Селекты в тексте | |
check = true; | |
$(this).find("select").each(function (index, value) { | |
if($(this).val() == 0){ | |
validate = false; | |
check = false; | |
} | |
}); | |
if(!check){ | |
$(this).append('<p class="error">На этот вопрос требуется ответ!</p>'); | |
} | |
break; | |
} | |
}); | |
return validate; | |
} | |
function validate_ask(){ | |
validate = true; | |
$(".error").remove(); | |
$('.ask.validate').each(function (index, value) { | |
if($(this).find("input").val() == ""){ | |
validate = false; | |
$(this).append('<p class="error">Это поле требуется!</p>'); | |
} | |
}); | |
return validate; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class UserTestQuestionCopyProcessor extends modObjectProcessor { | |
public $classKey = 'UserTestQuestions'; | |
/** {@inheritDoc} */ | |
public function process() { | |
/* @var msProduct $source */ | |
$ids = $this->modx->fromJSON($this->getProperty('ids')); | |
if (empty($ids)) { | |
return $this->failure($this->modx->lexicon('usertest_question_err_ns')); | |
} | |
$test_id = $this->getProperty('test_id'); | |
$q_copy_ids = array(); | |
foreach ($ids as $id) { | |
if(!$source = $this->modx->getObject($this->classKey, $id)){ | |
return $this->modx->error->failure(); | |
} | |
if($q = $this->modx->newObject($this->classKey)){ | |
$t = $source->toArray(); | |
unset($t['id']); | |
//$t['test_id'] = $this->getProperty('test_id'); | |
//$count = $this->modx->getCount('UserTestQuestions',array('test_id'=>$t['test_id'], 'parent'=>0)); | |
//$t['menuindex'] = $count + 1; | |
$q->fromArray($t); | |
$q->save(); | |
if (!empty($test_id)) { | |
$count = $this->modx->getCount('UserTestTestQuestionLink',array('test_id'=>$test_id)); | |
$menuindex = $count + 1; | |
if($TestQuestionLink = $this->modx->newObject('UserTestTestQuestionLink')){ | |
$TestQuestionLink->fromArray(array( | |
'menuindex'=>$menuindex, | |
'test_id'=>$test_id, | |
'question_id'=>$q->id, | |
)); | |
$TestQuestionLink->save(); | |
} | |
} | |
$q_copy_ids[] = $q->id; | |
if($q->type == 7 or $q->type == 8 or $q->type == 9){ | |
$c1 = $this->modx->newQuery($this->classKey); | |
$c1->where(array('parent' => $source->id)); | |
$c1->sortby('menuindex'); | |
$q_childs = $this->modx->getIterator($this->classKey, $c1); | |
foreach($q_childs as $q_child){ | |
if($q1 = $this->modx->newObject($this->classKey)){ | |
$t = $q_child->toArray(); | |
unset($t['id']); | |
//$t['test_id'] = $this->getProperty('test_id'); | |
$t['parent'] = $q->id; | |
$q1->fromArray($t); | |
$q1->save(); | |
$answers = $this->modx->getIterator('UserTestAnswers', array('question_id'=>$q_child->id)); | |
foreach($answers as $answer){ | |
$t = $answer->toArray(); | |
unset($t['id']); | |
$t['question_id'] = $q1->id; | |
if($a = $this->modx->newObject('UserTestAnswers')){ | |
$a->fromArray($t); | |
$a->save(); | |
} | |
} | |
} | |
} | |
}else{ | |
$answers = $this->modx->getIterator('UserTestAnswers', array('question_id'=>$source->id)); | |
foreach($answers as $answer){ | |
$t = $answer->toArray(); | |
unset($t['id']); | |
$t['question_id'] = $q->id; | |
if($a = $this->modx->newObject('UserTestAnswers')){ | |
$a->fromArray($t); | |
$a->save(); | |
} | |
} | |
} | |
} | |
} | |
return $this->modx->error->success('',array('q_copy_ids'=>implode(",",$q_copy_ids))); | |
} | |
} | |
return 'UserTestQuestionCopyProcessor'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
UserTest.window.QuestionsWithParent = function (config) { | |
config = config || {}; | |
if (!config.id) { | |
config.id = 'usertest-questions-with-parent-window'; | |
} | |
Ext.applyIf(config, { | |
title: _('usertest_test_questions'), | |
width: 1200, | |
autoHeight: true, | |
url: UserTest.config.connector_url, | |
//action: 'mgr/test/create', | |
fields: [{ | |
xtype: 'hidden', | |
fieldLabel: _('usertest_item_id'), | |
name: 'id', | |
id: config.id + '-' + 'id', | |
anchor: '99%' | |
},{ | |
//title: _('usertest_test_questions'), | |
layout: 'anchor', | |
items: [{ | |
xtype: 'usertest-grid-questions-with-parent', | |
id: config.id + '-grid-questions-with-parent', | |
cls: 'main-wrapper', | |
//test_id: config.record.object.test_id, | |
parent: config.record.object.id, | |
use_category: config.record.object.use_category | |
}] | |
}], | |
keys: [{ | |
key: Ext.EventObject.ENTER, shift: true, fn: function () { | |
//this.submit() | |
}, scope: this | |
}], | |
buttons: [{ | |
text: config.cancelBtnText || _('cancel') | |
,scope: this | |
,handler: function() { config.closeAction !== 'close' ? this.hide() : this.close(); } | |
}] | |
}); | |
UserTest.window.QuestionsWithParent.superclass.constructor.call(this, config); | |
}; | |
Ext.extend(UserTest.window.QuestionsWithParent, MODx.Window, {}); | |
Ext.reg('usertest-questions-with-parent-window', UserTest.window.QuestionsWithParent); | |
UserTest.grid.QuestionsWithParent = function (config) { | |
config = config || {}; | |
if (!config.id) { | |
config.id = 'usertest-grid-questions-with-parent'; | |
} | |
Ext.applyIf(config, { | |
url: UserTest.config.connector_url, | |
fields: this.getFields(config), | |
columns: this.getColumns(config), | |
tbar: this.getTopBar(config), | |
sm: new Ext.grid.CheckboxSelectionModel(), | |
baseParams: { | |
action: 'mgr/question/getlist', | |
//test_id: config.test_id, | |
parent: config.parent, | |
}, | |
save_action: 'mgr/question/autosave', | |
autosave: true, | |
pageSize: 10, | |
listeners: { | |
rowDblClick: function (grid, rowIndex, e) { | |
var row = grid.store.getAt(rowIndex); | |
this.updateItem(grid, e, row); | |
} | |
}, | |
viewConfig: { | |
forceFit: true, | |
enableRowBody: true, | |
autoFill: true, | |
showPreview: true, | |
scrollOffset: 0, | |
/* getRowClass: function (rec) { | |
return !rec.data.active | |
? 'usertest-grid-row-disabled' | |
: ''; | |
} */ | |
}, | |
paging: true, | |
remoteSort: true, | |
autoHeight: true, | |
ddGroup: 'dd', | |
enableDragDrop: true, | |
listeners: { | |
render: {fn: this._initDD, scope: this} | |
} | |
}); | |
UserTest.grid.QuestionsWithParent.superclass.constructor.call(this, config); | |
// Clear selection on grid refresh | |
this.store.on('load', function () { | |
if (this._getSelectedIds().length) { | |
this.getSelectionModel().clearSelections(); | |
} | |
}, this); | |
}; | |
Ext.extend(UserTest.grid.QuestionsWithParent, MODx.grid.Grid, { | |
windows: {}, | |
_initDD: function(grid) { | |
new Ext.dd.DropTarget(grid.el, { | |
ddGroup : 'dd', | |
copy:false, | |
notifyDrop : function(dd, e, data) { | |
var store = grid.store.data.items; | |
var target = store[dd.getDragData(e).rowIndex].data; | |
var source = store[data.rowIndex].data; | |
if ((target.parent == source.parent) && (target.id != source.id)) { | |
dd.el.mask(_('loading'),'x-mask-loading'); | |
MODx.Ajax.request({ | |
url: UserTest.config.connector_url | |
,params: { | |
action: 'mgr/question/sort' | |
,source: source.id | |
,target: target.id | |
} | |
,listeners: { | |
success: {fn:function(r) {dd.el.unmask();grid.refresh();},scope:grid} | |
,failure: {fn:function(r) {dd.el.unmask();},scope:grid} | |
} | |
}); | |
} | |
} | |
}); | |
}, | |
getMenu: function (grid, rowIndex) { | |
var ids = this._getSelectedIds(); | |
var row = grid.getStore().getAt(rowIndex); | |
var menu = UserTest.utils.getMenu(row.data['actions'], this, ids); | |
this.addContextMenuItem(menu); | |
}, | |
createItem: function (btn, e) { | |
//test_id = this.config.test_id; | |
//name = this.config.name; | |
use_category = this.config.use_category; | |
parent = this.config.parent; | |
var w = MODx.load({ | |
xtype: 'usertest-question-with-parent-window-create', | |
id: Ext.id(), | |
use_category:use_category, | |
listeners: { | |
success: { | |
fn: function () { | |
this.refresh(); | |
}, scope: this | |
} | |
} | |
}); | |
w.reset(); | |
w.setValues({type: 1,type_file: 0,parent:parent,question_type:1}); | |
w.show(e.target); | |
}, | |
updateItem: function (btn, e, row) { | |
if (typeof(row) != 'undefined') { | |
this.menu.record = row.data; | |
} | |
else if (!this.menu.record) { | |
return false; | |
} | |
var id = this.menu.record.id; | |
use_category = this.config.use_category; | |
MODx.Ajax.request({ | |
url: this.config.url, | |
params: { | |
action: 'mgr/question/get', | |
id: id | |
}, | |
listeners: { | |
success: { | |
fn: function (r) { | |
var w = MODx.load({ | |
xtype: 'usertest-question-with-parent-window-update', | |
id: Ext.id(), | |
use_category:use_category, | |
record: r, | |
listeners: { | |
success: { | |
fn: function () { | |
this.refresh(); | |
}, scope: this | |
} | |
} | |
}); | |
w.reset(); | |
r.object.name = this.config.name; | |
w.setValues(r.object); | |
w.show(e.target); | |
}, scope: this | |
} | |
} | |
}); | |
}, | |
removeItem: function () { | |
var ids = this._getSelectedIds(); | |
if (!ids.length) { | |
return false; | |
} | |
MODx.msg.confirm({ | |
title: ids.length > 1 | |
? _('usertest_questions_remove') | |
: _('usertest_question_remove'), | |
text: ids.length > 1 | |
? _('usertest_questions_remove_confirm') | |
: _('usertest_question_remove_confirm'), | |
url: this.config.url, | |
params: { | |
action: 'mgr/question/remove', | |
ids: Ext.util.JSON.encode(ids), | |
}, | |
listeners: { | |
success: { | |
fn: function () { | |
this.refresh(); | |
}, scope: this | |
} | |
} | |
}); | |
return true; | |
}, | |
editAnswers: function (btn, e, row) { | |
if (typeof(row) != 'undefined') { | |
this.menu.record = row.data; | |
} | |
else if (!this.menu.record) { | |
return false; | |
} | |
var id = this.menu.record.id; | |
//var type = this.menu.record.type; | |
//console.info(type); | |
MODx.Ajax.request({ | |
url: this.config.url, | |
params: { | |
action: 'mgr/question/get', | |
id: id | |
}, | |
listeners: { | |
success: { | |
fn: function (r) { | |
//console.info(r); | |
var type = r.object.type; | |
if(type < 4 || type == 6){ | |
var w = MODx.load({ | |
xtype: 'usertest-answers-window', | |
id: Ext.id(), | |
record: r, | |
listeners: { | |
success: { | |
fn: function () { | |
this.refresh(); | |
}, scope: this | |
} | |
} | |
}); | |
w.reset(); | |
w.setValues(r.object); | |
w.show(e.target); | |
}else{ | |
switch(type){ | |
case 4: | |
MODx.msg.alert('Сообщение!','Этот тип вопроса не требует задания ответов.',function() { | |
//MODx.clearCache(); | |
},MODx); | |
break; | |
case 5: | |
//console.info(r); | |
var extended = r.object.extended; | |
var q = [];var a = []; | |
if(extended){ | |
extended = Ext.util.JSON.decode(extended); | |
q = extended.q; | |
a = extended.a; | |
r.object.type_point = extended.type_point; | |
r.object.point = extended.point; | |
} | |
//q[0] = "test"; | |
for (var i = 0; i < 10; i++) { | |
r.object["q[" +i +"]"] = q[i]; | |
r.object["a[" +i +"]"] = a[i]; | |
} | |
//console.info(extended); | |
var w = MODx.load({ | |
xtype: 'usertest-answers-type5-window', | |
id: Ext.id(), | |
record: r, | |
listeners: { | |
success: { | |
fn: function () { | |
this.refresh(); | |
}, scope: this | |
} | |
} | |
}); | |
w.reset(); | |
w.setValues(r.object); | |
w.show(e.target); | |
break; | |
case 7: case 8: case 9: | |
//console.info(r); | |
var w = MODx.load({ | |
xtype: 'usertest-questions-window-with-parent', | |
id: Ext.id(), | |
record: r, | |
listeners: { | |
success: { | |
fn: function () { | |
this.refresh(); | |
}, scope: this | |
} | |
} | |
}); | |
w.reset(); | |
w.setValues(r.object); | |
w.show(e.target); | |
break; | |
} | |
} | |
}, scope: this | |
} | |
} | |
}); | |
}, | |
getFields: function () { | |
return ['id','menuindex', 'parent', 'type', 'category_id', 'category_name', 'question', 'type_file', 'file', 'extended', 'actions']; | |
}, | |
getColumns: function (config) { | |
var Columns1 =[{ | |
header: _('usertest_item_id'), | |
dataIndex: 'id', | |
sortable: true, | |
width: 70 | |
}, { | |
header: _('usertest_parent'), | |
dataIndex: 'parent', | |
sortable: true, | |
width: 70, | |
}, { | |
header: _('usertest_menuindex'), | |
dataIndex: 'menuindex', | |
sortable: false, | |
width: 70, | |
editor: {xtype: 'textfield'}, | |
}, { | |
header: _('usertest_category_name'), | |
dataIndex: 'category_name', | |
sortable: false, | |
width: 100, | |
},{ | |
header: _('usertest_question'), | |
dataIndex: 'question', | |
sortable: false, | |
width: 300, | |
}, { | |
header: _('usertest_grid_actions'), | |
dataIndex: 'actions', | |
renderer: UserTest.utils.renderActions, | |
sortable: false, | |
width: 100, | |
id: 'actions' | |
}]; | |
if(config.use_category){ | |
/* Columns1.splice(4, 0, { | |
header: _('usertest_category_name'), | |
dataIndex: 'category_name', | |
sortable: false, | |
width: 100, | |
}); */ | |
} | |
return Columns1; | |
}, | |
getTopBar: function () { | |
return [{ | |
text: '<i class="icon icon-plus"></i> ' + _('usertest_question_create'), | |
handler: this.createItem, | |
scope: this | |
}, '->', { | |
xtype: 'usertest-field-search', | |
width: 250, | |
listeners: { | |
search: { | |
fn: function (field) { | |
this._doSearch(field); | |
}, scope: this | |
}, | |
clear: { | |
fn: function (field) { | |
field.setValue(''); | |
this._clearSearch(); | |
}, scope: this | |
}, | |
} | |
}]; | |
}, | |
onClick: function (e) { | |
var elem = e.getTarget(); | |
if (elem.nodeName == 'BUTTON') { | |
var row = this.getSelectionModel().getSelected(); | |
if (typeof(row) != 'undefined') { | |
var action = elem.getAttribute('action'); | |
if (action == 'showMenu') { | |
var ri = this.getStore().find('id', row.id); | |
return this._showMenu(this, ri, e); | |
} | |
else if (typeof this[action] === 'function') { | |
this.menu.record = row.data; | |
return this[action](this, e); | |
} | |
} | |
} | |
return this.processEvent('click', e); | |
}, | |
_getSelectedIds: function () { | |
var ids = []; | |
var selected = this.getSelectionModel().getSelections(); | |
for (var i in selected) { | |
if (!selected.hasOwnProperty(i)) { | |
continue; | |
} | |
ids.push(selected[i]['id']); | |
} | |
return ids; | |
}, | |
_doSearch: function (tf) { | |
this.getStore().baseParams.query = tf.getValue(); | |
this.getBottomToolbar().changePage(1); | |
}, | |
_clearSearch: function () { | |
this.getStore().baseParams.query = ''; | |
this.getBottomToolbar().changePage(1); | |
}, | |
}); | |
Ext.reg('usertest-grid-questions-with-parent', UserTest.grid.QuestionsWithParent); | |
UserTest.window.CreateQuestionWithParent = function (config) { | |
config = config || {}; | |
if (!config.id) { | |
config.id = 'usertest-question-with-parent-window-create'; | |
} | |
Ext.applyIf(config, { | |
title: _('usertest_question_create'), | |
width: 900, | |
autoHeight: true, | |
url: UserTest.config.connector_url, | |
action: 'mgr/question/create', | |
fields: this.getFields(config), | |
keys: [{ | |
key: Ext.EventObject.ENTER, shift: true, fn: function () { | |
this.submit() | |
}, scope: this | |
}] | |
}); | |
UserTest.window.CreateQuestionWithParent.superclass.constructor.call(this, config); | |
this.on('activate',function(w,e) { | |
if (MODx.loadRTE && UserTest.config.useRTE == "1" && UserTest.config.useRTEinChildQuestions == "1") { | |
MODx.loadRTE(config.id + '-question'); | |
} | |
},this); | |
this.on('deactivate',function(w,e) { | |
if (typeof(tinyMCE) != "undefined" && MODx.loadRTE && UserTest.config.useRTE == "1" && UserTest.config.useRTEinChildQuestions == "1"){ | |
tinyMCE.execCommand('mceRemoveControl',true,config.id + '-question'); | |
} | |
},this); | |
}; | |
Ext.extend(UserTest.window.CreateQuestionWithParent, MODx.Window, { | |
getFields: function (config) { | |
var Fields1 = [{ | |
xtype: 'hidden', | |
fieldLabel: _('usertest_parent'), | |
name: 'parent', | |
id: config.id + '-parent', | |
anchor: '99%', | |
allowBlank: false, | |
}, { | |
xtype: 'hidden', | |
fieldLabel: _('usertest_question_type'), | |
name: 'question_type', | |
id: config.id + '-question_type', | |
anchor: '99%', | |
allowBlank: false, | |
}, { | |
xtype: 'category-combo', | |
fieldLabel: _('usertest_category_name'), | |
//name: 'org_id', | |
id: config.id + '-' + 'category', | |
anchor: '99%' | |
},{ | |
xtype: 'textarea', | |
fieldLabel: _('usertest_question'), | |
name: 'question', | |
id: config.id + '-question', | |
height: 150, | |
anchor: '99%' | |
}]; | |
if(config.use_category){ | |
/* Fields1.splice(3, 0, { | |
xtype: 'category-combo', | |
fieldLabel: _('usertest_category_name'), | |
//name: 'org_id', | |
id: config.id + '-' + 'category', | |
anchor: '99%' | |
}); */ | |
} | |
return Fields1; | |
}, | |
//['id', 'test_id', 'menuindex', 'type', 'question', 'type_file', 'file', 'extended', 'actions']; | |
loadDropZones: function () { | |
} | |
}); | |
Ext.reg('usertest-question-with-parent-window-create', UserTest.window.CreateQuestionWithParent); | |
UserTest.window.UpdateQuestionWithParent = function (config) { | |
config = config || {}; | |
if (!config.id) { | |
config.id = 'usertest-question-with-parent-window-update'; | |
} | |
Ext.applyIf(config, { | |
title: _('usertest_question_update'), | |
width: 900, | |
autoHeight: true, | |
url: UserTest.config.connector_url, | |
action: 'mgr/question/update', | |
fields: this.getFields(config), | |
keys: [{ | |
key: Ext.EventObject.ENTER, shift: true, fn: function () { | |
this.submit() | |
}, scope: this | |
}] | |
}); | |
UserTest.window.UpdateQuestionWithParent.superclass.constructor.call(this, config); | |
this.on('activate',function(w,e) { | |
if (MODx.loadRTE && UserTest.config.useRTE == "1" && UserTest.config.useRTEinChildQuestions == "1") { | |
MODx.loadRTE(config.id + '-question'); | |
} | |
},this); | |
this.on('deactivate',function(w,e) { | |
if (typeof(tinyMCE) != "undefined" && MODx.loadRTE && UserTest.config.useRTE == "1" && UserTest.config.useRTEinChildQuestions == "1"){ | |
tinyMCE.execCommand('mceRemoveControl',true,config.id + '-question'); | |
} | |
},this); | |
}; | |
Ext.extend(UserTest.window.UpdateQuestionWithParent, MODx.Window, { | |
getFields: function (config) { | |
var Fields2 = [{ | |
xtype: 'hidden', | |
name: 'id', | |
id: config.id + '-id', | |
}, { | |
xtype: 'hidden', | |
fieldLabel: _('usertest_parent'), | |
name: 'parent', | |
id: config.id + '-parent', | |
anchor: '99%', | |
allowBlank: false, | |
}, { | |
xtype: 'hidden', | |
fieldLabel: _('usertest_question_type'), | |
name: 'question_type', | |
id: config.id + '-question_type', | |
anchor: '99%', | |
allowBlank: false, | |
}, { | |
xtype: 'category-combo', | |
fieldLabel: _('usertest_category_name'), | |
//name: 'org_id', | |
id: config.id + '-' + 'category', | |
anchor: '99%' | |
},{ | |
xtype: 'textarea', | |
fieldLabel: _('usertest_question'), | |
name: 'question', | |
id: config.id + '-question', | |
height: 150, | |
anchor: '99%' | |
}]; | |
if(config.use_category){ | |
/* Fields2.splice(4, 0, { | |
xtype: 'category-combo', | |
fieldLabel: _('usertest_category_name'), | |
//name: 'org_id', | |
id: config.id + '-' + 'category', | |
anchor: '99%' | |
}); */ | |
} | |
return Fields2; | |
}, | |
loadDropZones: function () { | |
} | |
}); | |
Ext.reg('usertest-question-with-parent-window-update', UserTest.window.UpdateQuestionWithParent); | |
UserTest.combo.TypeQuestionWithParent = function(config) { | |
config = config || {}; | |
Ext.applyIf(config,{ | |
store: new Ext.data.SimpleStore({ | |
fields: ['type', 'name'] | |
,data: [ | |
[1 , _('usertest_type_questions_radiobutton')], | |
[2 , _('usertest_type_questions_checkbox')], | |
[4 , _('usertest_type_questions_open_question')], | |
] | |
}) | |
//,emptyText: _('ms2_combo_select') | |
,displayField: 'name' | |
,valueField: 'type' | |
,hiddenName: 'type' | |
,mode: 'local' | |
,triggerAction: 'all' | |
,editable: false | |
,selectOnFocus: false | |
,preventRender: true | |
,forceSelection: true | |
,enableKeyEvents: true | |
}); | |
UserTest.combo.TypeQuestionWithParent.superclass.constructor.call(this,config); | |
}; | |
Ext.extend(UserTest.combo.TypeQuestionWithParent,MODx.combo.ComboBox, {}); | |
Ext.reg('usertest-combo-question-with-parent-type',UserTest.combo.TypeQuestionWithParent); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<br><br> | |
{*$catResults | print_r*} | |
<div class="row"> | |
<div class="col-md-3"> | |
{foreach $catResults as $cr} | |
<div class="row"> | |
<div class="col-md-6"> | |
<label>{$cr.cat_name}</label> | |
</div> | |
<div class="col-md-3"> | |
{$cr.cat_point} | |
</div> | |
</div> | |
{/foreach} | |
</div> | |
<div class="col-md-9"> | |
<div id="canvas-holder" style="width:100%"> | |
<canvas id="chart-area" /> | |
</div> | |
</div> | |
</div> | |
<script> | |
var randomScalingFactor = function() { | |
return Math.round(Math.random() * 100); | |
}; | |
var getProc = function(point,all) { | |
return Math.round(point / all * 100); | |
}; | |
var config = { | |
type: 'pie', | |
data: { | |
datasets: [{ | |
data: [ | |
{foreach $catResults as $cr} | |
getProc({$cr.cat_point},{$test_point}), | |
{/foreach} | |
], | |
backgroundColor: [ | |
'rgb(255, 99, 132)', | |
'rgb(255, 159, 64)', | |
'rgb(255, 205, 86)', | |
'rgb(75, 192, 192)', | |
'rgb(54, 162, 235)', | |
'rgb(153, 102, 255)', | |
'rgb(201, 203, 207)', | |
], | |
label: 'Dataset 1' | |
}], | |
labels: [ | |
{foreach $catResults as $cr} | |
"{$cr.cat_name} {$cr.cat_point}{if $test.type == 1} из {$cr.max_point}{/if}", | |
{/foreach} | |
] | |
}, | |
options: { | |
responsive: true | |
} | |
}; | |
{if !$check_ajax} | |
onload_chart = function() { | |
{/if} | |
var ctx = document.getElementById("chart-area").getContext("2d"); | |
window.myPie = new Chart(ctx, config); | |
{if !$check_ajax} | |
}; | |
_init.push(onload_chart); | |
{/if} | |
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div id="testuser-main" class="row"> | |
<script> | |
{if !$check_ajax} | |
var _init = []; | |
{/if} | |
</script> | |
<div class="col-md-2"> | |
{if $block_q_number} | |
{foreach $block_q_number as $q} | |
<a href="#" class="step-box__item {if $q.curStepCheck}current{/if} {if $q.ansCheck}check{/if}" | |
onclick="$('#next_step').val({$q.step});$('#UserTestForm').trigger('submit');return false;"> | |
{$q.numberQ} | |
</a> | |
{/foreach} | |
{/if} | |
</div> | |
<div class="col-md-8"> | |
<h1>{$test.name}</h1> | |
<p>{$debug}</p> | |
{if $curStep == "start"} | |
{if $test.description} | |
<h2>Анотация</h2> | |
<div class="row">{$test.description}</div> | |
{/if} | |
{if $test.instruction} | |
<h2>Инструкция</h2> | |
<div class="row">{$test.instruction}</div> | |
{/if} | |
{if $test.appeal} | |
<h2>ОБРАЩЕНИЕ К ПОЛЬЗОВАТЕЛЮ</h2> | |
<div class="row">{$test.appeal}</div> | |
{/if} | |
<form id="UserTestForm" action="{if $_modx->resource.id}{$_modx->makeUrl($_modx->resource.id,'',['test_id'=>$.get.test_id,'step'=>'start'])}{/if}" method="POST"> | |
<input type="hidden" name="test_id" value="{$test_id}"/> | |
<input type="hidden" name="step" value="start"/> | |
<button type="submit" class="btn btn-info">Начать тестирование</button> | |
</form> | |
{elseif $curStep == "finish"} | |
{if $result_status == 3} | |
<p>Тест ожидает проверки преподователем!</p> | |
{else} | |
<script> | |
{if !$check_ajax} | |
onload_af = function() { | |
{/if} | |
$('#af_test_point').val('{$test_point}'); | |
$('#af_var_result').val('{$var_result |preg_replace : '~\n~': ''}'); | |
$('#af_test_name').val('{$test.name |preg_replace : '~\n~': ''}'); | |
$('#af_result_id').val('{$result_id}'); | |
$('#af_max_point').val('{$max_point}'); | |
$('#af_cat_email_results').val('{$cat_email_results}'); | |
$('#sendMail').show(); | |
{if !$check_ajax} | |
}; | |
_init.push(onload_af); | |
{/if} | |
</script> | |
{if $test.use_category} | |
{$_modx->getChunk('tpl.UserTest.CatResult',['check_ajax'=>$check_ajax,'test'=>$test,'catResults'=>$catResults,'test_point'=>$test_point])} | |
{/if} | |
{/if} | |
{else} | |
{if $test_url} | |
<p>Если вы прервали тест, используйте для возврата ссылку: {$test_url}</p> | |
{/if} | |
{*$end_test_time} {$test_time*} | |
{if $end_test_time > 0} | |
<p>До окончания теста: <span id="getting-started"></span></p> | |
<script> | |
{if !$check_ajax} | |
onload_time = function() { | |
{/if} | |
time1 = {$end_test_time}*1000 + Date.now(); | |
$('#getting-started').countdown(time1, function(event) { | |
$(this).html(event.strftime('%H:%M:%S')); | |
}); | |
{if !$check_ajax} | |
}; | |
_init.push(onload_time); | |
{/if} | |
</script> | |
{/if} | |
<div id="testuser-questions"> | |
{*<p>Вы набрали {$test_point} баллов. Время теста: {$test_time}с.</p>*} | |
<form id="UserTestForm" action="{if $_modx->resource.id}{$_modx->makeUrl($_modx->resource.id,'',['test_id'=>$.get.test_id])}{/if}" method="POST"> | |
<input type="hidden" name="test_id" value="{$test_id}"/> | |
{if $enable_cat_child_questions} | |
{foreach $cats_questions as $cat_qs} | |
<br> | |
<div class="row"> | |
<p>Вопрос №{$cat_qs.idx} из {$cat_qs.cat.name}.</p> | |
<p> {$cat_qs.cat.description}</p> | |
{foreach $cat_qs.questions as $q} | |
<div class="row"> | |
{if $q.type == 12} {* Опросник САН *} | |
{var $qarr = $q.question | split : '##'} | |
<div class="col-lg-4"> | |
{$qarr.0} | |
</div> | |
<div class="col-lg-4 question {if $q.validate}validate{/if}" data-id="{$q.id}" data-type_id="{$q.type}"> | |
{foreach $q.answers as $a} | |
<div class="opros_san"> | |
{switch $a.type_file} | |
{case 1} | |
<img src="{$a.file}" alt="{$a.answer}"> | |
{case 2} | |
<video src="{$a.file}" controls></video> | |
{case 3} | |
<audio controls> | |
<source src="{$a.file}" type="audio/mpeg"> | |
</audio> | |
{/switch} | |
{if $q.answer_id == $a.id} | |
<label><input name="question[{$q.id}]" type="radio" value="{$a.id}" checked>{$a.answer}</label> | |
{else} | |
<label><input name="question[{$q.id}]" type="radio" value="{$a.id}">{$a.answer}</label> | |
{/if} | |
</div> | |
{/foreach} | |
</div> | |
<div class="col-lg-4"> | |
{$qarr.1} | |
</div> | |
{/if} | |
</div> | |
{/foreach} | |
</div> | |
{/foreach} | |
{else} | |
{foreach $questions as $q} | |
<br> | |
<div class="row"> | |
<p>Вопрос {$q.numberQ} из {$q.countQ}.</p> | |
{if $q.type == 9} {* Селекты в тексте *} | |
<div class="question {if $q.validate}validate{/if}" data-id="{$q.id}" data-type_id="{$q.type}">{$q.q_str}</div> | |
{elseif $q.type == 12} {* Опросник САН *} | |
{var $qarr = $q.question | split : '##'} | |
<div class="col-lg-4"> | |
{$qarr.0} | |
</div> | |
<div class="col-lg-4 question {if $q.validate}validate{/if}" data-id="{$q.id}" data-type_id="{$q.type}"> | |
{foreach $q.answers as $a} | |
<div class="opros_san"> | |
{switch $a.type_file} | |
{case 1} | |
<img src="{$a.file}" alt="{$a.answer}"> | |
{case 2} | |
<video src="{$a.file}" controls></video> | |
{case 3} | |
<audio controls> | |
<source src="{$a.file}" type="audio/mpeg"> | |
</audio> | |
{/switch} | |
{if $q.answer_id == $a.id} | |
<label><input name="question[{$q.id}]" type="radio" value="{$a.id}" checked>{$a.answer}</label> | |
{else} | |
<label><input name="question[{$q.id}]" type="radio" value="{$a.id}">{$a.answer}</label> | |
{/if} | |
</div> | |
{/foreach} | |
</div> | |
<div class="col-lg-4"> | |
{$qarr.1} | |
</div> | |
{else} | |
<div class="row">{$q.question}</div> | |
{switch $q.type_file} | |
{case 1} | |
<img src="{$q.file}" alt="{$q.question}"> | |
{case 2} | |
<video src="{$q.file}" controls></video> | |
{case 3} | |
<audio controls> | |
<source src="{$q.file}" type="audio/mpeg"> | |
</audio> | |
{/switch} | |
{*$q | print_r : true*} | |
{/if} | |
</div> | |
<div class="row question {if $q.validate}validate{/if}" data-id="{$q.id}" data-type_id="{$q.type}"> | |
{switch $q.type} | |
{case 1} {* Одиночный выбор *} | |
{foreach $q.answers as $a} | |
<div class="col-lg-4"> | |
{switch $a.type_file} | |
{case 1} | |
<img src="{$a.file}" alt="{$a.answer}"> | |
{case 2} | |
<video src="{$a.file}" controls></video> | |
{case 3} | |
<audio controls> | |
<source src="{$a.file}" type="audio/mpeg"> | |
</audio> | |
{/switch} | |
{if $q.answer_id == $a.id} | |
<label><input name="question[{$q.id}]" type="radio" value="{$a.id}" checked>{$a.answer}</label> | |
{else} | |
<label><input name="question[{$q.id}]" type="radio" value="{$a.id}">{$a.answer}</label> | |
{/if} | |
</div> | |
{/foreach} | |
{case 2} {* Множественный выбор *} | |
{foreach $q.answers as $a} | |
<div class="col-lg-4"> | |
{switch $a.type_file} | |
{case 1} | |
<img src="{$a.file}" alt="{$a.answer}"> | |
{case 2} | |
<video src="{$a.file}" controls></video> | |
{case 3} | |
<audio controls> | |
<source src="{$a.file}" type="audio/mpeg"> | |
</audio> | |
{/switch} | |
{if $a.check} | |
<label><input name="question[{$q.id}][]" type="checkbox" value="{$a.id}" checked>{$a.answer}</label> | |
{else} | |
<label><input name="question[{$q.id}][]" type="checkbox" value="{$a.id}">{$a.answer}</label> | |
{/if} | |
</div> | |
{/foreach} | |
{case 3} {* Простой текст *} | |
<div class="form-group"> | |
<input name="question[{$q.id}]" type="text" value="{$q.answer}" class="form-control"> | |
</div> | |
{case 4} {* Открытый вопрос *} | |
<div class="form-group"> | |
<input name="question[{$q.id}]" type="text" value="{$q.answer}" class="form-control"> | |
</div> | |
{case 5} {* На сопоставление. Простой *} | |
<div style="float: left; margin-top: 15px; margin-left: 10px"> | |
<ul style="list-style: none;" class="comparison"> | |
{foreach $q.q as $qk => $qv} | |
<li data-id="{$qk}">{$qv}</li> | |
{/foreach} | |
</ul> | |
</div> | |
<div style="float: left; margin-top: 15px; margin-left: 10px"> | |
<ul id="sortable-{$q.id}" style="list-style: none;" class="comparison"> | |
{foreach $q.a as $ak => $av} | |
<li data-id="{$ak}">{$av}</li> | |
{/foreach} | |
</ul> | |
</div> | |
<input name="question[{$q.id}]" id="ans-{$q.id}" type="hidden" value="{$q.answer}"> | |
<script> | |
{if !$check_ajax} | |
onload_sortable_{$q.id} = function() { | |
{/if} | |
var el = document.getElementById('sortable-{$q.id}'); | |
var sortable{$q.id} = Sortable.create(el,{ | |
onEnd: function (evt) { | |
var order{$q.id} = sortable{$q.id}.toArray(); | |
//console.info(order{$q.id}); | |
var ans{$q.id} = document.getElementById('ans-{$q.id}'); | |
ans{$q.id}.value = order{$q.id}.join('|'); | |
}, | |
}); | |
{if !$check_ajax} | |
}; | |
_init.push(onload_sortable_{$q.id}); | |
{/if} | |
</script> | |
{case 6} {* Комбинированный вариант *} | |
{foreach $q.answers as $a} | |
<div class="col-lg-4"> | |
{switch $a.type_file} | |
{case 1} | |
<img src="{$a.file}" alt="{$a.answer}"> | |
{case 2} | |
<video src="{$a.file}" controls></video> | |
{case 3} | |
<audio controls> | |
<source src="{$a.file}" type="audio/mpeg"> | |
</audio> | |
{/switch} | |
{if $a.check} | |
<label><input name="question[{$q.id}][]" type="checkbox" value="{$a.id}" checked>{$a.answer}</label> | |
{else} | |
<label><input name="question[{$q.id}][]" type="checkbox" value="{$a.id}">{$a.answer}</label> | |
{/if} | |
</div> | |
{/foreach} | |
<div class="col-lg-4"> | |
{if $q.answers_add.check} | |
<label> | |
<input name="question[{$q.id}][ans_add]" type="checkbox" value="" checked> Другое | |
<input name="question[{$q.id}][ans_add_ans]" type="text" value="{$q.answers_add.ans}" class="form-control"> | |
</label> | |
{else} | |
<label> | |
<input name="question[{$q.id}][ans_add]" type="checkbox" value=""> Другое | |
<input name="question[{$q.id}][ans_add_ans]" type="text" value="" class="form-control"> | |
</label> | |
{/if} | |
</div> | |
{case 7} {* Таблица чек-боксов *} | |
{foreach $q.q_childs as $qc} | |
<div class="row"> | |
<div class="col-md-6">{$qc.question}</div> | |
<div class="col-md-6"> | |
{foreach $qc.answers as $a} | |
{if $a.check} | |
<label>{$a.answer | replace : "<p>" : "" | replace : "</p>" : "" }<input name="question[{$q.id}][{$qc.id}][]" type="radio" value="{$a.id}" checked></label> | |
{else} | |
<label>{$a.answer | replace : "<p>" : "" | replace : "</p>" : "" }<input name="question[{$q.id}][{$qc.id}][]" type="radio" value="{$a.id}"></label> | |
{/if} | |
{/foreach} | |
</div> | |
</div> | |
{/foreach} | |
</table> | |
{case 8} {* Таблица текстовых полей *} | |
<table class="table"> | |
<tbody> | |
<tr> | |
{foreach $q.header as $h} | |
<td>{$h}</td> | |
{/foreach} | |
</tr> | |
{foreach $q.q_childs as $qc} | |
<tr> | |
<td>{$qc.question}</td> | |
{foreach $qc.answers as $a} | |
<td> | |
<div class="answer__textarea-box"> | |
<textarea name="question[{$q.id}][{$qc.id}][{$a.id}]" class="answer__textarea">{$a.ac}</textarea> | |
</div> | |
</td> | |
{/foreach} | |
</tr> | |
{/foreach} | |
</tbody> | |
</table> | |
{case 10} {* Комбинированный одиночный выбор *} | |
{foreach $q.answers as $a} | |
<div class="col-lg-4"> | |
{switch $a.type_file} | |
{case 1} | |
<img src="{$a.file}" alt="{$a.answer}"> | |
{case 2} | |
<video src="{$a.file}" controls></video> | |
{case 3} | |
<audio controls> | |
<source src="{$a.file}" type="audio/mpeg"> | |
</audio> | |
{/switch} | |
{if $a.check} | |
<label><input name="question[{$q.id}][ans]" type="radio" value="{$a.id}" checked>{$a.answer}</label> | |
{else} | |
<label><input name="question[{$q.id}][ans]" type="radio" value="{$a.id}">{$a.answer}</label> | |
{/if} | |
</div> | |
{/foreach} | |
<div class="col-lg-4"> | |
{if $q.answers_add.check} | |
<label> | |
<input name="question[{$q.id}][ans]" type="radio" value="ans_add" checked> Другое | |
<input name="question[{$q.id}][ans_add_ans]" type="text" value="{$q.answers_add.ans}" class="form-control"> | |
</label> | |
{else} | |
<label> | |
<input name="question[{$q.id}][ans]" type="radio" value="ans_add"> Другое | |
<input name="question[{$q.id}][ans_add_ans]" type="text" value="" class="form-control"> | |
</label> | |
{/if} | |
</div> | |
{/switch} | |
</div> | |
{/foreach} | |
{/if} | |
<div class="row"> | |
<input type="hidden" name="step" id="next_step" value="{$nextStep}"> | |
<input type="hidden" name="answer_step" id="answer_step" value="{$curStep}"> | |
<div class="col-lg-4"> | |
{*if $prevStep != "start"} | |
<button type="submit" onclick="$('#next_step').val({$prevStep});return true;" class="btn btn-info">Предудущие вопросы</button> | |
{/if*} | |
</div> | |
<div class="col-lg-4 pull-right"> | |
{if $nextStep != "finish"} | |
<button type="submit" class="btn btn-info">Далее</button> | |
{else} | |
<button type="submit" class="btn btn-info">Финиш</button> | |
{/if} | |
</div> | |
</div> | |
</form> | |
</div> | |
{/if} | |
</div> | |
<div class="col-md-2"> | |
{if $test.customer} | |
{*<h2>Инструкция</h2>*} | |
<div class="row">{$test.customer}</div> | |
{/if} | |
</div> | |
{if !$check_ajax} | |
<script> | |
window.onload = function() | |
{ | |
for ( var i in _init ) | |
{ | |
if ( typeof( _init[i] ) == 'function' ) _init[i](); // вызываем подряд все функции из _init | |
} | |
} | |
</script> | |
{/if} | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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: //Таблица чек-боксов | |
$c1 = $modx->newQuery('UserTestQuestions'); | |
$c1->where(array('parent' =>$q_id['id'])); | |
$c1->sortby('menuindex'); | |
$q_childs = $modx->getIterator('UserTestQuestions', $c1); | |
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->sortby('sum_point DESC, cat_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 .= "<p>".$cr['cat_name'].": ".$cat_result->cat_point." </p>"; | |
} | |
} | |
} | |
//ссылка на правильные ответы | |
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('UserTestQuestions','UserTestQuestions2', '`UserTestQuestions`.`parent` = `UserTestQuestions2`.`id`'); | |
$c->leftJoin('UserTestTestQuestionLink','UserTestTestQuestionLink', '`UserTestTestQuestionLink`.`question_id` = `UserTestQuestions2`.`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,'`UserTestQuestions2`.`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 "<pre>".$c->toSQL()."</pre>"; | |
$Questions = $modx->getCollection('UserTestQuestions', $c); | |
$maxPoint=0; | |
foreach($Questions as $q){ | |
//echo "<pre>".print_r($q->toArray(),1)."</pre>"; | |
switch($q->type){ | |
case 8: //Таблица текстовых полей | |
case 4: //Открытый вопрос | |
case 6: //Комбинированный вариант | |
case 10: //usertest_type_questions_combined_radiobutton | |
$maxPoint += $q->max_point; | |
break; | |
default: | |
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