fix TestingQuestionPassing and AdminGrid

parent 4f4686ee
...@@ -7,8 +7,8 @@ Website: http://www.seantheme.com/color-admin-v1.6/admin/ ...@@ -7,8 +7,8 @@ Website: http://www.seantheme.com/color-admin-v1.6/admin/
var handleDataTableColVis = function() { var handleDataTableColVis = function() {
"use strict"; "use strict";
$('table.table.table-striped.table-bordered .empty').closest('tr').remove(); $('.dataTable .empty').closest('tr').remove();
if ($('table.table.table-striped.table-bordered').length !== 0) { if ($('.dataTable').length !== 0) {
var table = $('table.table.table-striped.table-bordered').DataTable({ var table = $('table.table.table-striped.table-bordered').DataTable({
dom: 'C<"clear">lfrtip', dom: 'C<"clear">lfrtip',
paging: false, paging: false,
......
...@@ -10,7 +10,7 @@ abstract class AdminController extends \common\components\BaseController ...@@ -10,7 +10,7 @@ abstract class AdminController extends \common\components\BaseController
public static function getLocalId() { public static function getLocalId() {
return str_replace('Controller','',self::className()); return str_replace('Controller', '', self::className());
} }
public function init() public function init()
...@@ -32,69 +32,8 @@ abstract class AdminController extends \common\components\BaseController ...@@ -32,69 +32,8 @@ abstract class AdminController extends \common\components\BaseController
$this->redirect($admin_url); $this->redirect($admin_url);
} }
$this->initTabs();
$this->view->registerJsFile('/js/packages/adminBaseClasses/buttonSet.js'); $this->view->registerJsFile('/js/packages/adminBaseClasses/buttonSet.js');
$this->view->registerJsFile('/js/packages/adminBaseClasses/gridBase.js'); $this->view->registerJsFile('/js/packages/adminBaseClasses/gridBase.js');
} }
private function initTabs()
{
/* $tabs = array();
$actions_titles = call_user_func(array(get_class(Yii::app()->controller), 'actionsTitles'));
foreach ($actions_titles as $action => $title)
{
if (in_array($action, array('Delete', 'Update', 'View')))
{
continue;
}
$tabs[$title] = $this->createUrl($action);
}
$this->tabs = $tabs;*/
}
private function initAssets()
{
/* $assets_dir = MODULES_PATH . Yii::app()->controller->module->id . '/assets/';
if (!is_dir($assets_dir))
{
return;
}
$dir_names = array('css', 'js');
foreach ($dir_names as $dir_name)
{
$dir = $assets_dir . $dir_name . '/';
if (!is_dir($dir))
{
continue;
}
$asset_dir = Yii::app()->getAssetManager()->publish($dir) . '/';
$scripts = scandir($dir);
foreach ($scripts as $script)
{
if ($script[0] == '.')
{
continue;
}
if ($dir_name == 'js')
{
echo $asset_dir . $script . "<br>";
Yii::app()->clientScript->registerScriptFile($asset_dir . $script);
}
else if ($dir_name == 'css')
{
Yii::app()->clientScript->registerCssFile($asset_dir . $script);
}
}
}*/
}
} }
...@@ -11,6 +11,7 @@ use common\modules\testings\models\TestingTest; ...@@ -11,6 +11,7 @@ use common\modules\testings\models\TestingTest;
use common\modules\testings\models\TestingPassing; use common\modules\testings\models\TestingPassing;
use common\modules\testings\models\SearchTestingPassing; use common\modules\testings\models\SearchTestingPassing;
use common\modules\testings\models\TestingSession; use common\modules\testings\models\TestingSession;
use common\modules\testings\models\SearchTestingQuestionPassing;
use common\modules\testings\models\TestingQuestionPassing; use common\modules\testings\models\TestingQuestionPassing;
class TestingPassingAdminController extends AdminController class TestingPassingAdminController extends AdminController
...@@ -44,12 +45,13 @@ class TestingPassingAdminController extends AdminController ...@@ -44,12 +45,13 @@ class TestingPassingAdminController extends AdminController
public function actionView($id) public function actionView($id)
{ {
// $questions = new TestingQuestionPassing('search'); $searchModel = new SearchTestingQuestionPassing();
// $questions->unsetAttributes(); $dataProvider = $searchModel->search(Yii::$app->request->queryParams, null, null, $id);
return $this->render('view', [ return $this->render('view', [
'model' => $this->findModel($id), 'model' => $this->findModel($id),
'questions' => $questions, 'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'time' => $this->showPeriod($model->time), 'time' => $this->showPeriod($model->time),
]); ]);
} }
...@@ -223,7 +225,7 @@ class TestingPassingAdminController extends AdminController ...@@ -223,7 +225,7 @@ class TestingPassingAdminController extends AdminController
*/ */
protected function findModel($id) protected function findModel($id)
{ {
if (($model = TestingAnswer::findOne($id)) !== null) { if (($model = TestingPassing::findOne($id)) !== null) {
return $model; return $model;
} else { } else {
throw new NotFoundHttpException('The requested page does not exist.'); throw new NotFoundHttpException('The requested page does not exist.');
......
<?php
namespace common\modules\testings\models;
use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use common\modules\testings\models\TestingQuestionPassing;
class SearchTestingQuestionPassing extends TestingQuestionPassing
{
/**
* @inheritdoc
*/
public function rules()
{
return [
[['id', 'passing_id', 'question_id', 'answer_time'], 'integer'],
[['id', 'passing_id', 'question_id', 'user_answer', 'answer_time'], 'safe'],
];
}
/**
* @inheritdoc
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* @param array $params
*
* @return ActiveDataProvider
*/
public function search($params, $order = null, $limit = null, $passing_id = null)
{
$query = TestingQuestionPassing::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
'pagination' => ['pageSize' => self::PAGE_SIZE],
'sort'=>array(
'defaultOrder'=>'create_date DESC',
),
]);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
$query->andFilterWhere([
'id' => $this->id,
'passing_id' => $this->passing_id,
'question_id' => $this->question_id,
'answer_time' => $this->answer_time,
]);
$query->andFilterWhere(['like', 'user_answer', $this->user_answer]);
if($passing_id)
{
$query->andWhere(['passing_id' => $passing_id]);
}
if(!empty($order))
$query->orderBy($order);
if(!empty($limit))
$query->limit($limit);
return $dataProvider;
}
}
\ No newline at end of file
...@@ -109,38 +109,19 @@ class TestingPassing extends \common\components\ActiveRecordModel ...@@ -109,38 +109,19 @@ class TestingPassing extends \common\components\ActiveRecordModel
return $this->hasMany(TestingQuestionPassing::className(), ['passing_id' => 'id']); return $this->hasMany(TestingQuestionPassing::className(), ['passing_id' => 'id']);
} }
public function search() { public function getCountPassedQuestions()
{
$criteria = $this->buildSearchCriteria();
return new ActiveDataProvider(get_class($this), array(
'criteria' => $criteria
));
}
public function getCountPassedQuestions() {
//Получаем все вопросы
$questions = TestingQuestionPassing::model()->findAllByAttributes(
array('passing_id' => $this->id)
);
$count = 0; $count = 0;
foreach($questions as $question) {
if($question->isRight) { foreach($this->questions as $question)
{
if($question->isRight)
{
$count++; $count++;
} }
} }
return $count; return $count;
/*
$sql = 'SELECT count(*) FROM testings_questions q
INNER JOIN testings_answers a ON q.id = a.question_id
WHERE q.test_id = :test_id AND a.is_right = :is_right';
$count = Yii::app()->db->createCommand($sql)->queryScalar(array(
'test_id' => $this->id,
'is_right' => TestingAnswer::IS_RIGHT,
));
return $count;
*
*/
} }
......
...@@ -114,33 +114,52 @@ class TestingQuestion extends \common\components\ActiveRecordModel ...@@ -114,33 +114,52 @@ class TestingQuestion extends \common\components\ActiveRecordModel
public function getRightAnswer() public function getRightAnswer()
{ {
switch ($this->type) { $query = TestingAnswer::find()->where(['question_id' => $this->id]);
case self::ONE_OPTION :
$answerModel = TestingAnswer::model()->find('question_id = :question and is_right = 1',array(':question' => $this->id)); switch ($this->type)
if ($answerModel) { {
$answer = trim(preg_replace('/\s+/', ' ', $answerModel->text)); case self::ONE_OPTION:
} else { $model = $query->andWhere(['is_right' => 1])->one();
if($model)
{
$answer = trim(preg_replace('/\s+/', ' ', $model->text));
}
else
{
$answer = null; $answer = null;
} }
break; break;
case self::FEW_OPTIONS :
$answerModel = TestingAnswer::model()->findAll('question_id = :question and is_right = 1',array(':question' => $this->id)); case self::FEW_OPTIONS:
if ($answerModel) { $models = $query->andWhere(['is_right' => 1])->all();
if ($models)
{
$arr = array(); $arr = array();
foreach ($answerModel as $answerItem) {
$arr[] = trim(preg_replace('/\s+/', ' ', $answerItem->text)); foreach ($models as $model)
{
$arr[] = trim(preg_replace('/\s+/', ' ', $model->text));
} }
sort($arr); sort($arr);
$answer = implode(self::DELIMITER,$arr); $answer = implode(self::DELIMITER, $arr);
} else { }
else
{
$answer = null; $answer = null;
} }
break; break;
case self::USER_ANSWER :
$answerModel = TestingAnswer::model()->find('question_id = :question',array(':question' => $this->id)); case self::USER_ANSWER:
if ($answerModel) { $models = $query->one();
$answer = trim(preg_replace('/\s+/', ' ', $answerModel->text)); if ($model)
} else { {
$answer = trim(preg_replace('/\s+/', ' ', $model->text));
}
else
{
$answer = null; $answer = null;
} }
break; break;
......
<?php <?php
class TestingQuestionPassing extends ActiveRecordModel namespace common\modules\testings\models;
{
const PAGE_SIZE = 10;
public static function model($className=__CLASS__) use Yii;
{ use yii\behaviors\TimestampBehavior;
return parent::model($className); use yii\db\Expression;
}
use common\modules\testings\models\TestingQuestion;
use common\modules\testings\models\TestingPassing;
class TestingQuestionPassing extends \common\components\ActiveRecordModel
{
const PAGE_SIZE = 10;
public function tableName() public static function tableName()
{ {
return 'testings_questions_passings'; return 'testings_questions_passings';
} }
...@@ -18,49 +21,59 @@ class TestingQuestionPassing extends ActiveRecordModel ...@@ -18,49 +21,59 @@ class TestingQuestionPassing extends ActiveRecordModel
public function name() public function name()
{ {
return 'Модель TestingsQuestionsPassings'; return 'Назначенные вопросы';
} }
public function behaviors(){ /**
return array( * @inheritdoc
'CTimestampBehavior' => array( */
'class' => 'zii.behaviors.CTimestampBehavior', public function behaviors()
'createAttribute' => 'create_date', {
'updateAttribute' => null, return [
) [
); 'class' => TimestampBehavior::className(),
} 'createdAtAttribute' => 'create_date',
'updatedAtAttribute' => null,
'value' => new Expression('NOW()'),
],
];
}
/**
* @inheritdoc
*/
public function rules() public function rules()
{ {
return array( return [
array('passing_id, question_id', 'required'), [['passing_id', 'question_id'], 'required'],
array('passing_id, answer_time', 'numerical', 'integerOnly' => true), [['passing_id', 'answer_time'], 'integer'],
array('question_id', 'length', 'max' => 11), [['question_id'], 'string', 'max' => 11],
array('user_answer', 'length', 'max' => 3000), [['user_answer'], 'string', 'max' => 3000],
// array('id, passing_id, question_id, user_answer, answer_time', 'safe', 'on' => 'search'),
array('id, passing_id, question_id, user_answer, answer_time', 'safe', 'on' => 'search'), ];
);
} }
public function attributeLabels() { public function attributeLabels()
return array( {
return [
'question_id' => 'Наименование вопроса', 'question_id' => 'Наименование вопроса',
'user_answer' => 'Ответ пользователя', 'user_answer' => 'Ответ пользователя',
'answer_time' => 'Время прохождения, секунд', 'answer_time' => 'Время прохождения, секунд',
'create_date' => 'Дата создания', 'create_date' => 'Дата создания',
'question_text' => 'Текст вопроса', 'question_text' => 'Текст вопроса',
'answer_text' => 'Правильный ответ', 'answer_text' => 'Правильный ответ',
); ];
} }
public function relations() public function getQuestion()
{ {
return array( return $this->hasOne(TestingQuestion::className(), ['id' => 'question_id']);
'question' => array(self::BELONGS_TO, 'TestingQuestion', 'question_id'), }
'passing' => array(self::BELONGS_TO, 'TestingPassing', 'passing_id'),
); public function getPassing()
} {
return $this->hasOne(TestingPassing::className(), ['passing_id' => 'id']);
}
public function search($passing = null) public function search($passing = null)
{ {
...@@ -82,31 +95,39 @@ class TestingQuestionPassing extends ActiveRecordModel ...@@ -82,31 +95,39 @@ class TestingQuestionPassing extends ActiveRecordModel
)); ));
} }
public function getIsRight() { public function getIsRight()
{
$right = false; $right = false;
switch ($this->question->type) {
case TestingQuestion::ONE_OPTION : switch ($this->question->type)
{
case TestingQuestion::ONE_OPTION:
$right = (trim($this->answer_text) == trim($this->user_answer)); $right = (trim($this->answer_text) == trim($this->user_answer));
break; break;
case TestingQuestion::FEW_OPTIONS :
case TestingQuestion::FEW_OPTIONS:
$arr = explode(TestingQuestion::DELIMITER, $this->answer_text); $arr = explode(TestingQuestion::DELIMITER, $this->answer_text);
foreach ($arr as $index => $item) { foreach ($arr as $index => $item)
{
$arr[$index] = trim(preg_replace('/\s+/', ' ', mb_strtolower($item))); $arr[$index] = trim(preg_replace('/\s+/', ' ', mb_strtolower($item)));
} }
$arr2 = explode(TestingQuestion::DELIMITER, $this->user_answer); $arr2 = explode(TestingQuestion::DELIMITER, $this->user_answer);
foreach ($arr2 as $index => $item) { foreach ($arr2 as $index => $item)
{
$arr2[$index] = trim(preg_replace('/\s+/', ' ', mb_strtolower($item))); $arr2[$index] = trim(preg_replace('/\s+/', ' ', mb_strtolower($item)));
} }
sort($arr); sort($arr);
sort($arr2); sort($arr2);
$right = ($arr == $arr2); // TRUE в случае, если $a и $b содержат одни и те же элементы $right = ($arr == $arr2); // TRUE в случае, если $a и $b содержат одни и те же элементы
break; break;
case TestingQuestion::USER_ANSWER :
case TestingQuestion::USER_ANSWER:
$opt1 = str_replace(';', ',', preg_replace('/\s+/', '', mb_strtolower($this->answer_text))); $opt1 = str_replace(';', ',', preg_replace('/\s+/', '', mb_strtolower($this->answer_text)));
$opt2 = str_replace(';', ',', preg_replace('/\s+/', '', mb_strtolower($this->user_answer))); $opt2 = str_replace(';', ',', preg_replace('/\s+/', '', mb_strtolower($this->user_answer)));
$right = (trim($opt1) == trim($opt2)); $right = (trim($opt1) == trim($opt2));
break; break;
} }
return $right; return $right;
} }
......
...@@ -7,8 +7,6 @@ use common\modules\testings\models\TestingAnswer; ...@@ -7,8 +7,6 @@ use common\modules\testings\models\TestingAnswer;
/* @var $this yii\web\View */ /* @var $this yii\web\View */
$this->title = $model->text;
?> ?>
<div class="faq-view"> <div class="faq-view">
......
...@@ -2,15 +2,25 @@ ...@@ -2,15 +2,25 @@
use yii\helpers\Html; use yii\helpers\Html;
use yii\widgets\DetailView; use yii\widgets\DetailView;
use \common\components\zii\AdminGrid;
use common\modules\testings\models\TestingQuestion; use common\modules\testings\models\TestingPassing;
/* @var $this yii\web\View */ /* @var $this yii\web\View */
$this->title = $model->text;
?> ?>
<style type="text/css">
.STATE1 {
font-weight: bold;
color: #449944;
}
.STATE {
font-weight: bold;
color: #ee4444;
}
</style>
<div class="faq-view"> <div class="faq-view">
<?= DetailView::widget([ <?= DetailView::widget([
...@@ -18,42 +28,23 @@ $this->title = $model->text; ...@@ -18,42 +28,23 @@ $this->title = $model->text;
'attributes' => [ 'attributes' => [
[ [
'attribute' => 'user_id', 'attribute' => 'user_id',
'value' => function($model) 'value' => ($model->user) ? Html::a($model->user->fio, ["/testings/testing-user-admin/view", "id" => $model->user->id]) : "Пользователь удалён",
{
if($model->user)
{
return Html::a($model->user->fio, ["/testings/testing-user-admin/view", "id" => $model->user->id]);
}
else
{
return "Пользователь удалён";
}
},
'format' => 'html', 'format' => 'html',
], ],
[ [
'attribute' => 'session_id', 'attribute' => 'session_id',
'value' => function($model) 'value' => Html::a($model->test->session->name, ["/testings/testing-session-admin/view", "id" => $model->test->session_id]),
{
return Html::a($model->test->session->name, ["/testings/testing-session-admin/view", "id" => $model->test->session_id]);
},
'format' => 'html', 'format' => 'html',
], ],
[ [
'attribute' => 'test_id', 'attribute' => 'test_id',
'value' => function($model) 'value' => Html::a($model->test->name, ["/testings/testing-test-admin/view", "id" => $model->test_id]),
{
return Html::a($model->test->name, ["/testings/testing-test-admin/view", "id" => $model->test_id]);
},
'format' => 'html', 'format' => 'html',
], ],
[ [
'attribute' => 'is_passed', 'attribute' => 'is_passed',
'format' => 'raw', 'format' => 'raw',
'value' => function($model) 'value' => TestingPassing::$state_list[$model->is_passed] . " ({$model->CountPassedQuestions} - {$model->percent_rights}%)",
{
return TestingPassing::$state_list[$model->is_passed] . " ({$model->CountPassedQuestions} - {$model->percent_rights}%)";
},
], ],
'pass_date', 'pass_date',
], ],
...@@ -62,76 +53,43 @@ $this->title = $model->text; ...@@ -62,76 +53,43 @@ $this->title = $model->text;
</div> </div>
<style type="text/css">
.STATE1 {
font-weight: bold;
color: #449944;
}
.STATE {
font-weight: bold;
color: #ee4444;
}
</style>
<br /><br /> <br /><br />
<h1>Подробная статистика по ответам</h1> <h1>Подробная статистика по ответам</h1>
<h3>(Всего времени затрачено: <?php echo $time; ?>)</h3> <h3>(Всего времени затрачено: <?php echo $time; ?>)</h3>
<?php
$this->widget('AdminGrid', array( <?php echo AdminGrid::widget([
'id' => 'testing-question-passing-grid', 'dataProvider' => $dataProvider,
'dataProvider' => $questions->search($model->id), // 'emptyText'=>'Подробная статистика появится тут после того, как пользователь начнёт тестирование',
'filter' => $questions, 'filterModel' => $searchModel,
'columns' => array( 'columns' => [
array( // ['class' => 'yii\grid\SerialColumn'],
'name' => 'question_id',
'value' => '$data->question->text', [
'filter' => false, 'attribute' => 'question_id',
), 'value' => function($model)
array( {
'header' => 'Правильный ответ', return $model->question->text;
'value' => '$data->question->rightAnswer', }
'filter' => false, ],
), [
array( 'header' => 'Правильный ответ',
'name' => 'user_answer', 'value' => function($model)
'filter' => false, {
), return $model->question->rightAnswer;
array( }
'header' => 'Ответ', ],
'value' => 'CHtml::tag("span",array("class"=>"STATE".$data->isRight),TestingPassing::$answer_list[$data->isRight])." ".' 'user_answer',
.'CHtml::link("Изменить на обратное",array("/testings/testingPassingAdmin/changeAnswerStatus","qp_id"=>$data->id))', [
'filter' => false, 'header' => 'Ответ',
'type' => 'html', 'value' => function($model)
), {
array( return Html::tag("span", TestingPassing::$answer_list[$model->isRight], ["class"=>"STATE".$model->isRight]) . " " . Html::a("Изменить на обратное", ["/testings/testing-passing-admin/change-answer-status", "qp_id" => $model->id]);
'name' => 'answer_time', },
'filter' => false, 'format' => 'html'
), ],
), 'answer_time',
'emptyText'=>'Подробная статистика появится тут после того, как пользователь начнёт тестирование', ],
)); ]); ?>
...@@ -7,8 +7,6 @@ use common\modules\testings\models\TestingQuestion; ...@@ -7,8 +7,6 @@ use common\modules\testings\models\TestingQuestion;
/* @var $this yii\web\View */ /* @var $this yii\web\View */
$this->title = $model->text;
?> ?>
<div class="faq-view"> <div class="faq-view">
......
...@@ -6,25 +6,15 @@ use yii\widgets\DetailView; ...@@ -6,25 +6,15 @@ use yii\widgets\DetailView;
/* @var $this yii\web\View */ /* @var $this yii\web\View */
/* @var $model common\modules\faq\models\Faq */ /* @var $model common\modules\faq\models\Faq */
$this->title = $model->name;
$this->params['breadcrumbs'][] = ['label' => 'Список сессий', 'url' => ['/testings/testing-session-admin/manage']];
$this->params['breadcrumbs'][] = 'Сессия "' . $model->name;
?> ?>
<div class="faq-view"> <div class="faq-view">
<h1><?= Html::encode($this->title) ?></h1> <h1><?= Html::encode($model->name) ?></h1>
<p> <p>
<?= Html::a(Yii::t('content', 'Update'), ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?> <?= Html::a(Yii::t('content', 'Update'), ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
<!-- <?= Html::a(Yii::t('content', 'Delete'), ['delete', 'id' => $model->id], [ <?= Html::a("Экспорт результатов", ['testings/testing-session-admin/export-session-result', 'id' => $model->id], ['class' => 'btn btn-info']) ?>
'class' => 'btn btn-danger',
'data' => [
'confirm' => Yii::t('content', 'Are you sure you want to delete this item?'),
'method' => 'post',
],
]) ?> -->
</p> </p>
<?= DetailView::widget([ <?= DetailView::widget([
......
...@@ -6,13 +6,11 @@ use yii\widgets\DetailView; ...@@ -6,13 +6,11 @@ use yii\widgets\DetailView;
/* @var $this yii\web\View */ /* @var $this yii\web\View */
/* @var $model common\modules\faq\models\Faq */ /* @var $model common\modules\faq\models\Faq */
$this->title = $model->name;
?> ?>
<div class="faq-view"> <div class="faq-view">
<h1><?= Html::encode($this->title) ?></h1> <h1><?= Html::encode($model->name) ?></h1>
<p> <p>
<?= Html::a(Yii::t('content', 'Update'), ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?> <?= Html::a(Yii::t('content', 'Update'), ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
......
...@@ -8,13 +8,11 @@ use common\modules\testings\models\TestingUser; ...@@ -8,13 +8,11 @@ use common\modules\testings\models\TestingUser;
/* @var $this yii\web\View */ /* @var $this yii\web\View */
/* @var $model common\modules\faq\models\Faq */ /* @var $model common\modules\faq\models\Faq */
$this->title = $model->fio;
?> ?>
<div class="faq-view"> <div class="faq-view">
<h1><?= Html::encode($this->title) ?></h1> <h1><?= Html::encode($model->fio) ?></h1>
<p> <p>
<?= Html::a(Yii::t('content', 'Update'), ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?> <?= Html::a(Yii::t('content', 'Update'), ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment