Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
 
3
// This file is part of Moodle - http://moodle.org/
4
//
5
// Moodle is free software: you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation, either version 3 of the License, or
8
// (at your option) any later version.
9
//
10
// Moodle is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
// GNU General Public License for more details.
14
//
15
// You should have received a copy of the GNU General Public License
16
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17
 
18
require_once($CFG->dirroot.'/lib/gradelib.php');
19
require_once($CFG->dirroot.'/grade/lib.php');
20
require_once($CFG->dirroot.'/grade/export/grade_export_form.php');
21
 
22
/**
23
 * Base export class
24
 */
25
abstract class grade_export {
26
 
27
    /** @var int Value to state nothing is being exported. */
28
    protected const EXPORT_SELECT_NONE = -1;
29
 
30
    public $plugin; // plgin name - must be filled in subclasses!
31
 
32
    public $grade_items; // list of all course grade items
33
    public $groupid;     // groupid, 0 means all groups
34
    public $course;      // course object
35
    public $columns;     // array of grade_items selected for export
36
 
37
    public $export_letters;  // export letters
38
    public $export_feedback; // export feedback
39
    public $userkey;         // export using private user key
40
 
41
    public $updatedgradesonly; // only export updated grades
42
 
43
    /**
44
     *  Grade display type (real, percentages or letter).
45
     *
46
     *  This attribute is an integer for XML file export. Otherwise is an array for all other formats (ODS, XLS and TXT).
47
     *
48
     *  @var $displaytype Grade display type constant (1, 2 or 3) or an array of display types where the key is the name
49
     *                    and the value is the grade display type constant or 0 for unchecked display types.
50
     * @access public.
51
     */
52
    public $displaytype;
53
    public $decimalpoints; // number of decimal points for exports
54
    public $onlyactive; // only include users with an active enrolment
55
    public $usercustomfields; // include users custom fields
56
 
57
    /**
58
     * @deprecated since Moodle 2.8
59
     * @var $previewrows Number of rows in preview.
60
     */
61
    public $previewrows;
62
 
63
    /**
64
     * Constructor should set up all the private variables ready to be pulled.
65
     *
66
     * This constructor used to accept the individual parameters as separate arguments, in
67
     * 2.8 this was simplified to just accept the data from the moodle form.
68
     *
69
     * @access public
70
     * @param object $course
71
     * @param int $groupid
72
     * @param stdClass|null $formdata
73
     * @note Exporting as letters will lead to data loss if that exported set it re-imported.
74
     */
75
    public function __construct($course, $groupid, $formdata) {
76
        if (func_num_args() != 3 || ($formdata != null && get_class($formdata) != "stdClass")) {
77
            $args = func_get_args();
78
            return call_user_func_array(array($this, "deprecated_constructor"), $args);
79
        }
80
        $this->course = $course;
81
        $this->groupid = $groupid;
82
 
83
        $this->grade_items = grade_item::fetch_all(array('courseid'=>$this->course->id));
84
 
85
        $this->process_form($formdata);
86
    }
87
 
88
    /**
89
     * Old deprecated constructor.
90
     *
91
     * This deprecated constructor accepts the individual parameters as separate arguments, in
92
     * 2.8 this was simplified to just accept the data from the moodle form.
93
     *
94
     * @deprecated since 2.8 MDL-46548. Instead call the shortened constructor which accepts the data
95
     * directly from the grade_export_form.
96
     */
97
    protected function deprecated_constructor($course,
98
                                              $groupid=0,
99
                                              $itemlist='',
100
                                              $export_feedback=false,
101
                                              $updatedgradesonly = false,
102
                                              $displaytype = GRADE_DISPLAY_TYPE_REAL,
103
                                              $decimalpoints = 2,
104
                                              $onlyactive = false,
105
                                              $usercustomfields = false) {
106
 
107
        debugging('Many argument constructor for class "grade_export" is deprecated. Call the 3 argument version instead.', DEBUG_DEVELOPER);
108
 
109
        $this->course = $course;
110
        $this->groupid = $groupid;
111
 
112
        $this->grade_items = grade_item::fetch_all(array('courseid'=>$this->course->id));
113
        //Populating the columns here is required by /grade/export/(whatever)/export.php
114
        //however index.php, when the form is submitted, will construct the collection here
115
        //with an empty $itemlist then reconstruct it in process_form() using $formdata
116
        $this->columns = array();
117
        if (!empty($itemlist)) {
118
            // Check that user selected something.
119
            if ($itemlist != self::EXPORT_SELECT_NONE) {
120
                $itemids = explode(',', $itemlist);
121
                // remove items that are not requested
122
                foreach ($itemids as $itemid) {
123
                    if (array_key_exists($itemid, $this->grade_items)) {
124
                        $this->columns[$itemid] =& $this->grade_items[$itemid];
125
                    }
126
                }
127
            }
128
        } else {
129
            foreach ($this->grade_items as $itemid=>$unused) {
130
                $this->columns[$itemid] =& $this->grade_items[$itemid];
131
            }
132
        }
133
 
134
        $this->export_feedback = $export_feedback;
135
        $this->userkey         = '';
136
        $this->previewrows     = false;
137
        $this->updatedgradesonly = $updatedgradesonly;
138
 
139
        $this->displaytype = $displaytype;
140
        $this->decimalpoints = $decimalpoints;
141
        $this->onlyactive = $onlyactive;
142
        $this->usercustomfields = $usercustomfields;
143
    }
144
 
145
    /**
146
     * Init object based using data from form
147
     * @param object $formdata
148
     */
149
    function process_form($formdata) {
150
        global $USER;
151
 
152
        $this->columns = array();
153
        if (!empty($formdata->itemids)) {
154
            // Check that user selected something.
155
            if ($formdata->itemids != self::EXPORT_SELECT_NONE) {
156
                foreach ($formdata->itemids as $itemid=>$selected) {
157
                    if ($selected and array_key_exists($itemid, $this->grade_items)) {
158
                        $this->columns[$itemid] =& $this->grade_items[$itemid];
159
                    }
160
                }
161
            }
162
        } else {
163
            foreach ($this->grade_items as $itemid=>$unused) {
164
                $this->columns[$itemid] =& $this->grade_items[$itemid];
165
            }
166
        }
167
 
168
        if (isset($formdata->key)) {
169
            if ($formdata->key == 1 && isset($formdata->iprestriction) && isset($formdata->validuntil)) {
170
                // Create a new key
171
                $formdata->key = create_user_key('grade/export', $USER->id, $this->course->id, $formdata->iprestriction, $formdata->validuntil);
172
            }
173
            $this->userkey = $formdata->key;
174
        }
175
 
176
        if (isset($formdata->decimals)) {
177
            $this->decimalpoints = $formdata->decimals;
178
        }
179
 
180
        if (isset($formdata->export_letters)) {
181
            $this->export_letters = $formdata->export_letters;
182
        }
183
 
184
        if (isset($formdata->export_feedback)) {
185
            $this->export_feedback = $formdata->export_feedback;
186
        }
187
 
188
        if (isset($formdata->export_onlyactive)) {
189
            $this->onlyactive = $formdata->export_onlyactive;
190
        }
191
 
192
        if (isset($formdata->previewrows)) {
193
            $this->previewrows = $formdata->previewrows;
194
        }
195
 
196
        if (isset($formdata->display)) {
197
            $this->displaytype = $formdata->display;
198
 
199
            // Used by grade exports which accept multiple display types.
200
            // If the checkbox value is 0 (unchecked) then remove it.
201
            if (is_array($formdata->display)) {
202
                $this->displaytype = array_filter($formdata->display);
203
            }
204
        }
205
 
206
        if (isset($formdata->updatedgradesonly)) {
207
            $this->updatedgradesonly = $formdata->updatedgradesonly;
208
        }
209
    }
210
 
211
    /**
212
     * Update exported field in grade_grades table
213
     * @return boolean
214
     */
215
    public function track_exports() {
216
        global $CFG;
217
 
218
        /// Whether this plugin is entitled to update export time
219
        if ($expplugins = explode(",", $CFG->gradeexport)) {
220
            if (in_array($this->plugin, $expplugins)) {
221
                return true;
222
            } else {
223
                return false;
224
          }
225
        } else {
226
            return false;
227
        }
228
    }
229
 
230
    /**
231
     * Returns string representation of final grade
232
     * @param object $grade instance of grade_grade class
233
     * @param integer $gradedisplayconst grade display type constant.
234
     * @return string
235
     */
236
    public function format_grade($grade, $gradedisplayconst = null) {
237
        $displaytype = $this->displaytype;
238
        if (is_array($this->displaytype) && !is_null($gradedisplayconst)) {
239
            $displaytype = $gradedisplayconst;
240
        }
241
 
242
        $gradeitem = $this->grade_items[$grade->itemid];
243
 
244
        // We are going to store the min and max so that we can "reset" the grade_item for later.
245
        $grademax = $gradeitem->grademax;
246
        $grademin = $gradeitem->grademin;
247
 
248
        // Updating grade_item with this grade_grades min and max.
249
        $gradeitem->grademax = $grade->get_grade_max();
250
        $gradeitem->grademin = $grade->get_grade_min();
251
 
252
        $formattedgrade = grade_format_gradevalue($grade->finalgrade, $gradeitem, false, $displaytype, $this->decimalpoints);
253
 
254
        // Resetting the grade item in case it is reused.
255
        $gradeitem->grademax = $grademax;
256
        $gradeitem->grademin = $grademin;
257
 
258
        return $formattedgrade;
259
    }
260
 
261
    /**
262
     * Returns the name of column in export
263
     * @param object $grade_item
264
     * @param boolean $feedback feedback colum
265
     * @param string $gradedisplayname grade display name.
266
     * @return string
267
     */
268
    public function format_column_name($grade_item, $feedback=false, $gradedisplayname = null) {
269
        $column = new stdClass();
270
 
271
        if ($grade_item->itemtype == 'mod') {
272
            $column->name = get_string('modulename', $grade_item->itemmodule).get_string('labelsep', 'langconfig').$grade_item->get_name();
273
        } else {
274
            $column->name = $grade_item->get_name(true);
275
        }
276
 
277
        // We can't have feedback and display type at the same time.
278
        $column->extra = ($feedback) ? get_string('feedback') : get_string($gradedisplayname, 'grades');
279
 
280
        return html_to_text(get_string('gradeexportcolumntype', 'grades', $column), 0, false);
281
    }
282
 
283
    /**
284
     * Returns formatted grade feedback
285
     * @param object $feedback object with properties feedback and feedbackformat
286
     * @param object $grade Grade object with grade properties
287
     * @return string
288
     */
289
    public function format_feedback($feedback, $grade = null) {
290
        $string = $feedback->feedback;
291
        if (!empty($grade)) {
292
            // Rewrite links to get the export working for 36, refer MDL-63488.
293
            $string = file_rewrite_pluginfile_urls(
294
                $feedback->feedback,
295
                'pluginfile.php',
296
                $grade->get_context()->id,
297
                GRADE_FILE_COMPONENT,
298
                GRADE_FEEDBACK_FILEAREA,
299
                $grade->id
300
            );
301
        }
302
 
303
        return strip_tags(format_text($string, $feedback->feedbackformat));
304
    }
305
 
306
    /**
307
     * Implemented by child class
308
     */
309
    abstract public function print_grades();
310
 
311
    /**
312
     * Prints preview of exported grades on screen as a feedback mechanism
313
     * @param bool $require_user_idnumber true means skip users without idnumber
314
     * @deprecated since 2.8 MDL-46548. Previews are not useful on export.
315
     */
316
    public function display_preview($require_user_idnumber=false) {
317
        global $OUTPUT;
318
 
319
        debugging('function grade_export::display_preview is deprecated.', DEBUG_DEVELOPER);
320
 
321
        $userprofilefields = grade_helper::get_user_profile_fields($this->course->id, $this->usercustomfields);
322
        $formatoptions = new stdClass();
323
        $formatoptions->para = false;
324
 
325
        echo $OUTPUT->heading(get_string('previewrows', 'grades'));
326
 
327
        echo '<table>';
328
        echo '<tr>';
329
        foreach ($userprofilefields as $field) {
330
            echo '<th>' . $field->fullname . '</th>';
331
        }
332
        if (!$this->onlyactive) {
333
            echo '<th>'.get_string("suspended")."</th>";
334
        }
335
        foreach ($this->columns as $grade_item) {
336
            echo '<th>'.$this->format_column_name($grade_item).'</th>';
337
 
338
            /// add a column_feedback column
339
            if ($this->export_feedback) {
340
                echo '<th>'.$this->format_column_name($grade_item, true).'</th>';
341
            }
342
        }
343
        echo '</tr>';
344
        /// Print all the lines of data.
345
        $i = 0;
346
        $gui = new graded_users_iterator($this->course, $this->columns, $this->groupid);
347
        $gui->require_active_enrolment($this->onlyactive);
348
        $gui->allow_user_custom_fields($this->usercustomfields);
349
        $gui->init();
350
        while ($userdata = $gui->next_user()) {
351
            // number of preview rows
352
            if ($this->previewrows and $this->previewrows <= $i) {
353
                break;
354
            }
355
            $user = $userdata->user;
356
            if ($require_user_idnumber and empty($user->idnumber)) {
357
                // some exports require user idnumber so we can match up students when importing the data
358
                continue;
359
            }
360
 
361
            $gradeupdated = false; // if no grade is update at all for this user, do not display this row
362
            $rowstr = '';
363
            foreach ($this->columns as $itemid=>$unused) {
364
                $gradetxt = $this->format_grade($userdata->grades[$itemid]);
365
 
366
                // get the status of this grade, and put it through track to get the status
367
                $g = new grade_export_update_buffer();
368
                $grade_grade = new grade_grade(array('itemid'=>$itemid, 'userid'=>$user->id));
369
                $status = $g->track($grade_grade);
370
 
371
                if ($this->updatedgradesonly && ($status == 'nochange' || $status == 'unknown')) {
372
                    $rowstr .= '<td>'.get_string('unchangedgrade', 'grades').'</td>';
373
                } else {
374
                    $rowstr .= "<td>$gradetxt</td>";
375
                    $gradeupdated = true;
376
                }
377
 
378
                if ($this->export_feedback) {
379
                    $rowstr .=  '<td>'.$this->format_feedback($userdata->feedbacks[$itemid]).'</td>';
380
                }
381
            }
382
 
383
            // if we are requesting updated grades only, we are not interested in this user at all
384
            if (!$gradeupdated && $this->updatedgradesonly) {
385
                continue;
386
            }
387
 
388
            echo '<tr>';
389
            foreach ($userprofilefields as $field) {
390
                $fieldvalue = grade_helper::get_user_field_value($user, $field);
391
                // @see profile_field_base::display_data().
392
                echo '<td>' . format_text($fieldvalue, FORMAT_MOODLE, $formatoptions) . '</td>';
393
            }
394
            if (!$this->onlyactive) {
395
                $issuspended = ($user->suspendedenrolment) ? get_string('yes') : '';
396
                echo "<td>$issuspended</td>";
397
            }
398
            echo $rowstr;
399
            echo "</tr>";
400
 
401
            $i++; // increment the counter
402
        }
403
        echo '</table>';
404
        $gui->close();
405
    }
406
 
407
    /**
408
     * Returns array of parameters used by dump.php and export.php.
409
     * @return array
410
     */
411
    public function get_export_params() {
412
        $itemids = array_keys($this->columns);
413
        $itemidsparam = implode(',', $itemids);
414
        if (empty($itemidsparam)) {
415
            $itemidsparam = self::EXPORT_SELECT_NONE;
416
        }
417
 
418
        // We have a single grade display type constant.
419
        if (!is_array($this->displaytype)) {
420
            $displaytypes = $this->displaytype;
421
        } else {
422
            // Implode the grade display types array as moodle_url function doesn't accept arrays.
423
            $displaytypes = implode(',', $this->displaytype);
424
        }
425
 
426
        if (!empty($this->updatedgradesonly)) {
427
            $updatedgradesonly = $this->updatedgradesonly;
428
        } else {
429
            $updatedgradesonly = 0;
430
        }
431
        $params = array('id'                => $this->course->id,
432
                        'groupid'           => $this->groupid,
433
                        'itemids'           => $itemidsparam,
434
                        'export_letters'    => $this->export_letters,
435
                        'export_feedback'   => $this->export_feedback,
436
                        'updatedgradesonly' => $updatedgradesonly,
437
                        'decimalpoints'     => $this->decimalpoints,
438
                        'export_onlyactive' => $this->onlyactive,
439
                        'usercustomfields'  => $this->usercustomfields,
440
                        'displaytype'       => $displaytypes,
441
                        'key'               => $this->userkey);
442
 
443
        return $params;
444
    }
445
 
446
    /**
447
     * Either prints a "Export" box, which will redirect the user to the download page,
448
     * or prints the URL for the published data.
449
     *
450
     * @deprecated since 2.8 MDL-46548. Call get_export_url and set the
451
     *             action of the grade_export_form instead.
452
     * @return void
453
     */
454
    public function print_continue() {
455
        global $CFG, $OUTPUT;
456
 
457
        debugging('function grade_export::print_continue is deprecated.', DEBUG_DEVELOPER);
458
        $params = $this->get_export_params();
459
 
460
        echo $OUTPUT->heading(get_string('export', 'grades'));
461
 
462
        echo $OUTPUT->container_start('gradeexportlink');
463
 
464
        if (!$this->userkey) {
465
            // This button should trigger a download prompt.
466
            $url = new moodle_url('/grade/export/'.$this->plugin.'/export.php', $params);
467
            echo $OUTPUT->single_button($url, get_string('download', 'admin'));
468
 
469
        } else {
470
            $paramstr = '';
471
            $sep = '?';
472
            foreach($params as $name=>$value) {
473
                $paramstr .= $sep.$name.'='.$value;
474
                $sep = '&';
475
            }
476
 
477
            $link = $CFG->wwwroot.'/grade/export/'.$this->plugin.'/dump.php'.$paramstr.'&key='.$this->userkey;
478
 
479
            echo get_string('download', 'admin').': ' . html_writer::link($link, $link);
480
        }
481
        echo $OUTPUT->container_end();
482
 
483
        return;
484
    }
485
 
486
    /**
487
     * Generate the export url.
488
     *
489
     * Get submitted form data and create the url to be used on the grade publish feature.
490
     *
491
     * @return moodle_url the url of grade publishing export.
492
     */
493
    public function get_export_url() {
494
        return new moodle_url('/grade/export/'.$this->plugin.'/dump.php', $this->get_export_params());
495
    }
496
 
497
    /**
498
     * Convert the grade display types parameter into the required array to grade exporting class.
499
     *
500
     * In order to export, the array key must be the display type name and the value must be the grade display type
501
     * constant.
502
     *
503
     * Note: Added support for combined display types constants like the (GRADE_DISPLAY_TYPE_PERCENTAGE_REAL) as
504
     *       the $CFG->grade_export_displaytype config is still used on 2.7 in case of missing displaytype url param.
505
     *       In these cases, the file will be exported with a column for each display type.
506
     *
507
     * @param string $displaytypes can be a single or multiple display type constants comma separated.
508
     * @return array $types
509
     */
510
    public static function convert_flat_displaytypes_to_array($displaytypes) {
511
        $types = array();
512
 
513
        // We have a single grade display type constant.
514
        if (is_int($displaytypes)) {
515
            $displaytype = clean_param($displaytypes, PARAM_INT);
516
 
517
            // Let's set a default value, will be replaced below by the grade display type constant.
518
            $display[$displaytype] = 1;
519
        } else {
520
            // Multiple grade display types constants.
521
            $display = array_flip(explode(',', $displaytypes));
522
        }
523
 
524
        // Now, create the array in the required format by grade exporting class.
525
        foreach ($display as $type => $value) {
526
            $type = clean_param($type, PARAM_INT);
527
            if ($type == GRADE_DISPLAY_TYPE_LETTER) {
528
                $types['letter'] = GRADE_DISPLAY_TYPE_LETTER;
529
            } else if ($type == GRADE_DISPLAY_TYPE_PERCENTAGE) {
530
                $types['percentage'] = GRADE_DISPLAY_TYPE_PERCENTAGE;
531
            } else if ($type == GRADE_DISPLAY_TYPE_REAL) {
532
                $types['real'] = GRADE_DISPLAY_TYPE_REAL;
533
            } else if ($type == GRADE_DISPLAY_TYPE_REAL_PERCENTAGE) {
534
                $types['real'] = GRADE_DISPLAY_TYPE_REAL;
535
                $types['percentage'] = GRADE_DISPLAY_TYPE_PERCENTAGE;
536
            } else if ($type == GRADE_DISPLAY_TYPE_REAL_LETTER) {
537
                $types['real'] = GRADE_DISPLAY_TYPE_REAL;
538
                $types['letter'] = GRADE_DISPLAY_TYPE_LETTER;
539
            } else if ($type == GRADE_DISPLAY_TYPE_LETTER_REAL) {
540
                $types['letter'] = GRADE_DISPLAY_TYPE_LETTER;
541
                $types['real'] = GRADE_DISPLAY_TYPE_REAL;
542
            } else if ($type == GRADE_DISPLAY_TYPE_LETTER_PERCENTAGE) {
543
                $types['letter'] = GRADE_DISPLAY_TYPE_LETTER;
544
                $types['percentage'] = GRADE_DISPLAY_TYPE_PERCENTAGE;
545
            } else if ($type == GRADE_DISPLAY_TYPE_PERCENTAGE_LETTER) {
546
                $types['percentage'] = GRADE_DISPLAY_TYPE_PERCENTAGE;
547
                $types['letter'] = GRADE_DISPLAY_TYPE_LETTER;
548
            } else if ($type == GRADE_DISPLAY_TYPE_PERCENTAGE_REAL) {
549
                $types['percentage'] = GRADE_DISPLAY_TYPE_PERCENTAGE;
550
                $types['real'] = GRADE_DISPLAY_TYPE_REAL;
551
            }
552
        }
553
        return $types;
554
    }
555
 
556
    /**
557
     * Convert the item ids parameter into the required array to grade exporting class.
558
     *
559
     * In order to export, the array key must be the grade item id and all values must be one.
560
     *
561
     * @param string $itemids can be a single item id or many item ids comma separated.
562
     * @return array $items correctly formatted array.
563
     */
564
    public static function convert_flat_itemids_to_array($itemids) {
565
        $items = array();
566
 
567
        // We just have one single item id.
568
        if (is_int($itemids)) {
569
            $itemid = clean_param($itemids, PARAM_INT);
570
            $items[$itemid] = 1;
571
        } else {
572
            // Few grade items.
573
            $items = array_flip(explode(',', $itemids));
574
            foreach ($items as $itemid => $value) {
575
                $itemid = clean_param($itemid, PARAM_INT);
576
                $items[$itemid] = 1;
577
            }
578
        }
579
        return $items;
580
    }
581
 
582
    /**
583
     * Create the html code of the grade publishing feature.
584
     *
585
     * @return string $output html code of the grade publishing.
586
     */
587
    public function get_grade_publishing_url() {
588
        $url = $this->get_export_url();
589
        $output =  html_writer::start_div();
590
        $output .= html_writer::tag('p', get_string('gradepublishinglink', 'grades', html_writer::link($url, $url)));
591
        $output .=  html_writer::end_div();
592
        return $output;
593
    }
594
 
595
    /**
596
     * Create a stdClass object from URL parameters to be used by grade_export class.
597
     *
598
     * @param int $id course id.
599
     * @param string $itemids grade items comma separated.
600
     * @param bool $exportfeedback export feedback option.
601
     * @param bool $onlyactive only enrolled active students.
602
     * @param string $displaytype grade display type constants comma separated.
603
     * @param int $decimalpoints grade decimal points.
604
     * @param null $updatedgradesonly recently updated grades only (Used by XML exporting only).
605
     * @param null $separator separator character: tab, comma, colon and semicolon (Used by TXT exporting only).
606
     *
607
     * @return stdClass $formdata
608
     */
609
    public static function export_bulk_export_data($id, $itemids, $exportfeedback, $onlyactive, $displaytype,
610
                                                   $decimalpoints, $updatedgradesonly = null, $separator = null) {
611
 
612
        $formdata = new \stdClass();
613
        $formdata->id = $id;
614
        $formdata->itemids = self::convert_flat_itemids_to_array($itemids);
615
        $formdata->exportfeedback = $exportfeedback;
616
        $formdata->export_onlyactive = $onlyactive;
617
        $formdata->display = self::convert_flat_displaytypes_to_array($displaytype);
618
        $formdata->decimals = $decimalpoints;
619
 
620
        if (!empty($updatedgradesonly)) {
621
            $formdata->updatedgradesonly = $updatedgradesonly;
622
        }
623
 
624
        if (!empty($separator)) {
625
            $formdata->separator = $separator;
626
        }
627
 
628
        return $formdata;
629
    }
630
}
631
 
