コード例 #1
0
ファイル: solution.php プロジェクト: andrejjursa/list-lms
 /**
  * Delete this object from database or specified relations.
  * If this object is deleted, all student files will be deleted as well.
  * @param DataMapper|string $object related object to delete from relation.
  * @param string $related_field relation internal name.
  */
 public function delete($object = '', $related_field = '')
 {
     $this_id = $this->id;
     $this_task_set_id = $this->task_set_id;
     $this_student_id = $this->student_id;
     parent::delete($object, $related_field);
     if (empty($object) && !is_array($object) && !empty($this_id)) {
         $task_set = new Task_set();
         $task_set->get_by_id($this_task_set_id);
         if ($task_set->exists()) {
             $student_files = $task_set->get_student_files($this_student_id);
             if (count($student_files) > 0) {
                 foreach ($student_files as $file) {
                     @unlink($file['filepath']);
                 }
             }
         }
     }
 }
コード例 #2
0
ファイル: tests.php プロジェクト: andrejjursa/list-lms
 public function run_test_for_task($test_id, $task_set_id, $student_id, $version, $token = '')
 {
     $task_set = new Task_set();
     $task_set->include_related('course', 'test_scoring_deadline');
     $task_set->get_by_id(intval($task_set_id));
     $student = new Student();
     $student->get_by_id(intval($student_id));
     $output = new stdClass();
     $output->text = $this->lang->line('admin_tests_error_message_failed_to_run_student_test');
     $output->code = 1;
     if ($task_set->exists() && $student->exists()) {
         $files = $task_set->get_student_files($student->id, (int) $version);
         if (isset($files[(int) $version]['filepath'])) {
             $run_evaluation = $task_set->enable_tests_scoring > 0 && $task_set->course_test_scoring_deadline >= date('Y-m-d H:i:s') ? TRUE : FALSE;
             $this->run_single_test($test_id, encode_for_url($files[(int) $version]['filepath']), $run_evaluation, $token, $student->id);
         } else {
             $this->output->set_content_type('application/json');
             $this->output->set_output(json_encode($output));
         }
     } else {
         $this->output->set_content_type('application/json');
         $this->output->set_output(json_encode($output));
     }
 }
