Proyectos de Subversion Moodle

Rev

Rev 1 | Mostrar el archivo completo | | | Autoría | Ultima modificación | Ver Log |

Rev 1 Rev 1441
Línea 143... Línea 143...
143
                        $quizdetails['completionpass'] = $quizobj->get_cm()->completionpassgrade;
143
                        $quizdetails['completionpass'] = $quizobj->get_cm()->completionpassgrade;
144
                    }
144
                    }
Línea 145... Línea 145...
145
 
145
 
146
                    // Fields only for managers.
146
                    // Fields only for managers.
147
                    if (has_capability('moodle/course:manageactivities', $context)) {
147
                    if (has_capability('moodle/course:manageactivities', $context)) {
-
 
148
                        $additionalfields = [
-
 
149
                            'shuffleanswers',
-
 
150
                            'timecreated',
-
 
151
                            'timemodified',
-
 
152
                            'password',
-
 
153
                            'subnet',
-
 
154
                            'precreateattempts',
148
                        $additionalfields = ['shuffleanswers', 'timecreated', 'timemodified', 'password', 'subnet'];
155
                        ];
149
                        $viewablefields = array_merge($viewablefields, $additionalfields);
156
                        $viewablefields = array_merge($viewablefields, $additionalfields);
Línea 150... Línea 157...
150
                    }
157
                    }
151
 
158
 
Línea 265... Línea 272...
265
                                                                            offline in the mobile app', VALUE_OPTIONAL),
272
                                                                            offline in the mobile app', VALUE_OPTIONAL),
266
                            'autosaveperiod' => new external_value(PARAM_INT, 'Auto-save delay', VALUE_OPTIONAL),
273
                            'autosaveperiod' => new external_value(PARAM_INT, 'Auto-save delay', VALUE_OPTIONAL),
267
                            'hasfeedback' => new external_value(PARAM_INT, 'Whether the quiz has any non-blank feedback text',
274
                            'hasfeedback' => new external_value(PARAM_INT, 'Whether the quiz has any non-blank feedback text',
268
                                                                VALUE_OPTIONAL),
275
                                                                VALUE_OPTIONAL),
269
                            'hasquestions' => new external_value(PARAM_INT, 'Whether the quiz has questions', VALUE_OPTIONAL),
276
                            'hasquestions' => new external_value(PARAM_INT, 'Whether the quiz has questions', VALUE_OPTIONAL),
-
 
277
                            'precreateattempts' => new external_value(PARAM_INT, 'Whether attempt pre-creation is enabled',
-
 
278
                                VALUE_OPTIONAL),
270
                        ]
279
                        ]
271
                    ))
280
                    ))
272
                ),
281
                ),
273
                'warnings' => new external_warnings(),
282
                'warnings' => new external_warnings(),
274
            ]
283
            ]
Línea 352... Línea 361...
352
    /**
361
    /**
353
     * Describes the parameters for get_user_attempts.
362
     * Describes the parameters for get_user_attempts.
354
     *
363
     *
355
     * @return external_function_parameters
364
     * @return external_function_parameters
356
     * @since Moodle 3.1
365
     * @since Moodle 3.1
-
 
366
     * @deprecated Since Moodle 5.0 MDL-68806.
-
 
367
     * @todo Final deprecation in Moodle 6.0 (MDL-80956)
357
     */
368
     */
-
 
369
    #[\core\attribute\deprecated(
-
 
370
        'mod_quiz_external::get_user_quiz_attempts_parameters',
-
 
371
        since: '5.0',
-
 
372
        reason: 'The old API for fetching attempts doesn\'t return true states for NOT_STARTED and SUBMITTED attempts',
-
 
373
        mdl: 'MDL-68806'
-
 
374
    )]