632
/**
633
 * This class is used to update the exported field in grade_grades.
634
 * It does internal buffering to speedup the db operations.
635
 */
636
class grade_export_update_buffer {
637
    public $update_list;
638
    public $export_time;
639
 
640
    /**
641
     * Constructor - creates the buffer and initialises the time stamp
642
     */
643
    public function __construct() {
644
        $this->update_list = array();
645
        $this->export_time = time();
646
    }
647
 
648
    /**
649
     * Old syntax of class constructor. Deprecated in PHP7.
650
     *
651
     * @deprecated since Moodle 3.1
652
     */
653
    public function grade_export_update_buffer() {
654
        debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER);
655
        self::__construct();
656
    }
657
 
658
    public function flush($buffersize) {
659
        global $CFG, $DB;
660
 
661
        if (count($this->update_list) > $buffersize) {
662
            list($usql, $params) = $DB->get_in_or_equal($this->update_list);
663
            $params = array_merge(array($this->export_time), $params);
664
 
665
            $sql = "UPDATE {grade_grades} SET exported = ? WHERE id $usql";
666
            $DB->execute($sql, $params);
667
            $this->update_list = array();
668
        }
669
    }
670
 
671
    /**
672
     * Track grade export status
673
     * @param object $grade_grade
674
     * @return string $status (unknow, new, regrade, nochange)
675
     */
