Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
MDL-61905 workshop: Implement privacy API in grading strategies
On low level, standard grading strategies subplugins do not store
personal themselves.  They make use of the grades storage provided by
the workshop itself.  What they do contain though is the information
about how the assessment forms were defined. And they are also
responsible for correctly interpreting the values in the central grades
table.

Grading strategies fulfil the contract with the parent workshop module
by implementing the workshopform_provider interface. That gives them a
chance to export data about the assessment form to each of exported
assessment.
  • Loading branch information
mudrd8mz committed May 9, 2018
1 parent d3ae85a commit be19685
Show file tree
Hide file tree
Showing 12 changed files with 980 additions and 0 deletions.
105 changes: 105 additions & 0 deletions mod/workshop/form/accumulative/classes/privacy/provider.php
@@ -0,0 +1,105 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* Provides the class {@link workshopform_accumulative\privacy\provider}
*
* @package workshopform_accumulative
* @category privacy
* @copyright 2018 David Mudrák <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

namespace workshopform_accumulative\privacy;

use core_privacy\local\request\writer;

defined('MOODLE_INTERNAL') || die();

/**
* Privacy API implementation for the Accumulative grading strategy.
*
* @copyright 2018 David Mudrák <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider, \mod_workshop\privacy\workshopform_provider {

/**
* Explain that this plugin stores no personal data.
*
* @return string
*/
public static function get_reason() {
return 'privacy:metadata';
}

/**
* Return details of the filled assessment form.
*
* @param stdClass $user User we are exporting data for
* @param context $context The workshop activity context
* @param array $subcontext Subcontext within the context to export to
* @param int $assessmentid ID of the assessment
*/
public static function export_assessment_form(\stdClass $user, \context $context, array $subcontext, $assessmentid) {
global $DB;

if ($context->contextlevel != CONTEXT_MODULE) {
throw new \coding_exception('Unexpected context provided');
}

$sql = "SELECT dim.id, dim.description, dim.descriptionformat, dim.grade AS dimgrade, dim.weight,
wg.grade, wg.peercomment, wg.peercommentformat
FROM {course_modules} cm
JOIN {context} ctx ON ctx.contextlevel = :contextlevel AND ctx.instanceid = cm.id
JOIN {workshop} w ON cm.instance = w.id
JOIN {workshopform_accumulative} dim ON dim.workshopid = w.id
LEFT JOIN {workshop_grades} wg ON wg.strategy = :strategy
AND wg.dimensionid = dim.id AND wg.assessmentid = :assessmentid
WHERE ctx.id = :contextid
ORDER BY dim.sort";

$params = [
'strategy' => 'accumulative',
'contextlevel' => CONTEXT_MODULE,
'contextid' => $context->id,
'assessmentid' => $assessmentid,
];

$writer = \core_privacy\local\request\writer::with_context($context);
$data = [];
$hasdata = false;
$dimensionids = [];

foreach ($DB->get_records_sql($sql, $params) as $record) {
if ($record->grade !== null) {
$hasdata = true;
}
$record->description = $writer->rewrite_pluginfile_urls($subcontext, 'workshopform_accumulative',
'description', $record->id, $record->description);
$dimensionids[] = $record->id;
unset($record->id);
$data[] = $record;
}

if ($hasdata) {
$writer->export_data($subcontext, (object) ['aspects' => $data]);
foreach ($dimensionids as $dimensionid) {
$writer->export_area_files($subcontext, 'workshopform_accumulative', 'description', $dimensionid);
}
}
}
}
Expand Up @@ -39,6 +39,7 @@
$string['pluginname'] = 'Accumulative grading';
$string['poor'] = 'Poor';
$string['present'] = 'Present';
$string['privacy:metadata'] = 'The Accumulative grading plugin only stores the details of the assessment form. Actual personal data of how the form has been filled are stored by the Workshop module itself and are attached to exported assessments.';
$string['scalename0'] = 'Yes/No (2 point)';
$string['scalename1'] = 'Present/Absent (2 point)';
$string['scalename2'] = 'Correct/Incorrect (2 point)';
Expand Down
122 changes: 122 additions & 0 deletions mod/workshop/form/accumulative/tests/privacy_provider_test.php
@@ -0,0 +1,122 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* Provides the {@link workshopform_accumulative_privacy_provider_testcase} class.
*
* @package workshopform_accumulative
* @category test
* @copyright 2018 David Mudrák <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

defined('MOODLE_INTERNAL') || die();

global $CFG;

use core_privacy\local\request\writer;