358
    public static function get_user_attempts_parameters() {
375
    public static function get_user_attempts_parameters() {
359
        return new external_function_parameters (
376
        return new external_function_parameters (
360
            [
377
            [
361
                'quizid' => new external_value(PARAM_INT, 'quiz instance id'),
378
                'quizid' => new external_value(PARAM_INT, 'quiz instance id'),
362
                'userid' => new external_value(PARAM_INT, 'user id, empty for current user', VALUE_DEFAULT, 0),
379
                'userid' => new external_value(PARAM_INT, 'user id, empty for current user', VALUE_DEFAULT, 0),
Línea 368... Línea 385...
368
    }
385
    }
Línea 369... Línea 386...
369
 
386
 
370
    /**
387
    /**
371
     * Return a list of attempts for the given quiz and user.
388
     * Return a list of attempts for the given quiz and user.
-
 
389
     *
-
 
390
     * For backwards compatibility, SUBMITTED attempts will be treated as FINISHED with marks hidden, and NOT_STARTED will not
-
 
391
     * be returned. To return all real states, call get_user_quiz_attempts instead.
372
     *
392
     *
373
     * @param int $quizid quiz instance id
393
     * @param int $quizid quiz instance id
374
     * @param int $userid user id
394
     * @param int $userid user id
375
     * @param string $status quiz status: all, finished or unfinished
395
     * @param string $status quiz status: all, finished or unfinished
376
     * @param bool $includepreviews whether to include previews or not
396
     * @param bool $includepreviews whether to include previews or not
377
     * @return array of warnings and the list of attempts
397
     * @return array of warnings and the list of attempts
-
 
398
     * @since Moodle 3.1
-
 
399
     * @deprecated Since Moodle 5.0 MDL-68806.
378
     * @since Moodle 3.1
400
     * @todo Final deprecation in Moodle 6.0 (MDL-80956)
-
 
401
     */
-
 
402
    #[\core\attribute\deprecated(
-
 
403
        'mod_quiz_external::get_user_quiz_attempts',
-
 
404
        since: '5.0',
-
 
405
        reason: 'The old API for fetching attempts doesn\'t return true states for NOT_STARTED and SUBMITTED attempts',
-
 
406
        mdl: 'MDL-68806'
379
     */
407
    )]
380
    public static function get_user_attempts($quizid, $userid = 0, $status = 'finished', $includepreviews = false) {
408
    public static function get_user_attempts($quizid, $userid = 0, $status = 'finished', $includepreviews = false) {
-
 
409
        global $USER;
Línea 381... Línea 410...
381
        global $USER;
410
        \core\deprecation::emit_deprecation(__METHOD__);
Línea 382... Línea 411...
382
 
411
 
383
        $warnings = [];
412
        $warnings = [];
Línea 415... Línea 444...
415
        $quizobj = new quiz_settings($quiz, $cm, $course);
444
        $quizobj = new quiz_settings($quiz, $cm, $course);
416
        $gradeitemmarks = $quizobj->get_grade_calculator()->compute_grade_item_totals_for_attempts(
445
        $gradeitemmarks = $quizobj->get_grade_calculator()->compute_grade_item_totals_for_attempts(
417
                array_column($attempts, 'uniqueid'));
446
                array_column($attempts, 'uniqueid'));
418
        $attemptresponse = [];
447
        $attemptresponse = [];
419
        foreach ($attempts as $attempt) {
448
        foreach ($attempts as $attempt) {
-
 
449
            if ($attempt->state == quiz_attempt::NOT_STARTED) {
-
 
450
                continue; // For backwards compatibility, do not return Not Started attempts.
-
 
451
            }
420
            $reviewoptions = quiz_get_review_options($quiz, $attempt, $context);
452
            $reviewoptions = quiz_get_review_options($quiz, $attempt, $context);
-
 
453
            if (
-
 
454
                $attempt->state == quiz_attempt::SUBMITTED ||
-
 
455
                (
421
            if (!has_capability('mod/quiz:viewreports', $context) &&
456
                    !has_capability('mod/quiz:viewreports', $context) &&
-
 
457
                    (
422
                    ($reviewoptions->marks < question_display_options::MARK_AND_MAX || $attempt->state != quiz_attempt::FINISHED)) {
458
                        $reviewoptions->marks < question_display_options::MARK_AND_MAX ||
-
 
459
                        $attempt->state != quiz_attempt::FINISHED
-
 
460
                    )
-
 
461
                )
-
 
462
            ) {
423
                // Blank the mark if the teacher does not allow it.
463
                // Blank the mark if the teacher does not allow it.
424
                $attempt->sumgrades = null;
464
                $attempt->sumgrades = null;
425
            } else if (isset($gradeitemmarks[$attempt->uniqueid])) {
465
            } else if (isset($gradeitemmarks[$attempt->uniqueid])) {
426
                $attempt->gradeitemmarks = [];
466
                $attempt->gradeitemmarks = [];
427
                foreach ($gradeitemmarks[$attempt->uniqueid] as $gradeitem) {
467
                foreach ($gradeitemmarks[$attempt->uniqueid] as $gradeitem) {
Línea 430... Línea 470...
430
                        'grade' => $gradeitem->grade,
470
                        'grade' => $gradeitem->grade,
431
                        'maxgrade' => $gradeitem->maxgrade,
471
                        'maxgrade' => $gradeitem->maxgrade,
432
                    ];
472
                    ];
433
                }
473
                }
434
            }
474
            }
-
 
475
            if ($attempt->state == quiz_attempt::SUBMITTED) {
-
 
476
                $attempt->state = quiz_attempt::FINISHED; // For backwards-compatibility.
-
 
477
            }
435
            $attemptresponse[] = $attempt;
478
            $attemptresponse[] = $attempt;
436
        }
479
        }
437
        $result = [];
480
        $result = [];
438
        $result['attempts'] = $attemptresponse;
481
        $result['attempts'] = $attemptresponse;
439
        $result['warnings'] = $warnings;
482
        $result['warnings'] = $warnings;
Línea 487... Línea 530...
487
    /**
530
    /**
488
     * Describes the get_user_attempts return value.
531
     * Describes the get_user_attempts return value.
489
     *
532
     *
490
     * @return external_single_structure
533
     * @return external_single_structure
491
     * @since Moodle 3.1
534
     * @since Moodle 3.1
-
 
535
     * @deprecated Since Moodle 5.0 MDL-68806.
-
 
536
     * @todo Final deprecation in Moodle 6.0 (MDL-80956)
492
     */
537
     */
-
 
538
    #[\core\attribute\deprecated(
-
 
539
        'mod_quiz_external::get_user_quiz_attempts_returns',
-
 
540
        since: '5.0',
-
 
541
        reason: 'The old API for fetching attempts doesn\'t return true states for NOT_STARTED and SUBMITTED attempts',
-
 
542
        mdl: 'MDL-68806'
-
 
543
    )]