676
    public function track($grade_grade) {
677
 
678
        if (empty($grade_grade->exported) or empty($grade_grade->timemodified)) {
679
            if (is_null($grade_grade->finalgrade)) {
680
                // grade does not exist yet
681
                $status = 'unknown';
682
            } else {
683
                $status = 'new';
684
                $this->update_list[] = $grade_grade->id;
685
            }
686
 
687
        } else if ($grade_grade->exported < $grade_grade->timemodified) {
688
            $status = 'regrade';
689
            $this->update_list[] = $grade_grade->id;
690
 
691
        } else if ($grade_grade->exported >= $grade_grade->timemodified) {
692
            $status = 'nochange';
693
 
694
        } else {
695
            // something is wrong?
696
            $status = 'unknown';
697
        }
698
 
699
        $this->flush(100);
700
 
701
        return $status;
702
    }
703
 
704
    /**
705
     * Flush and close the buffer.
706
     */
707
    public function close() {
708
        $this->flush(0);
709
    }
710
}
711
 
712
/**
713
 * Verify that there is a valid set of grades to export.
714
 * @param $courseid int The course being exported
715
 */
716
function export_verify_grades($courseid) {
717
    if (grade_needs_regrade_final_grades($courseid)) {
718
        throw new moodle_exception('gradesneedregrading', 'grades');
719
    }
720
}