Issues (2037)

gradebook/lib/results_data_generator.class.php (2 issues)

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
/**
5
 * ResultsDataGenerator Class
6
 * Class to select, sort and transform object data into array data,
7
 * used for the teacher's evaluation results view.
8
 *
9
 * @author Bert Steppé
10
 */
11
class ResultsDataGenerator
12
{
13
    // Sorting types constants
14
    public const RDG_SORT_LASTNAME = 1;
15
    public const RDG_SORT_FIRSTNAME = 2;
16
    public const RDG_SORT_SCORE = 4;
17
    public const RDG_SORT_MASK = 8;
18
19
    public const RDG_SORT_ASC = 16;
20
    public const RDG_SORT_DESC = 32;
21
    private $evaluation;
22
    private $results;
23
    private $is_course_ind;
0 ignored issues
show
The private property $is_course_ind is not used, and could be removed.
Loading history...
24
    private $include_edit;
0 ignored issues
show
The private property $include_edit is not used, and could be removed.
Loading history...
25
26
    /**
27
     * Constructor.
28
     */
29
    public function __construct(
30
        $evaluation,
31
        $results = [],
32
        $include_edit = false
33
    ) {
34
        $this->evaluation = $evaluation;
35
        $this->results = isset($results) ? $results : [];
36
    }
37
38
    /**
39
     * Get total number of results (rows).
40
     */
41
    public function get_total_results_count()
42
    {
43
        return count($this->results);
44
    }
45
46
    /**
47
     * Get actual array data.
48
     *
49
     * @param int $count
50
     *
51
     * @return array 2-dimensional array - each array contains the elements:
52
     *               0 ['id']        : user id
53
     *               1 ['result_id'] : result id
54
     *               2 ['lastname']  : user lastname
55
     *               3 ['firstname'] : user firstname
56
     *               4 ['score']     : student's score
57
     *               5 ['display']   : custom score display (only if custom scoring enabled)
58
     */
59
    public function get_data(
60
        $sorting = 0,
61
        $start = 0,
62
        $count = null,
63
        $ignore_score_color = false,
64
        $pdf = false
65
    ) {
66
        // do some checks on count, redefine if invalid value
67
        $number_decimals = api_get_setting('gradebook_number_decimals');
68
        if (!isset($count)) {
69
            $count = count($this->results) - $start;
70
        }
71
        if ($count < 0) {
72
            $count = 0;
73
        }
74
75
        $model = ExerciseLib::getCourseScoreModel();
76
77
        $scoreDisplay = ScoreDisplay::instance();
78
        // generate actual data array
79
        $table = [];
80
        foreach ($this->results as $result) {
81
            $user = [];
82
            $info = api_get_user_info($result->get_user_id());
83
            $user['id'] = $result->get_user_id();
84
            if ($pdf) {
85
                $user['username'] = $info['username'];
86
            }
87
            $user['result_id'] = $result->get_id();
88
            $user['lastname'] = $info['lastname'];
89
            $user['firstname'] = $info['firstname'];
90
            if ($pdf) {
91
                $user['score'] = $result->get_score();
92
            } else {
93
                $user['score'] = $this->get_score_display(
94
                    $result->get_score(),
95
                    true,
96
                    $ignore_score_color
97
                );
98
            }
99
100
            $user['percentage_score'] = (int) $scoreDisplay->display_score(
101
                [$result->get_score(), $this->evaluation->get_max()],
102
                SCORE_PERCENT,
103
                SCORE_BOTH,
104
                true
105
            );
106
107
            if ($pdf && null == $number_decimals) {
108
                $user['scoreletter'] = $result->get_score();
109
            }
110
            if ($scoreDisplay->is_custom()) {
111
                $user['display'] = $this->get_score_display(
112
                    $result->get_score(),
113
                    false,
114
                    $ignore_score_color
115
                );
116
                if (!empty($model)) {
117
                    $user['display'] .= '&nbsp;'.
118
                        ExerciseLib::show_score(
119
                            $result->get_score(),
120
                            $this->evaluation->get_max()
121
                        )
122
                    ;
123
                }
124
            }
125
            $table[] = $user;
126
        }
127
128
        // sort array
129
        if ($sorting & self::RDG_SORT_LASTNAME) {
130
            usort($table, ['ResultsDataGenerator', 'sort_by_last_name']);
131
        } elseif ($sorting & self::RDG_SORT_FIRSTNAME) {
132
            usort($table, ['ResultsDataGenerator', 'sort_by_first_name']);
133
        } elseif ($sorting & self::RDG_SORT_SCORE) {
134
            usort($table, ['ResultsDataGenerator', 'sort_by_score']);
135
        } elseif ($sorting & self::RDG_SORT_MASK) {
136
            usort($table, ['ResultsDataGenerator', 'sort_by_mask']);
137
        }
138
        if ($sorting & self::RDG_SORT_DESC) {
139
            $table = array_reverse($table);
140
        }
141
        $return = array_slice($table, $start, $count);
142
143
        return $return;
144
    }
145
146
    // Sort functions - used internally
147
148
    /**
149
     * @param array $item1
150
     * @param array $item2
151
     *
152
     * @return int
153
     */
154
    public function sort_by_last_name($item1, $item2)
155
    {
156
        return api_strcmp($item1['lastname'], $item2['lastname']);
157
    }
158
159
    /**
160
     * @param array $item1
161
     * @param array $item2
162
     *
163
     * @return int
164
     */
165
    public function sort_by_first_name($item1, $item2)
166
    {
167
        return api_strcmp($item1['firstname'], $item2['firstname']);
168
    }
169
170
    /**
171
     * @param array $item1
172
     * @param array $item2
173
     *
174
     * @return int
175
     */
176
    public function sort_by_score($item1, $item2)
177
    {
178
        if ($item1['percentage_score'] == $item2['percentage_score']) {
179
            return 0;
180
        } else {
181
            return $item1['percentage_score'] < $item2['percentage_score'] ? -1 : 1;
182
        }
183
    }
184
185
    /**
186
     * @param array $item1
187
     * @param array $item2
188
     *
189
     * @return int
190
     */
191
    public function sort_by_mask($item1, $item2)
192
    {
193
        $score1 = (isset($item1['score']) ? [$item1['score'], $this->evaluation->get_max()] : null);
194
        $score2 = (isset($item2['score']) ? [$item2['score'], $this->evaluation->get_max()] : null);
195
196
        return ScoreDisplay::compare_scores_by_custom_display($score1, $score2);
197
    }
198
199
    /**
200
     * Re-formats the score to show percentage ("2/4 (50 %)") or letters ("A").
201
     *
202
     * @param float Current absolute score (max score is taken from $this->evaluation->get_max()
203
     * @param bool  Whether we want the real score (2/4 (50 %)) or the transformation (A, B, C, etc)
204
     * @param bool  Whether we want to ignore the score color
205
     * @param bool $realscore
206
     *
207
     * @return string The score as we want to show it
208
     */
209
    private function get_score_display(
210
        $score,
211
        $realscore,
212
        $ignore_score_color = false
213
    ) {
214
        if (null != $score) {
215
            $scoreDisplay = ScoreDisplay::instance();
216
            $type = SCORE_CUSTOM;
217
            if (true === $realscore) {
218
                $type = SCORE_DIV_PERCENT;
219
            }
220
221
            return $scoreDisplay->display_score(
222
                [$score, $this->evaluation->get_max()],
223
                $type,
224
                SCORE_BOTH,
225
                $ignore_score_color
226
            );
227
        }
228
229
        return '';
230
    }
231
}
232