493
    public static function get_user_attempts_returns() {
544
    public static function get_user_attempts_returns() {
-
 
545
        $attemptstructure = self::attempt_structure();
-
 
546
        $attemptstructure->keys['state']->desc .= " For backwards compatibility, attempts in 'submitted' state will return " .
-
 
547
            "'finished' and attempts in 'notstarted' state will return 'inprogress'. To get attempts with all real states, call " .
-
 
548
            "get_user_quiz_attempts() instead.";
494
        return new external_single_structure(
549
        return new external_single_structure(
495
            [
550
            [
496
                'attempts' => new external_multiple_structure(self::attempt_structure()),
551
                'attempts' => new external_multiple_structure($attemptstructure),
497
                'warnings' => new external_warnings(),
552
                'warnings' => new external_warnings(),
498
            ]
553
            ]
499
        );
554
        );
500
    }
555
    }
Línea 501... Línea 556...
501
 
556
 
-
 
557
    /**
-
 
558
     * Mark get_user_attempts as deprecated.
-
 
559
     *
-
 
560
     * @return bool
-
 
561
     */
-
 
562
    public static function get_user_attempts_is_deprecated(): bool {
-
 
563
        return true;
-
 
564
    }
-
 
565
 
-
 
566
    /**
-
 
567
     * Describes the parameters for get_user_quiz_attempts.
-
 
568
     *
-
 
569
     * @return external_function_parameters
-
 
570
     * @since Moodle 4.5
-
 
571
     */
-
 
572
    public static function get_user_quiz_attempts_parameters(): external_function_parameters {
-
 
573
        return new external_function_parameters (
-
 
574
            [
-
 
575
                'quizid' => new external_value(PARAM_INT, 'quiz instance id'),
-
 
576
                'userid' => new external_value(PARAM_INT, 'user id, empty for current user', VALUE_DEFAULT, 0),
-
 
577
                'status' => new external_value(PARAM_ALPHA, 'quiz status: all, finished or unfinished', VALUE_DEFAULT, 'finished'),
-
 
578
                'includepreviews' => new external_value(PARAM_BOOL, 'whether to include previews or not', VALUE_DEFAULT, false),
-
 
579
            ],
-
 
580
        );
-
 
581
    }
-
 
582
 
-
 
583
    /**
-
 
584
     * Return a list of attempts for the given quiz and user.
-
 
585
     *
-
 
586
     * @param int $quizid quiz instance id
-
 
587
     * @param int $userid user id
-
 
588
     * @param string $status quiz status: all, finished or unfinished
-
 
589
     * @param bool $includepreviews whether to include previews or not
-
 
590
     * @return array of warnings and the list of attempts
-
 
591
     * @since Moodle 4.5
-
 
592
     */
-
 
