Merge branch 'MDL-48006-master' of git://github.com/damyon/moodle
[moodle.git] / grade / report / singleview / classes / local / screen / screen.php
CommitLineData
57fac09a
DW
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/**
18 * Abstract class used as a base for the 3 screens.
19 *
20 * @package gradereport_singleview
21 * @copyright 2014 Moodle Pty Ltd (http://moodle.com)
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 */
24
25namespace gradereport_singleview\local\screen;
26
27use context_course;
28use moodle_url;
29use html_writer;
30use grade_structure;
31use grade_grade;
32use grade_item;
33use stdClass;
34
35defined('MOODLE_INTERNAL') || die;
36
37/**
38 * Abstract class used as a base for the 3 screens.
39 *
40 * @package gradereport_singleview
41 * @copyright 2014 Moodle Pty Ltd (http://moodle.com)
42 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
43 */
44abstract class screen {
45
46 /** @var int $courseid The id of the course */
47 protected $courseid;
48
49 /** @var int $itemid Either a user id or a grade_item id */
50 protected $itemid;
51
52 /** @var int $groupid The currently set groupid (if set) */
53 protected $groupid;
54
55 /** @var course_context $context The course context */
56 protected $context;
57
58 /** @var int $page The page number */
59 protected $page;
60
61 /** @var int $perpage Results per page */
62 protected $perpage;
63
64 /** @var array $items List of items on the page, they could be users or grade_items */
65 protected $items;
66
67 /**
68 * Constructor
69 *
70 * @param int $courseid The course id
71 * @param int $itemid The item id
72 * @param int $groupid The group id
73 */
74 public function __construct($courseid, $itemid, $groupid = null) {
75 global $DB;
76
77 $this->courseid = $courseid;
78 $this->itemid = $itemid;
79 $this->groupid = $groupid;
80
81 $this->context = context_course::instance($this->courseid);
82 $this->course = $DB->get_record('course', array('id' => $courseid));
83
84 $this->page = optional_param('page', 0, PARAM_INT);
85 $this->perpage = optional_param('perpage', 100, PARAM_INT);
86 if ($this->perpage > 100) {
87 $this->perpage = 100;
88 }
89
90 $this->init(empty($itemid));
91 }
92
93 /**
94 * Cache the grade_structure class
95 */
96 public function setup_structure() {
97 $this->structure = new grade_structure();
98 $this->structure->modinfo = get_fast_modinfo($this->course);
99 }
100
101 /**
102 * Create a nice link from a thing (user or grade_item).
103 *
104 * @param string $screen
105 * @param int $itemid
106 * @param bool $display Should we wrap this in an anchor ?
107 * @return string The link
108 */
109 public function format_link($screen, $itemid, $display = null) {
110 $url = new moodle_url('/grade/report/singleview/index.php', array(
111 'id' => $this->courseid,
112 'item' => $screen,
113 'itemid' => $itemid,
114 'group' => $this->groupid,
115 ));
116
117 if ($display) {
118 return html_writer::link($url, $display);
119 } else {
120 return $url;
121 }
122 }
123
124 /**
125 * Get the grade_grade
126 *
127 * @param grade_item $item The grade_item
128 * @param int $userid The user id
129 * @return grade_grade
130 */
131 public function fetch_grade_or_default($item, $userid) {
132 $grade = grade_grade::fetch(array(
133 'itemid' => $item->id, 'userid' => $userid
134 ));
135
136 if (!$grade) {
137 $default = new stdClass;
138
139 $default->userid = $userid;
140 $default->itemid = $item->id;
141 $default->feedback = '';
142
143 $grade = new grade_grade($default, false);
144 }
145
146 $grade->grade_item = $item;
147
148 return $grade;
149 }
150
151 /**
152 * Make the HTML element that toggles all the checkboxes on or off.
153 *
154 * @param string $key A unique key for this control - inserted in the classes.
155 * @return string
156 */
157 public function make_toggle($key) {
158 $attrs = array('href' => '#');
159
160 $all = html_writer::tag('a', get_string('all'), $attrs + array(
161 'class' => 'include all ' . $key
162 ));
163
164 $none = html_writer::tag('a', get_string('none'), $attrs + array(
165 'class' => 'include none ' . $key
166 ));
167
168 return html_writer::tag('span', "$all / $none", array(
169 'class' => 'inclusion_links'
170 ));
171 }
172
173 /**
174 * Make a toggle link with some text before it.
175 *
176 * @param string $key A unique key for this control - inserted in the classes.
177 * @return string
178 */
179 public function make_toggle_links($key) {
180 return get_string($key, 'gradereport_singleview') . ' ' .
181 $this->make_toggle($key);
182 }
183
184 /**
185 * Get the default heading for the screen.
186 *
187 * @return string
188 */
189 public function heading() {
190 return get_string('pluginname', 'gradereport_singleview');
191 }
192
193 /**
194 * Override this to init the screen.
195 *
196 * @param boolean $selfitemisempty True if no item has been selected yet.
197 */
198 public abstract function init($selfitemisempty = false);
199
200 /**
201 * Get the type of items in the list.
202 *
203 * @return string
204 */
205 public abstract function item_type();
206
207 /**
208 * Get the entire screen as a string.
209 *
210 * @return string
211 */
212 public abstract function html();
213
214 /**
215 * Does this screen support paging?
216 *
217 * @return bool
218 */
219 public function supports_paging() {
220 return true;
221 }
222
223 /**
224 * Default pager
225 *
226 * @return string
227 */
228 public function pager() {
229 return '';
230 }
231
232 /**
233 * Initialise the js for this screen.
234 */
235 public function js() {
236 global $PAGE;
237
238 $module = array(
239 'name' => 'gradereport_singleview',
240 'fullpath' => '/grade/report/singleview/js/singleview.js',
241 'requires' => array('base', 'dom', 'event', 'event-simulate', 'io-base')
242 );
243
244 $PAGE->requires->js_init_call('M.gradereport_singleview.init', array(), false, $module);
245 }
246
247 /**
248 * Process the data from a form submission.
249 *
250 * @param array $data
251 * @return array of warnings
252 */
253 public function process($data) {
254 $warnings = array();
255
256 $fields = $this->definition();
257
258 foreach ($data as $varname => $throw) {
259 if (preg_match("/(\w+)_(\d+)_(\d+)/", $varname, $matches)) {
260 $itemid = $matches[2];
261 $userid = $matches[3];
262 } else {
263 continue;
264 }
265
57fac09a
DW
266 $gradeitem = grade_item::fetch(array(
267 'id' => $itemid, 'courseid' => $this->courseid
268 ));
269
1b2c1ccb
ZD
270 if (preg_match('/^old[oe]{1}/', $varname)) {
271 $elementname = preg_replace('/^old/', '', $varname);
272 if (!isset($data->$elementname)) {
273 $data->$elementname = false;
274 }
275 }
276
277 if (!in_array($matches[1], $fields)) {
278 continue;
279 }
280
57fac09a
DW
281 if (!$gradeitem) {
282 continue;
283 }
284
285 $grade = $this->fetch_grade_or_default($gradeitem, $userid);
286
287 $classname = '\\gradereport_singleview\\local\\ui\\' . $matches[1];
288 $element = new $classname($grade);
289
290 $name = $element->get_name();
291 $oldname = "old$name";
292
293 $posted = $data->$name;
294
295 $format = $element->determine_format();
296
297 if ($format->is_textbox() and trim($data->$name) === '') {
298 $data->$name = null;
299 }
300
301 // Same value; skip.
302 if (isset($data->$oldname) && $data->$oldname == $posted) {
303 continue;
304 }
305
306 $msg = $element->set($posted);
307
308 // Optional type.
309 if (!empty($msg)) {
310 $warnings[] = $msg;
311 }
312 }
313
314 // Some post-processing.
315 $eventdata = new stdClass;
316 $eventdata->warnings = $warnings;
317 $eventdata->post_data = $data;
318 $eventdata->instance = $this;
319
320 return $eventdata->warnings;
321 }
322
323 /**
324 * By default there are no options.
325 * @return array
326 */
327 public function options() {
328 return array();
329 }
330
331 /**
332 * Should we show the group selector?
333 * @return bool
334 */
335 public function display_group_selector() {
336 return true;
337 }
338
339 /**
340 * Should we show the next prev selector?
341 * @return bool
342 */
343 public function supports_next_prev() {
344 return true;
345 }
346}