/**
* Unit tests for the privacy API implementation.
*
* @copyright 2018 David Mudrák <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class workshopform_accumulative_privacy_provider_testcase extends advanced_testcase {

/**
* Test {@link workshopform_accumulative\privacy\provider::export_assessment_form()} implementation.
*/
public function test_export_assessment_form() {
global $DB;
$this->resetAfterTest();
$this->setAdminUser();

$this->generator = $this->getDataGenerator();
$this->workshopgenerator = $this->generator->get_plugin_generator('mod_workshop');

$this->course1 = $this->generator->create_course();

$this->workshop11 = $this->generator->create_module('workshop', [
'course' => $this->course1,
'name' => 'Workshop11',
]);
$DB->set_field('workshop', 'phase', 50, ['id' => $this->workshop11->id]);

$this->dim1 = $DB->insert_record('workshopform_accumulative', [
'workshopid' => $this->workshop11->id,
'sort' => 1,
'description' => 'Aspect 1 description',
'descriptionformat' => FORMAT_MARKDOWN,
'grade' => 6,
'weight' => 1,
]);

$this->dim2 = $DB->insert_record('workshopform_accumulative', [
'workshopid' => $this->workshop11->id,
'sort' => 2,
'description' => 'Aspect 2 description',
'descriptionformat' => FORMAT_MARKDOWN,
'grade' => 4,
'weight' => 1,
]);

$this->student1 = $this->generator->create_user();
$this->student2 = $this->generator->create_user();

$this->submission111 = $this->workshopgenerator->create_submission($this->workshop11->id, $this->student1->id);

$this->assessment1112 = $this->workshopgenerator->create_assessment($this->submission111, $this->student2->id, [
'grade' => 92,
]);

$DB->insert_record('workshop_grades', [
'assessmentid' => $this->assessment1112,
'strategy' => 'accumulative',
'dimensionid' => $this->dim1,
'grade' => 3,
'peercomment' => 'Not awesome',
'peercommentformat' => FORMAT_PLAIN,
]);

$DB->insert_record('workshop_grades', [
'assessmentid' => $this->assessment1112,
'strategy' => 'accumulative',
'dimensionid' => $this->dim2,
'grade' => 4,
'peercomment' => 'All good',
'peercommentformat' => FORMAT_PLAIN,
]);

$contextlist = new \core_privacy\local\request\approved_contextlist($this->student2, 'mod_workshop', [
\context_module::instance($this->workshop11->cmid)->id,
]);

\mod_workshop\privacy\provider::export_user_data($contextlist);

$writer = writer::with_context(\context_module::instance($this->workshop11->cmid));

$form = $writer->get_data([
get_string('myassessments', 'mod_workshop'),
$this->assessment1112,
get_string('assessmentform', 'mod_workshop'),
get_string('pluginname', 'workshopform_accumulative'),
]);

$this->assertEquals('Aspect 1 description', $form->aspects[0]->description);
$this->assertEquals(4, $form->aspects[1]->grade);
}
}
104 changes: 104 additions & 0 deletions mod/workshop/form/comments/classes/privacy/provider.php
@@ -0,0 +1,104 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* Provides the class {@link workshopform_comments\privacy\provider}
*
* @package workshopform_comments
* @category privacy
* @copyright 2018 David Mudrák <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

namespace workshopform_comments\privacy;

use core_privacy\local\request\writer;

defined('MOODLE_INTERNAL') || die();

/**
* Privacy API implementation for the Comments grading strategy.
*
* @copyright 2018 David Mudrák <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider, \mod_workshop\privacy\workshopform_provider {

/**
* Explain that this plugin stores no personal data.
*
* @return string
*/
public static function get_reason() {
return 'privacy:metadata';
}

/**
* Return details of the filled assessment form.
*
* @param stdClass $user User we are exporting data for
* @param context $context The workshop activity context
* @param array $subcontext Subcontext within the context to export to
* @param int $assessmentid ID of the assessment
*/
public static function export_assessment_form(\stdClass $user, \context $context, array $subcontext, $assessmentid) {
global $DB;

if ($context->contextlevel != CONTEXT_MODULE) {
throw new \coding_exception('Unexpected context provided');
}

$sql = "SELECT dim.id, dim.description, dim.descriptionformat, wg.peercomment, wg.peercommentformat
FROM {course_modules} cm
JOIN {context} ctx ON ctx.contextlevel = :contextlevel AND ctx.instanceid = cm.id
JOIN {workshop} w ON cm.instance = w.id
JOIN {workshopform_comments} dim ON dim.workshopid = w.id
LEFT JOIN {workshop_grades} wg ON wg.strategy = :strategy
AND wg.dimensionid = dim.id AND wg.assessmentid = :assessmentid
WHERE ctx.id = :contextid
ORDER BY dim.sort";

$params = [
'strategy' => 'comments',
'contextlevel' => CONTEXT_MODULE,
'contextid' => $context->id,
'assessmentid' => $assessmentid,
];

$writer = \core_privacy\local\request\writer::with_context($context);
$data = [];
$hasdata = false;
$dimensionids = [];

foreach ($DB->get_records_sql($sql, $params) as $record) {
if ($record->peercomment !== null) {
$hasdata = true;
}
$record->description = $writer->rewrite_pluginfile_urls($subcontext, 'workshopform_comments',
'description', $record->id, $record->description);
$dimensionids[] = $record->id;
unset($record->id);
$data[] = $record;
}

if ($hasdata) {
$writer->export_data($subcontext, (object) ['aspects' => $data]);
foreach ($dimensionids as $dimensionid) {
$writer->export_area_files($subcontext, 'workshopform_comments', 'description', $dimensionid);
}
}
}
}
Expand Up @@ -28,6 +28,7 @@
$string['dimensiondescription'] = 'Description';
$string['dimensionnumber'] = 'Aspect {$a}';
$string['pluginname'] = 'Comments';
$string['privacy:metadata'] = 'The Comments grading plugin only stores the details of the assessment form. Actual personal data of how the form has been filled are stored by the Workshop module itself and are attached to exported assessments.';

// Deprecated since Moodle 3.1.
$string['dimensioncomment'] = 'Comment';

0 comments on commit be19685

Please sign in to comment.