Skip to content
Snippets Groups Projects
Select Git revision
  • 2c66f24b59c51e769253aa4e7f32a8d758c5c42d
  • master default protected
  • vips-1.9
  • vips-1.8
  • 1.9.2
  • 1.9.1
  • 1.9
  • 1.8.8
  • 1.8.7
  • 1.8.6
  • 1.8.5
  • 1.8.4
  • 1.8.3
  • 1.8.2
  • 1.8.1
  • 1.8
16 results

api.php

Blame
  • Forked from Uni Osnabrück / Plugins / Vips
    285 commits behind, 96 commits ahead of the upstream repository.
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    api.php 9.84 KiB
    <?php
    /*
     * api.php - Vips plugin for Stud.IP
     * Copyright (c) 2021  Elmar Ludwig
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License as
     * published by the Free Software Foundation; either version 2 of
     * the License, or (at your option) any later version.
     */
    
    class ApiController extends StudipController
    {
        public function assignments_action($course_id)
        {
            vips_require_status('tutor', $course_id);
    
            $assignments = VipsAssignment::findBySQL('course_id = ? ORDER BY start', [$course_id]);
    
            $data = [];
    
            foreach ($assignments as $assignment) {
                if ($assignment->type !== 'exam') {
                    $data[] = [
                        'id'     => $assignment->id,
                        'link'   => $this->url_for('api/assignment', $assignment->id),
                        'title'  => $assignment->test->title,
                        'type'   => $assignment->type,
                        'icon'   => $assignment->getTypeIcon()->getShape(),
                        'start'  => date('d.m.Y, H:i', strtotime($assignment->start)),
                        'end'    => date('d.m.Y, H:i', strtotime($assignment->end)),
                        'active' => $assignment->active,
                        'block'  => $assignment->block->name
                    ];
                }
            }
    
            $this->render_json($data);
        }
    
        public function assignment_action($assignment_id)
        {
            $assignment = VipsAssignment::find($assignment_id);
            $user_id = $GLOBALS['user']->id;
            $released = $assignment->releaseStatus($user_id);
    
            if (!$assignment || !vips_has_status('autor', $assignment->course_id)) {
                throw new AccessDeniedException(_vips('Sie haben keinen Zugriff auf dieses Aufgabenblatt!'));
            }
    
            if ($assignment->type === 'exam') {
                throw new AccessDeniedException(_vips('Sie haben keinen Zugriff auf dieses Aufgabenblatt!'));
            }
    
            if (!$assignment->checkAccess() && $released < 3) {
                throw new AccessDeniedException(_vips('Das Aufgabenblatt kann zur Zeit nicht bearbeitet werden.'));
            }
    
            // enter user start time the moment he/she first clicks on any exercise
            if (!vips_has_status('tutor', $assignment->course_id)) {
                $assignment->recordAssignmentAttempt($user_id);
            }
    
            $data = [
                'id'             => $assignment->id,
                'title'          => $assignment->test->title,
                'type'           => $assignment->type,
                'icon'           => $assignment->getTypeIcon()->getShape(),
                'start'          => date('d.m.Y, H:i', strtotime($assignment->start)),
                'end'            => date('d.m.Y, H:i', strtotime($assignment->end)),
                'active'         => $assignment->active,
                'block'          => $assignment->block->name,
                'reset_allowed'  => $assignment->isRunning() && $assignment->isResetAllowed(),
                'points'         => $assignment->test->getTotalPoints(),
                'release_status' => $released,
                'exercises'      => []
            ];
    
            foreach ($assignment->getExerciseRefs($user_id) as $exercise_ref) {
                $template = $this->courseware_template($assignment, $exercise_ref, $released);
                $exercise = $exercise_ref->exercise;
    
                $data['exercises'][] = [
                    'id'            => $exercise->id,
                    'link'          => $this->url_for('api/exercise', $assignment_id, $exercise->id),
                    'type'          => $exercise->type,
                    'title'         => $exercise->title,
                    'template'      => $template->render(),
                    'item_count'    => $exercise->itemCount(),
                    'show_solution' => $template->show_solution
                ];
            }
    
            $this->render_json($data);
        }
    
        public function exercise_action($assignment_id, $exercise_id)
        {
            $assignment = VipsAssignment::find($assignment_id);
            $user_id = $GLOBALS['user']->id;
            $released = $assignment->releaseStatus($user_id);
    
            check_exercise_assignment($exercise_id, $assignment);
    
            if (!$assignment || !vips_has_status('autor', $assignment->course_id)) {
                throw new AccessDeniedException(_vips('Sie haben keinen Zugriff auf dieses Aufgabenblatt!'));
            }
    
            if ($assignment->type === 'exam') {
                throw new AccessDeniedException(_vips('Sie haben keinen Zugriff auf dieses Aufgabenblatt!'));
            }
    
            if (!$assignment->checkAccess() && $released < 3) {
                throw new AccessDeniedException(_vips('Das Aufgabenblatt kann zur Zeit nicht bearbeitet werden.'));
            }
    
            // enter user start time the moment he/she first clicks on any exercise
            if (!vips_has_status('tutor', $assignment->course_id)) {
                $assignment->recordAssignmentAttempt($user_id);
            }
    
            $exercise_ref = VipsExerciseRef::find([$exercise_id, $assignment->test_id]);
            $template = $this->courseware_template($assignment, $exercise_ref, $released);
            $exercise = $exercise_ref->exercise;
    
            $data = [
                'id'            => $exercise->id,
                'type'          => $exercise->type,
                'title'         => $exercise->title,
                'template'      => $template->render(),
                'item_count'    => $exercise->itemCount(),
                'show_solution' => $template->show_solution
            ];
    
            $this->render_json($data);
        }
    
        private function courseware_template($assignment, $exercise_ref, $released)
        {
            $user_id = $GLOBALS['user']->id;
            $exercise = $exercise_ref->exercise;
            $solution = $assignment->getSolution($user_id, $exercise->id);
            $max_points = $exercise_ref->points;
            $reached_points = $solution->points;
            $show_solution = false;
    
            if ($assignment->isRunning()) {
                // if a solution has been submitted during a selftest
                if ($assignment->type === 'selftest' && $solution) {
                    $max_tries = $assignment->options['max_tries'] ?: 3;
                    $tries_left = $max_tries - $solution->countTries();
    
                    if ($reached_points == $max_points || !$solution->corrected || $solution->corrector_id || $tries_left <= 0) {
                        $show_solution = true;
                    }
                }
            } else {
                $show_solution = true;
    
                if (!$solution) {
                    $solution = new VipsSolution();
                    $solution->assignment = $assignment;
                }
            }
    
            if ($show_solution) {
                $exercise_template = $exercise->getCorrectionTemplate($solution);
                $exercise_template->show_solution = $released == 4;
            } else {
                $exercise_template = $exercise->getSolveTemplate($solution, $assignment, $user_id);
            }
    
            $template = $this->get_template_factory()->open('exercises/courseware_block');
            $template->exercise = $exercise;
            $template->exercise_template = $exercise_template;
            $template->tries_left = $tries_left;
            $template->solution = $solution;
            $template->max_points = $max_points;
            $template->reached_points = $reached_points;
            $template->show_solution = $show_solution;
    
            return $template;
        }
    
        public function solution_action($assignment_id, $exercise_id)
        {
            CSRFProtection::verifyUnsafeRequest();
    
            $assignment = VipsAssignment::find($assignment_id);
            $block_id = Request::int('block_id');
            $user_id = $GLOBALS['user']->id;
    
            check_exercise_assignment($exercise_id, $assignment);
    
            // check access to courseware block
            if ($block_id) {
                $block = Courseware\Block::find($block_id);
                $payload = $block->type->getPayload();
    
                if ($payload['assignment'] != $assignment_id) {
                    throw new AccessDeniedException(_vips('Sie haben keinen Zugriff auf diesen Block!'));
                }
            }
    
            if (!$assignment || !vips_has_status('autor', $assignment->course_id)) {
                throw new AccessDeniedException(_vips('Sie haben keinen Zugriff auf dieses Aufgabenblatt!'));
            }
    
            if ($assignment->type === 'exam') {
                throw new AccessDeniedException(_vips('Sie haben keinen Zugriff auf dieses Aufgabenblatt!'));
            }
    
            if (!$assignment->checkAccess()) {
                throw new AccessDeniedException(_vips('Das Aufgabenblatt kann zur Zeit nicht bearbeitet werden.'));
            }
    
            // enter user start time the moment he/she first clicks on any exercise
            if (!vips_has_status('tutor', $assignment->course_id)) {
                $assignment->recordAssignmentAttempt($user_id);
            }
    
            if (Request::isPost()) {
                $request  = Request::getInstance();
                $exercise = Exercise::find($exercise_id);
                $solution = $exercise->getSolutionFromRequest($request, $_FILES);
                $solution->user_id = $user_id;
                $exercise->submitSolutionAction($this, $solution);
    
                if ($solution->isEmpty()) {
                    $this->set_status(422);
                } else {
                    $assignment->storeSolution($solution);
                    $this->set_status(201);
                }
            }
    
            if (Request::isDelete()) {
                if ($assignment->isResetAllowed()) {
                    $assignment->deleteSolution($user_id, $exercise_id);
                    $this->set_status(204);
                } else {
                    $this->set_status(403);
                }
            }
    
            // update user progress in Courseware
            if ($assignment->type === 'selftest' && $block_id) {
                $max_points = $assignment->test->getTotalPoints() ?: 1;
                $progress = new Courseware\UserProgress([$user_id, $block_id]);
                $progress->grade = $assignment->getUserPoints($user_id) / $max_points;
                $progress->store();
            }
    
            $this->render_nothing();
        }
    }