Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
namespace core_grades;
18
 
19
use grade_grade;
20
use grade_item;
21
use moodle_exception;
22
 
23
/**
24
 * An object for storing and aggregating penalty information.
25
 *
26
 * @package   core_grades
27
 * @copyright 2025 Catalyst IT Australia Pty Ltd
28
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
29
 */
30
final class penalty_container {
31
    /** @var float $penalty The number of points to deduct from the grade */
32
    private float $penalty = 0.0;
33
 
34
    /**
35
     * Constructor for the class.
36
     *
37
     * @param grade_item $gradeitem The grade item object
38
     * @param grade_grade $gradegrade The grade object
39
     * @param int $submissiondate The date and time the submission was made
40
     * @param int $duedate The date and time the activity is due
41
     */
42
    public function __construct(
43
        /** @var grade_item $gradeitem The grade item object*/
44
        private readonly grade_item $gradeitem,
45
 
46
        /** @var grade_grade $gradegrade The grade object */
47
        private readonly grade_grade $gradegrade,
48
 
49
        /** @var int $submissiondate The date and time the submission was made */
50
        private readonly int $submissiondate,
51
 
52
        /** @var int $duedate The date and time the activity is due */
53
        private readonly int $duedate,
54
    ) {
55
    }
56
 
57
    /**
58
     * Get the user id.
59
     *
60
     * @return int The user id
61
     */
62
    public function get_userid(): int {
63
        return $this->gradegrade->userid;
64
    }
65
 
66
    /**
67
     * Get the submission date.
68
     *
69
     * @return int The date and time the submission was made
70
     */
71
    public function get_submission_date(): int {
72
        return $this->submissiondate;
73
    }
74
 
75
    /**
76
     * Get the due date.
77
     *
78
     * @return int The date and time the activity is due
79
     */
80
    public function get_due_date(): int {
81
        return $this->duedate;
82
    }
83
 
84
    /**
85
     * Get the grade item object.
86
     * This object should not be modified.
87
     *
88
     * @return grade_item The grade item object
89
     */
90
    public function get_grade_item(): grade_item {
91
        return $this->gradeitem;
92
    }
93
 
94
    /**
95
     * Get the grade object.
96
     * This object should not be modified.
97
     *
98
     * @return grade_grade The grade object
99
     */
100
    public function get_grade_grade(): grade_grade {
101
        return $this->gradegrade;
102
    }
103
 
104
    /**
105
     * Get the grade before penalties are applied.
106
     *
107
     * @return float The grade before penalties are applied
108
     */
109
    public function get_grade_before_penalties(): float {
110
        return $this->gradegrade->finalgrade;
111
    }
112
 
113
    /**
114
     * Get the penalised grade.
115
     *
116
     * The penalised grade is clamped between the minimum and maximum grade for the grade item.
117
     *
118
     * @return float The penalised grade
119
     */
120
    public function get_grade_after_penalties(): float {
121
        // Prevent grades from becoming out of bounds which would otherwise be a fairly common occurrence.
122
        return self::clamp(
123
            $this->get_grade_before_penalties() - $this->penalty,
124
            $this->get_min_grade(),
125
            $this->get_max_grade()
126
        );
127
    }
128
 
129
    /**
130
     * Get the current penalty value.
131
     *
132
     * @return float The number of points to deduct from the grade
133
     */
134
    public function get_penalty(): float {
135
        return $this->penalty;
136
    }
137
 
138
    /**
139
     * Get the minimum grade for the grade item.
140
     *
141
     * @return float The minimum grade for the grade item
142
     */
143
    public function get_min_grade(): int {
144
        return $this->gradeitem->grademin;
145
    }
146
 
147
    /**
148
     * Get the maximum grade for the grade item.
149
     *
150
     * @return float The maximum grade for the grade item
151
     */
152
    public function get_max_grade(): float {
153
        return $this->gradeitem->grademax;
154
    }
155
 
156
    /**
157
     * Aggregate the number of points to deduct from the grade.
158
     * Each penalty plugin is expected to call this method from their calculate_penalty() method.
159
     *
160
     * For example, if a grade item has a maximum grade of 200 and a penalty plugin wants to deduct 10% from the maximum grade,
161
     * the penalty plugin should call this method with a penalty value of 20.
162
     *
163
     * Percentages must not be passed to this method. Any percentage values must be converted to points before calling this method.
164
     * Penalty values cannot be negative or an exception will be thrown.
165
     * After all penalty plugins have been called, the core penalty system will apply the aggregated penalty to the grade,
166
     * clamping the grade between the minimum and maximum grade for the grade item.
167
     *
168
     * @param float $penalty The number of points to deduct from the grade
169
     * @throws moodle_exception Thrown if the penalty value is negative
170
     */
171
    public function aggregate_penalty(float $penalty): void {
172
        if ($penalty < 0.0) {
173
            throw new moodle_exception('errornegativepenalty', 'core_grades', '', $this->get_grade_grade()->id);
174
        }
175
 
176
        $this->penalty += $penalty;
177
    }
178
 
179
    /**
180
     * Clamp a value between a minimum and maximum value.
181
     *
182
     * @param float $value The value to clamp
183
     * @param float $min The minimum value
184
     * @param float $max The maximum value
185
     * @return float The clamped value
186
     */
187
    private static function clamp(float $value, float $min, float $max): float {
188
        return max($min, min($max, $value));
189
    }
190
}