<?php defined('SYSPATH') or die('No direct script access.'); class Controller_Teacher_Rating extends Controller_Environment_Teacher { public function before() { parent::before(); // make it possible to download files Cookie::set('fD', 'true'); } // Получить из кука SGID выбранную ранее группу для данной дисциплины private function getFilterGroupID($disciplineID) { $groups = json_decode(Cookie::get('SGID', null), true); if ($groups && isset($groups[$disciplineID])) { return $groups[$disciplineID]; } return 0; } private static function getTitle($pageType, $try, &$module) { if ($pageType == 'rate') { $title = $module['SubmoduleName']; } else if ($module['ModuleType'] == 'extra') { $title = 'Добор баллов'; } else if ($try === 0) { $title = 'Основная сдача'; } else { $title = 'Пересдача ' . $try; } return $title; } // Шапка таблицы: структура УКД (модули и мероприятия) private function getStructure($id, $pageType) { $structure = Model_Map::getRoadmap($id, $pageType); if ($structure->count() == 0) { throw HTTP_Exception::factory(404, "Страница не найдена"); } $structureHandled = []; $maxRate = $i = $try = 0; // try = 1 - экзамен, = 2, 3 - пересдачи $lastModuleID = -1; foreach ($structure as $row) { if ($row['ModuleID'] != $lastModuleID) { $lastModuleID = $row['ModuleID']; $structureHandled[++$i] = [ 'SubmodulesCount' => 0, 'MaxRate' => 0, 'ModuleTitle' => $row['ModuleName'], 'ModuleType' => $row['ModuleType'], ]; } $j = $structureHandled[$i]['SubmodulesCount'] += 1; $structureHandled[$i]['MaxRate'] += (int) $row['MaxRate']; $curSubmodule = &$structureHandled[$i][$j]; $curSubmodule = $row; $curSubmodule['MaxRate'] = (int) $curSubmodule['MaxRate']; $curSubmodule['Title'] = self::getTitle($pageType, $try, $row); if ($pageType == 'rate' || $row['ModuleType'] == 'extra') { $maxRate += $row['MaxRate']; } else { ++$try; } } $structureHandled['ModulesCount'] = $i; $structureHandled['MaxRate'] = (int) $maxRate; return $structureHandled; } // TODO: extract to view private function processGroupInfo(&$groupInfo) { //GroupID, GroupNum, GradeNum, isAttached etc. $out = $groupInfo; //Формирование заголовка курса $gradeNum = $groupInfo['GradeNum']; $out['GradeTitle'] = ($groupInfo['Degree'] == 'master') ? 'Магистратура, ' . $gradeNum . ' год' : $gradeNum . ' курс'; //Формирование заголовка группы $out['GroupTitle'] = $out['GradeTitle'] . " " . $groupInfo['GroupNum'] . " группа"; return $out; } private function getRatesForRatingPage($info, &$rateResult) { $rateResult = 0; $rates = []; foreach ($info as $row) { $rateResult += $rate = $row['Rate']; $moduleType = $row['ModuleType']; $submoduleID = ($moduleType == 'exam') ? -1 : (($moduleType == 'extra') ? -2 : $row['SubmoduleID']); $rates[] = [ 'Type' => $moduleType, 'SubmoduleID' => $submoduleID, 'Rate' => $rate, ]; } return $rates; } private function correctExtra(&$curStudent, $examType, $lastExtraIndex, $firstEmptyExtraIndex, $totalExtraRate) { $bottomLimit = 0; $maxExtraRate = 0; $topLimit = ($examType == 'exam') ? 38 : 60; if ($curStudent['RateSemesterResult'] >= $bottomLimit && $curStudent['RateSemesterResult'] < $topLimit ) // студент задолженик { $maxExtraRate = $topLimit - $curStudent['RateSemesterResult']; } if ($lastExtraIndex >= 0) { $curStudent['Rates'][$lastExtraIndex]['MaxRate'] = $maxExtraRate - $totalExtraRate + $curStudent['Rates'][$lastExtraIndex]['Rate']; } if ($firstEmptyExtraIndex >= 0) { $curStudent['Rates'][$firstEmptyExtraIndex]['MaxRate'] = $maxExtraRate - $totalExtraRate; } } private function getRatesForExamPage(&$curStudent, $rateList, $examType, $disciplineID) { $rowIndex = 0; $lastExam = $lastExtraIndex = $lastNilExam = $firstEmptyExtra = -1; $rateExtra = 0; $curStudent['RateSemesterResult'] = 0; foreach ($rateList as $curRate) { $moduleType = $curRate['ModuleType']; if ($moduleType == 'exam' || $moduleType == 'extra') { $curStudent['Rates'][$rowIndex] = [ 'SubmoduleID' => $curRate['SubmoduleID'], 'Rate' => $curRate['Rate'], 'ModuleType' => $moduleType, 'ExamPeriodOption' => $curRate['ExamPeriodOption'], ]; } $points = $curRate['Rate']; switch ($moduleType) { case 'regular': $curStudent['RateSemesterResult'] += $points; break; case 'exam': if (!is_null($points)) { if ($lastExam >= 0) { $curStudent['Rates'][$lastExam]['Blocked'] = true; } $lastExam = $rowIndex; } else { if ($lastNilExam < 0) { $lastNilExam = $rowIndex; } else { $curStudent['Rates'][$rowIndex]['Blocked'] = true; } } break; case 'bonus': $curStudent['Bonus'] = $points; break; case 'extra': if ($points) { if ($lastExtraIndex >= 0) { $curStudent['Rates'][$lastExtraIndex]['Blocked'] = true; } $lastExtraIndex = $rowIndex; $curStudent['Rate'] += $curRate['Rate']; $rateExtra += $curRate['Rate']; } else { if ($firstEmptyExtra < 0) { $firstEmptyExtra = $rowIndex; } else { $curStudent['Rates'][$rowIndex]['Blocked'] = true; } } break; default: throw HTTP_Exception::factory(500, "Некорректный тип модуля!"); } $rowIndex++; } // $total = Model_Rating->GetStudentRate($curStudent['ID'], $disciplineID); // $total = ($total[0])?$total[0]['Num']:0; // if ($total) // $total = 0; $curStudent['RateResult'] = $curStudent['RateSemesterResult'] + $rateExtra; if ($lastExam >= 0) { $curStudent['RateResult'] += $curStudent['Rates'][$lastExam]['Rate']; } $this->correctExtra($curStudent, $examType, $lastExtraIndex, $firstEmptyExtra, $rateExtra); } private function showRatingHistory($disciplineID) { $this->twig->set([ 'log' => Model_Rating::getHistory($disciplineID), ])->set_filename('teacher/history'); } /** * @throws HTTP_Exception */ protected function action_rate() { $id = $this->request->param('id'); $pageType = $this->request->param('type'); // 'rate', 'exam', 'history' if ($pageType == 'history') { $this->showRatingHistory($id); return; } $discipline = Model_Discipline::load($id); $discipline['GroupID_Filter'] = $this->getFilterGroupID($id); $discipline['LocalizedExamType'] = RusLang::tr($discipline->Type); // Студенты и их баллы $students = Model_Rating::GetStudentsForRating($id); $rateHandled = []; $groupsHandled = []; $groupInd = $studentInd = $curGroupID = 0; foreach ($students as $row) { if ($curGroupID !== $row['GroupID']) { $curGroupID = $row['GroupID']; $studentInd = 0; $group = &$rateHandled[++$groupInd]; $group = $this->processGroupInfo($row); $groupsHandled[$curGroupID] = $group['GroupTitle']; } // Студенты $group['Students'][$studentInd] = $row; $curStudent = &$group['Students'][$studentInd++]; //ID, Name, isAttached // Баллы студента if ($pageType == 'rate') { $ratesRaw = Model_Rating::getRates($id, $row['ID']); $curStudent['Rates'] = $this->getRatesForRatingPage($ratesRaw, $curStudent['RateResult']); } else { $rate = Model_Rating::getExamRates($id, $row['ID']); $this->getRatesForExamPage($curStudent, $rate, $discipline->Type, $id); } } $twigType = ($pageType == 'rate') ? 'rating' : $pageType; // Шапка таблицы: структура УКД (модули и мероприятия) $this->twig->set([ 'groups' => $groupsHandled, 'rateTable' => $rateHandled, 'headerRate' => $this->getStructure($id, $pageType), 'Discipline' => $discipline, 'Discipline_JSON' => json_encode($discipline), ])->set_filename("teacher/" . $twigType); } }