コード例 #3
0
ファイル: cli_test.php プロジェクト: andrejjursa/list-lms
 public function index($worker_id = 0)
 {
     $test_queue = new Test_queue();
     $execute_tests = FALSE;
     try {
         $this->db->query('SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;');
         $this->db->trans_begin();
         $test_queue->where('worker', NULL);
         $test_queue->where('status', 0);
         $test_queue->where('version >', 0);
         $test_queue->group_start(' NOT ');
         $test_queue->where('task_set_id', NULL);
         $test_queue->group_end();
         $test_queue->group_start(' NOT ');
         $test_queue->where('student_id', NULL);
         $test_queue->group_end();
         $test_queue->order_by('priority', 'asc');
         $test_queue->order_by('start', 'asc');
         $test_queue->limit(1);
         $sql_query = $test_queue->get_sql();
         $sql_query = rtrim($sql_query, '; ' . "\n\r") . ' FOR UPDATE;';
         $test_queue->query($sql_query);
         if ($test_queue->exists()) {
             $test_queue->worker = (int) $worker_id;
             $test_queue->status = 1;
             $test_queue->exec_start = date('Y-m-d H:i:s');
             $test_queue->where('worker', NULL);
             $test_queue->where('status', 0);
             if ($test_queue->save()) {
                 $this->db->trans_commit();
                 $execute_tests = TRUE;
             } else {
                 $this->db->trans_rollback();
             }
         } else {
             $this->db->trans_rollback();
         }
     } catch (Exception $e) {
     }
     if ($test_queue->exists() && $execute_tests) {
         //$this->db->query('SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;');
         //$this->db->trans_begin();
         $this->lang->reinitialize_for_idiom($test_queue->system_language);
         $this->lang->load('admin/tests');
         $task_set = new Task_set();
         $task_set->include_related('course', 'test_scoring_deadline');
         $task_set->get_by_id($test_queue->task_set_id);
         $student = new Student();
         $student->get_by_id($test_queue->student_id);
         $tests = new Test();
         $tests->where_related($test_queue);
         $tests->get_iterated();
         try {
             if ($task_set->exists() && $student->exists() && $tests->exists()) {
                 $version = $test_queue->version;
                 $run_evaluation = $task_set->enable_tests_scoring > 0 && $task_set->course_test_scoring_deadline >= date('Y-m-d H:i:s') ? TRUE : FALSE;
                 $score_percent = array();
                 $score_points = array();
                 $bonus_percent = array();
                 $bonus_points = array();
                 $total_tests_count = $tests->result_count();
                 foreach ($tests as $test) {
                     $test_queue->single_test_exec_start = date('Y-m-d H:i:s');
                     $test_queue->save();
                     $files = $task_set->get_student_files($student->id, (int) $version);
                     if (isset($files[(int) $version]['filepath']) && file_exists($files[(int) $version]['filepath'])) {
                         $test_object = $this->load->test($test->type);
                         $test_object->initialize($test);
                         $token = '';
                         //echo 'Test queue ' . $test_queue->id . ' is running test ' . $test->id . ' ... ' . PHP_EOL;
                         try {
                             $test_output = $test_object->run($files[(int) $version]['filepath'], $run_evaluation && $test->enable_scoring > 0, $student->id, $token);
                             $test_score = $test_object->get_last_test_score();
                         } catch (Exception $e) {
                             $test_output = $e->getMessage();
                             $test_score = 0;
                         }
                         $test_queue->set_join_field($test, 'result_text', $test_output);
                         $test_queue->set_join_field($test, 'evaluation_table', $test_object->get_last_test_scoring());
                         $test_queue->set_join_field($test, 'result', $test_object->get_last_exit_code());
                         //echo 'Test queue ' . $test_queue->id . ' is done with test ' . $test->id . ' ... ' . PHP_EOL;
                         if ($run_evaluation && $test->enable_scoring > 0) {
                             $this->db->select('*');
                             $task_id = $test->task_id;
                             $this->db->where('task_set_id', $task_set->id);
                             $this->db->where('task_id', (int) $task_id);
                             $query = $this->db->get('task_task_set_rel');
                             if ($query->num_rows() > 0) {
                                 $task_rel = $query->row_object();
                                 $min = (double) $task_rel->test_min_points;
                                 $max = (double) $task_rel->test_max_points;
                                 $percent = (double) $test_score / 100.0;
                                 $points = (1.0 - $percent) * $min + $percent * $max;
                                 if ($task_rel->bonus_task == 0) {
                                     $test_queue->set_join_field($test, 'percent_points', $test_score);
                                     $test_queue->set_join_field($test, 'points', $points);
                                     $score_percent[$task_id] = isset($score_percent[$task_id]) ? $score_percent[$task_id] + $percent : $percent;
                                     $percent = (double) $score_percent[$task_id];
                                     $points = (1.0 - $percent) * $min + $percent * $max;
                                     $score_points[$task_id] = $points;
                                 } else {
                                     $test_queue->set_join_field($test, 'percent_bonus', $test_score);
                                     $test_queue->set_join_field($test, 'bonus', $points);
                                     $bonus_percent[$task_id] = isset($bonus_percent[$task_id]) ? $bonus_percent[$task_id] + $percent : $percent;
                                     $percent = (double) $bonus_percent[$task_id];
                                     $points = (1.0 - $percent) * $min + $percent * $max;
                                     $bonus_points[$task_id] = $points;
                                 }
                             }
                             $query->free_result();
                         }
                     } else {
                         //$this->db->trans_rollback();
                         $test_queue->worker = NULL;
                         $test_queue->status = 3;
                         $test_queue->finish = date('Y-m-d H:i:s');
                         $test_queue->save();
                         die;
                     }
                 }
                 $tests = new Test();
                 $tests->where_related('task/task_set', 'id', $task_set->id);
                 $tests->where('type', $test_queue->test_type);
                 $tests->where('enable_scoring >', 0);
                 $tests->group_by('task_id');
                 $tests->where('task_task_task_set_rel.bonus_task', 0);
                 $tests->get_iterated();
                 $test_count = $tests->result_count();
                 $min_results = $task_set->test_min_needed > $test_count ? $test_count : $task_set->test_min_needed;
                 $course = new Course();
                 $course->where_related_task_set('id', $task_set->id);
                 $course->get();
                 $min_points_limit = -$course->default_points_to_remove;
                 if ($test_count > 0 && $run_evaluation) {
                     $max_results = $task_set->test_max_allowed < count($score_points) ? $task_set->test_max_allowed : count($score_points);
                     arsort($score_points, SORT_NUMERIC);
                     $i = 0;
                     $total_score = 0;
                     foreach ($score_points as $task_id => $points) {
                         if ($i < $max_results) {
                             $total_score += $points;
                             $i++;
                         } else {
                             break;
                         }
                     }
                     $total_score = $total_score < $min_points_limit ? $min_points_limit : $total_score;
                     $total_bonus = array_sum($bonus_points);
                     $total_score += $total_bonus;
                     if (count($score_points) >= $min_results) {
                         $solution = new Solution();
                         $solution->where('task_set_id', $task_set->id);
                         $solution->where('student_id', $student->id);
                         $solution->get();
                         $save_solution = FALSE;
                         $solution_not_considered = FALSE;
                         $solution_disable_evaluation = FALSE;
                         $best_old_score = $min_points_limit;
                         if ($solution->exists()) {
                             if ($solution->not_considered == 0) {
                                 if ($solution->disable_evaluation_by_tests == 0) {
                                     if ($solution->tests_points < $total_score || is_null($solution->tests_points)) {
                                         $solution->tests_points = $total_score;
                                         $solution->teacher_id = NULL;
                                         $solution->best_version = (int) $version;
                                         $solution->revalidate = 0;
                                         $save_solution = TRUE;
                                     } else {
                                         $best_old_score = $solution->tests_points;
                                     }
                                 } else {
                                     $solution_disable_evaluation = TRUE;
                                 }
                             } else {
                                 $solution_not_considered = TRUE;
                             }
                         } else {
                             $solution->tests_points = $total_score;
                             $solution->comment = '';
                             $solution->teacher_id = NULL;
                             $solution->best_version = (int) $version;
                             $solution->task_set_id = $task_set->id;
                             $solution->student_id = $student->id;
                             $solution->revalidate = 0;
                             $save_solution = TRUE;
                         }
                         if ($save_solution) {
                             $solution->save();
                             $this->parser->clearCache('frontend/tasks/index.tpl');
                             $test_queue->result_message = $this->lang->line('admin_tests_test_result_new_points_added');
                         } else {
                             if (!$solution_disable_evaluation) {
                                 if (!$solution_not_considered) {
                                     $test_queue->result_message = sprintf($this->lang->line('admin_tests_test_result_nothing_to_update'), $total_score, $best_old_score);
                                 } else {
                                     $test_queue->result_message = $this->lang->line('admin_tests_test_result_solution_not_considered');
                                 }
                             } else {
                                 $test_queue->result_message = $this->lang->line('admin_tests_test_result_solution_disable_evaluation');
                             }
                         }
                         $test_queue->points = $total_score - $total_bonus;
                         $test_queue->bonus = $total_bonus;
                     } else {
                         $test_queue->result_message = sprintf($this->lang->line('admin_tests_test_result_minimum_number_of_test_not_selected'), $min_results);
                     }
                     $result_table_tasks = new Task();
                     $result_table_tasks->where_related_task_set('id', $task_set->id);
                     $result_table_tasks->order_by('`task_task_set_rel`.`sorting`', 'asc');
                     $result_table_tasks->get_iterated();
                     $test_queue->result_html = $this->parser->parse('backend/tests/evaluation_table.tpl', array('tasks' => $result_table_tasks, 'real_points' => $score_points, 'bonus_points' => $bonus_points, 'real_percentage' => $score_percent, 'bonus_percentage' => $bonus_percent, 'max_results' => $max_results), TRUE);
                     $test_queue->worker = NULL;
                     $test_queue->status = 2;
                     $test_queue->finish = date('Y-m-d H:i:s');
                     $test_queue->save();
                     //$this->db->trans_commit();
                 } else {
                     if ($total_tests_count && !$run_evaluation) {
                         $test_queue->worker = NULL;
                         $test_queue->status = 2;
                         $test_queue->finish = date('Y-m-d H:i:s');
                         $test_queue->result_message = $this->lang->line('admin_tests_test_result_testing_finished');
                         $test_queue->save();
                         //$this->db->trans_commit();
                     } else {
                         //$this->db->trans_rollback();
                         $test_queue->worker = NULL;
                         $test_queue->status = 3;
                         $test_queue->finish = date('Y-m-d H:i:s');
                         $test_queue->result_message = $this->lang->line('admin_tests_test_result_no_test_selected');
                         $test_queue->save();
                     }
                 }
             } else {
                 //$this->db->trans_rollback();
                 $test_queue->worker = NULL;
                 $test_queue->status = 3;
                 $test_queue->finish = date('Y-m-d H:i:s');
                 $test_queue->result_message = $this->lang->line('admin_tests_test_result_configuration_error');
                 $test_queue->save();
             }
         } catch (Exception $e) {
             //$this->db->trans_rollback();
             $test_queue->worker = NULL;
             $test_queue->status = 3;
             $test_queue->finish = date('Y-m-d H:i:s');
             $test_queue->result_message = $this->lang->line('admin_tests_test_result_execution_error');
             $test_queue->result_html = '<pre>' . $e->getMessage() . '</pre>';
             $test_queue->save();
         }
     }
     //@unlink($test_locks_path . 'worker_' . (int)$worker_id . '_lock.txt');
 }