593
    public static function get_user_quiz_attempts(
-
 
594
        int $quizid,
-
 
595
        int $userid = 0,
-
 
596
        string $status = 'finished',
-
 
597
        bool $includepreviews = false
-
 
598
    ): array {
-
 
599
        global $USER;
-
 
600
 
-
 
601
        $warnings = [];
-
 
602
 
-
 
603
        $params = [
-
 
604
            'quizid' => $quizid,
-
 
605
            'userid' => $userid,
-
 
606
            'status' => $status,
-
 
607
            'includepreviews' => $includepreviews,
-
 
608
        ];
-
 
609
        $params = self::validate_parameters(self::get_user_quiz_attempts_parameters(), $params);
-
 
610
 
-
 
611
        [$quiz, $course, $cm, $context] = self::validate_quiz($params['quizid']);
-
 
612
 
-
 
613
        if (!in_array($params['status'], ['all', 'finished', 'unfinished'])) {
-
 
614
            throw new invalid_parameter_exception('Invalid status value');
-
 
615
        }
-
 
616
 
-
 
617
        // Default value for userid.
-
 
618
        if (empty($params['userid'])) {
-
 
619
            $params['userid'] = $USER->id;
-
 
620
        }
-
 
621
 
-
 
622
        $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
-
 
623
        core_user::require_active_user($user);
-
 
624
 
-
 
625
        // Extra checks so only users with permissions can view other users attempts.
-
 
626
        if ($USER->id != $user->id) {
-
 
627
            require_capability('mod/quiz:viewreports', $context);
-
 
628
        }
-
 
629
 
-
 
630
        // Update quiz with override information.
-
 
631
        $quiz = quiz_update_effective_access($quiz, $params['userid']);
-
 
632
        $attempts = quiz_get_user_attempts($quiz->id, $user->id, $params['status'], $params['includepreviews']);
-
 
633
        $quizobj = new quiz_settings($quiz, $cm, $course);
-
 
634
        $gradeitemmarks = $quizobj->get_grade_calculator()->compute_grade_item_totals_for_attempts(
-
 
635
                array_column($attempts, 'uniqueid'));
-
 
636
        $attemptresponse = [];
-
 
637
        foreach ($attempts as $attempt) {
-
 
638
            $reviewoptions = quiz_get_review_options($quiz, $attempt, $context);
-
 
639
            if (!has_capability('mod/quiz:viewreports', $context) &&
-
 
640
                    ($reviewoptions->marks < question_display_options::MARK_AND_MAX || $attempt->state != quiz_attempt::FINISHED)) {
-
 
641
                // Blank the mark if the teacher does not allow it.
-
 
642
                $attempt->sumgrades = null;
-
 
643
            } else if (isset($gradeitemmarks[$attempt->uniqueid])) {
-
 
644
                $attempt->gradeitemmarks = [];
-
 
645
                foreach ($gradeitemmarks[$attempt->uniqueid] as $gradeitem) {
-
 
646
                    $attempt->gradeitemmarks[] = [
-
 
647
                            'name' => \core_external\util::format_string($gradeitem->name, $context),
-
 
648
                            'grade' => $gradeitem->grade,
-
 
649
                            'maxgrade' => $gradeitem->maxgrade,
-
 
650
                    ];
-
 
651
                }
-
 
652
            }
-
 
653
            $attemptresponse[] = $attempt;
-
 
654
        }
-
 
655
        $result = [];
-
 
656
        $result['attempts'] = $attemptresponse;
-
 
657
        $result['warnings'] = $warnings;
-
 
658
        return $result;
-
 
659
    }
-
 
660
 
-
 
661
    /**
-
 
662
     * Describes the get_user_attempts return value.
-
 
663
     *
-
 
664
     * @return external_single_structure
-
 
665
     * @since Moodle 4.5
-
 
666
     */
-
 
667
    public static function get_user_quiz_attempts_returns(): external_single_structure {
-
 
668
        return new external_single_structure(
-
 
669
            [
-
 
670
                'attempts' => new external_multiple_structure(self::attempt_structure()),
-
 
671
                'warnings' => new external_warnings(),
-
 
672
            ],
-
 
673
        );
-
 
674
    }
-
 
675
 
502
    /**
676
    /**
503
     * Describes the parameters for get_user_best_grade.
677
     * Describes the parameters for get_user_best_grade.
504
     *
678
     *
505
     * @return external_function_parameters
679
     * @return external_function_parameters
506
     * @since Moodle 3.1
680
     * @since Moodle 3.1
Línea 801... Línea 975...
801
 
975
 
802
                // Pre-flight check passed.
976
                // Pre-flight check passed.
803
                $accessmanager->notify_preflight_check_passed($currentattemptid);
977
                $accessmanager->notify_preflight_check_passed($currentattemptid);
Línea 804... Línea 978...
804
            }
978
            }
805
 
979
 
806
            if ($currentattemptid) {
980
            if ($currentattemptid && $lastattempt->state !== quiz_attempt::NOT_STARTED) {
807
                if ($lastattempt->state == quiz_attempt::OVERDUE) {
981
                if ($lastattempt->state == quiz_attempt::OVERDUE) {
808
                    throw new moodle_exception('stateoverdue', 'quiz', $quizobj->view_url());
982
                    throw new moodle_exception('stateoverdue', 'quiz', $quizobj->view_url());
809
                } else {
983
                } else {