Skip to content
Snippets Groups Projects
Rating.php 12 KiB
Newer Older
<?php defined('SYSPATH') or die('No direct script access.');

class Controller_Teacher_Rating extends Controller_UserEnvironment
{
    /** @var  Model_Rating */
PavelBegunkov's avatar
PavelBegunkov committed
    protected $model_rating;
    /** @var  Model_Map */
    protected $model_discipline;

    public function before() {
        Cookie::set('fD', 'true'); // Ставим кук fD, чтоб иметь возможность скачать отчет TODO

        $this->model_rating = new Model_Rating;
        $this->model_discipline = new Model_Map;
        parent::before();
    }

    // Получить из кука SGID выбранную ранее группу для данной дисциплины
PavelBegunkov's avatar
PavelBegunkov committed
    private function getGroupID_ForFilter($id) {
PavelBegunkov's avatar
PavelBegunkov committed
        if ($SG_array !== null && array_key_exists($id, $SG_array)) {
PavelBegunkov's avatar
PavelBegunkov committed
    // Шапка таблицы: структура УКД (модули и мероприятия)
    private function getStructure($id, $type) {
        $teacherID = $this->user['TeacherID'];
PavelBegunkov's avatar
PavelBegunkov committed
        if ($type == "rating") {
PavelBegunkov's avatar
PavelBegunkov committed
            $structure = $this->model_rating->getMapForDiscipline($id);
PavelBegunkov's avatar
PavelBegunkov committed
        } else {
PavelBegunkov's avatar
PavelBegunkov committed
            $structure = $this->model_rating->GetMapForDisciplineExam($id);
PavelBegunkov's avatar
PavelBegunkov committed
        }
        if($structure->count() == 0) {
            throw HTTP_Exception::factory (404, "Страница не найдена");
        }
PavelBegunkov's avatar
PavelBegunkov committed
        $structureHandled = array();
        $maxRate = $i = 0;
        $temp_moduleID = -1;
        $try = 0; // try = 1 - экзамен, = 2, 3 - пересдачи
PavelBegunkov's avatar
PavelBegunkov committed
        
        foreach($structure as $row) {
PavelBegunkov's avatar
PavelBegunkov committed
                ++$i; // todo
                $structureHandled[$i]['SubmodulesCount'] = 0;
                $structureHandled[$i]['MaxRate'] = 0;
PavelBegunkov's avatar
PavelBegunkov committed
                $structureHandled[$i]['ModuleTitle'] = $row['ModuleName'];
                $structureHandled[$i]['ModuleType'] = $row['ModuleType'];
PavelBegunkov's avatar
PavelBegunkov committed

            $j = $structureHandled[$i]['SubmodulesCount'] += 1;
            $structureHandled[$i]['MaxRate'] += (int) $row['MaxRate'];
PavelBegunkov's avatar
PavelBegunkov committed

PavelBegunkov's avatar
PavelBegunkov committed
            $cur_submodule = array();
            $cur_submodule = $row;
            $cur_submodule['MaxRate'] = (int)$cur_submodule['MaxRate'];
            
            if ($type == "rating") {
PavelBegunkov's avatar
PavelBegunkov committed
                $cur_submodule['Title'] = $row['SubmoduleName'];
PavelBegunkov's avatar
PavelBegunkov committed
                $maxRate += $row['MaxRate'];
            } else { //$type == "exam"
                if ($row['ModuleType'] == 'extra') {
                    $cur_submodule['Title'] = 'Добор баллов';
                    $maxRate += $row['MaxRate'];
                }
                else {
                    if ($try === 0) {
                        $cur_submodule['Title'] = 'Основная сдача';
                    } else {
                        $cur_submodule['Title'] = 'Пересдача ' . $try;
                    }
                    $try++;
                }
PavelBegunkov's avatar
PavelBegunkov committed
            }
PavelBegunkov's avatar
PavelBegunkov committed
            $structureHandled[$i][$j] = $cur_submodule;
        $structureHandled['ModulesCount'] = $i;
PavelBegunkov's avatar
PavelBegunkov committed
        $structureHandled['MaxRate'] = (int) $maxRate;
        return $structureHandled;
    }
    
    private function processGroupInfo($groupInfo) {
PavelBegunkov's avatar
PavelBegunkov committed
        //GroupID, GroupNum, GradeNum, isAttached etc.
        $out = $groupInfo;
        
        //Формирование заголовка курса
        $gradeNum = $groupInfo['GradeNum'];
        if ($groupInfo['Degree'] == 'bachelor') {
            $out['GradeTitle'] = $gradeNum.' курс';
        } else if ($groupInfo['Degree'] == 'specialist') {
            $out['GradeTitle'] = $gradeNum.' курс';
        } if ($groupInfo['Degree'] == 'master') {
            $out['GradeTitle'] = 'Магистратура, '.$gradeNum.' год';
        }
        
        //Формирование заголовка группы
        $out['GroupTitle'] = $out['GradeTitle']." ".$groupInfo['GroupNum']." группа";
        return $out;
    }
    
    private function getRatesForRatingPage($info) {
PavelBegunkov's avatar
PavelBegunkov committed
        $rates = array();
        $i_r = 0;
        $rateResult = 0;

        foreach($info as $row) {
             ++$i_r;
            $cur_rate = array();
            $rateResult += $cur_rate['Rate'] = $row['Rate'];
            $moduleType = $row['ModuleType'];
            $cur_rate['Type'] = $moduleType;
            if ($moduleType == 'exam') {
                $cur_rate['SubmoduleID'] = -1;
            } else if ($moduleType == 'extra') {
                $cur_rate['SubmoduleID'] = -2;
            } else {
                $cur_rate['SubmoduleID'] = $row['SubmoduleID'];
PavelBegunkov's avatar
PavelBegunkov committed
            $rates[$i_r] = $cur_rate;
           
        }
        $rates['RateResult'] = $rateResult;
        return $rates;
    }
    
    private function correctExtra(&$curStudent, $examType, $lastExtraIndex, $firstEmptyExtraIndex, $totalExtraRate) {
PavelBegunkov's avatar
PavelBegunkov committed
        $bottomLimit = 0;
PavelBegunkov's avatar
PavelBegunkov committed
        $topLimit = ($examType == 'exam') ? 38 : 60;
        
        if ($curStudent['RateSemesterResult'] >= $bottomLimit && 
            $curStudent['RateSemesterResult'] < $topLimit) // студент задолженик
        {
            $maxExtraRate = $topLimit - $curStudent['RateSemesterResult'];
PavelBegunkov's avatar
PavelBegunkov committed
        }
        if ($lastExtraIndex >= 0) {
            $curStudent['Rates'][$lastExtraIndex]['MaxRate'] = $maxExtraRate - $totalExtraRate
                + $curStudent['Rates'][$lastExtraIndex]['Rate'];
PavelBegunkov's avatar
PavelBegunkov committed
        } 
        if ($firstEmptyExtraIndex >= 0) {
            $curStudent['Rates'][$firstEmptyExtraIndex]['MaxRate'] = $maxExtraRate - $totalExtraRate;
        }
    private function getRatesForExamPage(&$curStudent, $rate, $examType, $disciplineID) {
        $rowIndex = 0;
        $lastExam = $lastExtraIndex = $lastNilExam = $firstEmptyExtra = -1;
        $rateExtra = 0;
PavelBegunkov's avatar
PavelBegunkov committed
        $curStudent['RateSemesterResult'] = 0;
        foreach($rate as $curRate) {
            if (($curRate['ModuleType'] == 'exam') or ($curRate['ModuleType'] == 'extra')) {
                    $curStudent['Rates'][$rowIndex] = array();
                    $curStudent['Rates'][$rowIndex]['SubmoduleID'] = $curRate['SubmoduleID'];
                    $curStudent['Rates'][$rowIndex]['Rate'] = $curRate['Rate'];
                    $curStudent['Rates'][$rowIndex]['ModuleType'] = $curRate['ModuleType'];
                    $curStudent['Rates'][$rowIndex]['ExamPeriodOption'] = $curRate['ExamPeriodOption'];
            switch ($curRate['ModuleType'])
PavelBegunkov's avatar
PavelBegunkov committed
            {
            case 'regular':
                    $curStudent['RateSemesterResult'] += $curRate['Rate'];
PavelBegunkov's avatar
PavelBegunkov committed
                    break;
            case 'exam':
                    if (!is_null($curRate['Rate'])) {
PavelBegunkov's avatar
PavelBegunkov committed
                        if ($lastExam >= 0) {
                            $curStudent['Rates'][$lastExam]['Block'] = 'True';
                        }
                        $lastExam = $rowIndex;
PavelBegunkov's avatar
PavelBegunkov committed
                    } else {
                            if ($lastNilExam < 0) {
                                    $lastNilExam = $rowIndex;
PavelBegunkov's avatar
PavelBegunkov committed
                            } else {
                                    $curStudent['Rates'][$rowIndex]['Block'] = 'True';
PavelBegunkov's avatar
PavelBegunkov committed
                            }
                    }
                    break;
            case 'bonus':
                    $curStudent['Bonus'] = $curRate['Rate'];
PavelBegunkov's avatar
PavelBegunkov committed
                    break;
            case 'extra':
                if ($curRate['Rate']) {
                    if ($lastExtraIndex >= 0) {
                        $curStudent['Rates'][$lastExtraIndex]['Block'] = 'True';
PavelBegunkov's avatar
PavelBegunkov committed
                    }
                    $lastExtraIndex = $rowIndex;
                    $curStudent['Rate'] += $curRate['Rate'];
                    $rateExtra += $curRate['Rate'];
                } else {
                    if ($firstEmptyExtra < 0) {
                        $firstEmptyExtra = $rowIndex;
PavelBegunkov's avatar
PavelBegunkov committed
                    } else {
                        $curStudent['Rates'][$rowIndex]['Block'] = 'True';
PavelBegunkov's avatar
PavelBegunkov committed
                    }
PavelBegunkov's avatar
PavelBegunkov committed
            default:
                    throw HTTP_Exception::factory (500, "Некорректный тип модуля!");
PavelBegunkov's avatar
PavelBegunkov committed
        
PavelBegunkov's avatar
PavelBegunkov committed
//        $total = $this->model_rating->GetStudentRate($curStudent['ID'], $disciplineID);
//        $total = ($total[0])?$total[0]['Num']:0;
//        if ($total)
//            $total = 0;
PavelBegunkov's avatar
PavelBegunkov committed
        $curStudent['RateResult'] = $curStudent['RateSemesterResult'] + $rateExtra;
PavelBegunkov's avatar
PavelBegunkov committed
        if ($lastExam >= 0) {
            $curStudent['RateResult'] += $curStudent['Rates'][$lastExam]['Rate'];
        }
        $this->correctExtra($curStudent, $examType, $lastExtraIndex, $firstEmptyExtra, $rateExtra);
	protected function get_edit_rights_for_teacher($teacherID, $disciplineID) {
	    // $this->user['TeacherID']=id
		$sql = "SELECT `GetEditRightsForTeacher`('$teacherID', '$disciplineID') AS `Num`;";//"CALL `GetEditRightsForTeacher`('$teacherID', '$disciplineID'); ";
        $res = DB::query(Database::SELECT, $sql)->execute();
RomanSteinberg's avatar
RomanSteinberg committed
		//$row = mysql_fetch_array($res);
		return $res['Num'];
xamgore's avatar
xamgore committed

    /**
     * @param $page_type: rating, exam
     * @throws HTTP_Exception
     */
    protected function stub_action($page_type) {
xamgore's avatar
xamgore committed
        if ($page_type != 'exam' && $page_type != 'rating')
            throw new RuntimeException('invalid $page_type param');

        $id = $this->request->param('id');
pimka's avatar
pimka committed

xamgore's avatar
xamgore committed
        $discipline = Model_Discipline::load($id);
        $discipline['GroupID_Filter']    = $this->getGroupID_ForFilter($id);
		$discipline['LocalizedExamType'] = RusLang::tr($discipline->Type);
xamgore's avatar
xamgore committed
        
        // Студенты и их баллы
        $students = $this->model_rating->GetStudentsForRating($id);
pimka's avatar
pimka committed

        $rateHandled = array();
        $groupsHandled = array();
PavelBegunkov's avatar
PavelBegunkov committed
        $i_g = $i_s = $curGroup = 0;

        foreach($students as $row) {
PavelBegunkov's avatar
PavelBegunkov committed
            
            if ($curGroup !== $row['GroupID']) {
                $curGroup = $row['GroupID'];
                $i_g++;
PavelBegunkov's avatar
PavelBegunkov committed
                $i_s = 0;
PavelBegunkov's avatar
PavelBegunkov committed
                $rateHandled[$i_g] = $this->processGroupInfo($row);
                $groupsHandled[$curGroup] = $rateHandled[$i_g]['GroupTitle'];
PavelBegunkov's avatar
PavelBegunkov committed
            
            // Студенты
            $curStudent = $row; //ID, Name, isAttached
PavelBegunkov's avatar
PavelBegunkov committed
            $curStudent['RateResult'] = 0;
PavelBegunkov's avatar
PavelBegunkov committed
            
            // Баллы студента
PavelBegunkov's avatar
PavelBegunkov committed
            if ($page_type == "rating") {
xamgore's avatar
xamgore committed
                $rates_raw = Model_Rating::getRates($id, $row['ID']);
PavelBegunkov's avatar
PavelBegunkov committed
                $rates = $this->getRatesForRatingPage($rates_raw);
                $curStudent['RateResult'] = $rates['RateResult'];
                unset($rates['RateResult']);
                $curStudent['Rates'] = $rates;
                $rateHandled[$i_g]['Students'][$i_s] = $curStudent;
            } else {
xamgore's avatar
xamgore committed
                $rate = Model_Rating::getExamRates($id, $row['ID']);
xamgore's avatar
xamgore committed
                $this->getRatesForExamPage($curStudent, $rate, $discipline->Type, $id);
PavelBegunkov's avatar
PavelBegunkov committed
                $rateHandled[$i_g]['Students'][$i_s] = $curStudent;
PavelBegunkov's avatar
PavelBegunkov committed
            $i_s++;
PavelBegunkov's avatar
PavelBegunkov committed
        
xamgore's avatar
xamgore committed
		$editRights=$this->get_edit_rights_for_teacher($this->user['TeacherID'], $discipline->ID);


        // Шапка таблицы: структура УКД (модули и мероприятия)
        $this->twig->set([
            'groups'              => $groupsHandled,
            'rateTable'           => $rateHandled,
            'headerRate'          => $this->getStructure($id, $page_type),
            'editRights'          => (1 == $editRights),
xamgore's avatar
xamgore committed
            'Discipline'      => $discipline,
            'Discipline_JSON' => json_encode($discipline),
        ])->set_filename("teacher/" . $page_type);
PavelBegunkov's avatar
PavelBegunkov committed
    }

    
    
    // Страница оценивания в течение семестра
    public function action_edit() {
        $this->stub_action("rating");
    }

    // Страница оценивания в сессию
    public function action_exam() {
        $this->stub_action("exam");
Антон Шалимов's avatar
Антон Шалимов committed
    }