Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
 * Data privacy plugin library
19
 * @package   tool_dataprivacy
20
 * @copyright 2018 onwards Jun Pataleta
21
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22
 */
23
 
24
use core_user\output\myprofile\tree;
25
use tool_dataprivacy\form\exportfilter_form;
26
 
27
/**
28
 * Add nodes to myprofile page.
29
 *
30
 * @param tree $tree Tree object
31
 * @param stdClass $user User object
32
 * @param bool $iscurrentuser
33
 * @param stdClass $course Course object
34
 * @return bool
35
 * @throws coding_exception
36
 * @throws dml_exception
37
 * @throws moodle_exception
38
 */
39
function tool_dataprivacy_myprofile_navigation(tree $tree, $user, $iscurrentuser, $course) {
40
    global $PAGE, $USER;
41
 
42
    // Get the Privacy and policies category.
43
    if (!array_key_exists('privacyandpolicies', $tree->__get('categories'))) {
44
        // Create the category.
45
        $categoryname = get_string('privacyandpolicies', 'admin');
46
        $category = new core_user\output\myprofile\category('privacyandpolicies', $categoryname, 'contact');
47
        $tree->add_category($category);
48
    } else {
49
        // Get the existing category.
50
        $category = $tree->__get('categories')['privacyandpolicies'];
51
    }
52
 
53
    // Contact data protection officer link.
54
    if (\tool_dataprivacy\api::can_contact_dpo() && $iscurrentuser) {
55
        $renderer = $PAGE->get_renderer('tool_dataprivacy');
56
        $content = $renderer->render_contact_dpo_link();
57
        $node = new core_user\output\myprofile\node('privacyandpolicies', 'contactdpo', null, null, null, $content);
58
        $category->add_node($node);
59
 
60
        // Require our Javascript module to handle contact DPO interaction.
61
        $PAGE->requires->js_call_amd('tool_dataprivacy/contactdpo', 'init');
62
 
63
        $url = new moodle_url('/admin/tool/dataprivacy/mydatarequests.php');
64
        $node = new core_user\output\myprofile\node('privacyandpolicies', 'datarequests',
65
            get_string('datarequests', 'tool_dataprivacy'), null, $url);
66
        $category->add_node($node);
67
 
68
        // Check if the user has an ongoing data export request.
69
        $hasexportrequest = \tool_dataprivacy\api::has_ongoing_request($user->id, \tool_dataprivacy\api::DATAREQUEST_TYPE_EXPORT);
70
        // Show data export link only if the user doesn't have an ongoing data export request and has permission
71
        // to download own data.
72
        if (!$hasexportrequest && \tool_dataprivacy\api::can_create_data_download_request_for_self()) {
73
            $exportparams = ['type' => \tool_dataprivacy\api::DATAREQUEST_TYPE_EXPORT];
74
            $exporturl = new moodle_url('/admin/tool/dataprivacy/createdatarequest.php', $exportparams);
75
            $exportnode = new core_user\output\myprofile\node('privacyandpolicies', 'requestdataexport',
76
                get_string('requesttypeexport', 'tool_dataprivacy'), null, $exporturl);
77
            $category->add_node($exportnode);
78
        }
79
 
80
        // Check if the user has an ongoing data deletion request.
81
        $hasdeleterequest = \tool_dataprivacy\api::has_ongoing_request($user->id, \tool_dataprivacy\api::DATAREQUEST_TYPE_DELETE);
82
        // Show data deletion link only if the user doesn't have an ongoing data deletion request and has permission
83
        // to create data deletion request.
84
        if (!$hasdeleterequest && \tool_dataprivacy\api::can_create_data_deletion_request_for_self()) {
85
            $deleteparams = ['type' => \tool_dataprivacy\api::DATAREQUEST_TYPE_DELETE];
86
            $deleteurl = new moodle_url('/admin/tool/dataprivacy/createdatarequest.php', $deleteparams);
87
            $deletenode = new core_user\output\myprofile\node('privacyandpolicies', 'requestdatadeletion',
88
                get_string('deletemyaccount', 'tool_dataprivacy'), null, $deleteurl);
89
            $category->add_node($deletenode);
90
        }
91
    }
92
 
93
    // A returned 0 means that the setting was set and disabled, false means that there is no value for the provided setting.
94
    $showsummary = get_config('tool_dataprivacy', 'showdataretentionsummary');
95
    if ($showsummary === false) {
96
        // This means that no value is stored in db. We use the default value in this case.
97
        $showsummary = true;
98
    }
99
 
100
    if ($showsummary && $iscurrentuser) {
101
        $summaryurl = new moodle_url('/admin/tool/dataprivacy/summary.php');
102
        $summarynode = new core_user\output\myprofile\node('privacyandpolicies', 'retentionsummary',
103
            get_string('dataretentionsummary', 'tool_dataprivacy'), null, $summaryurl);
104
        $category->add_node($summarynode);
105
    }
106
 
107
    // Add the Privacy category to the tree if it's not empty and it doesn't exist.
108
    $nodes = $category->nodes;
109
    if (!empty($nodes)) {
110
        if (!array_key_exists('privacyandpolicies', $tree->__get('categories'))) {
111
            $tree->add_category($category);
112
        }
113
        return true;
114
    }
115
 
116
    return false;
117
}
118
 
119
/**
120
 * Fragment to add a new purpose.
121
 *
122
 * @param array $args The fragment arguments.
123
 * @return string The rendered mform fragment.
124
 */
125
function tool_dataprivacy_output_fragment_addpurpose_form($args) {
126
 
127
    $formdata = [];
128
    if (!empty($args['jsonformdata'])) {
129
        $serialiseddata = json_decode($args['jsonformdata']);
130
        parse_str($serialiseddata, $formdata);
131
    }
132
 
133
    $persistent = new \tool_dataprivacy\purpose();
134
    $mform = new \tool_dataprivacy\form\purpose(null, ['persistent' => $persistent],
135
        'post', '', null, true, $formdata);
136
 
137
    if (!empty($args['jsonformdata'])) {
138
        // Show errors if data was received.
139
        $mform->is_validated();
140
    }
141
 
142
    return $mform->render();
143
}
144
 
145
/**
146
 * Fragment to add a new category.
147
 *
148
 * @param array $args The fragment arguments.
149
 * @return string The rendered mform fragment.
150
 */
151
function tool_dataprivacy_output_fragment_addcategory_form($args) {
152
 
153
    $formdata = [];
154
    if (!empty($args['jsonformdata'])) {
155
        $serialiseddata = json_decode($args['jsonformdata']);
156
        parse_str($serialiseddata, $formdata);
157
    }
158
 
159
    $persistent = new \tool_dataprivacy\category();
160
    $mform = new \tool_dataprivacy\form\category(null, ['persistent' => $persistent],
161
        'post', '', null, true, $formdata);
162
 
163
    if (!empty($args['jsonformdata'])) {
164
        // Show errors if data was received.
165
        $mform->is_validated();
166
    }
167
 
168
    return $mform->render();
169
}
170
 
171
/**
172
 * Fragment to edit a context purpose and category.
173
 *
174
 * @param array $args The fragment arguments.
175
 * @return string The rendered mform fragment.
176
 */
177
function tool_dataprivacy_output_fragment_context_form($args) {
178
    global $PAGE;
179
 
180
    $contextid = $args[0];
181
 
182
    $context = \context_helper::instance_by_id($contextid);
183
    $customdata = \tool_dataprivacy\form\context_instance::get_context_instance_customdata($context);
184
 
185
    if (!empty($customdata['purposeretentionperiods'])) {
186
        $PAGE->requires->js_call_amd('tool_dataprivacy/effective_retention_period', 'init',
187
            [$customdata['purposeretentionperiods']]);
188
    }
189
    $mform = new \tool_dataprivacy\form\context_instance(null, $customdata);
190
    return $mform->render();
191
}
192
 
193
/**
194
 * Fragment to edit a contextlevel purpose and category.
195
 *
196
 * @param array $args The fragment arguments.
197
 * @return string The rendered mform fragment.
198
 */
199
function tool_dataprivacy_output_fragment_contextlevel_form($args) {
200
    global $PAGE;
201
 
202
    $contextlevel = $args[0];
203
    $customdata = \tool_dataprivacy\form\contextlevel::get_contextlevel_customdata($contextlevel);
204
 
205
    if (!empty($customdata['purposeretentionperiods'])) {
206
        $PAGE->requires->js_call_amd('tool_dataprivacy/effective_retention_period', 'init',
207
            [$customdata['purposeretentionperiods']]);
208
    }
209
 
210
    $mform = new \tool_dataprivacy\form\contextlevel(null, $customdata);
211
    return $mform->render();
212
}
213
 
214
/**
215
 * Serves any files associated with the data privacy settings.
216
 *
217
 * @param stdClass $course Course object
218
 * @param stdClass $cm Course module object
219
 * @param context $context Context
220
 * @param string $filearea File area for data privacy
221
 * @param array $args Arguments
222
 * @param bool $forcedownload If we are forcing the download
223
 * @param array $options More options
224
 * @return bool Returns false if we don't find a file.
225
 */
226
function tool_dataprivacy_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = array()) {
227
    if ($context->contextlevel == CONTEXT_USER) {
228
        // Make sure the user is logged in.
229
        require_login(null, false);
230
 
231
        // Get the data request ID. This should be the first element of the $args array.
232
        $itemid = $args[0];
233
        // Fetch the data request object. An invalid ID will throw an exception.
234
        $datarequest = new \tool_dataprivacy\data_request($itemid);
235
 
236
        // Check if user is allowed to download it.
237
        if (!\tool_dataprivacy\api::can_download_data_request_for_user($context->instanceid, $datarequest->get('requestedby'))) {
238
            return false;
239
        }
240
 
241
        // Make the file unavailable if it has expired.
242
        if (\tool_dataprivacy\data_request::is_expired($datarequest)) {
243
            send_file_not_found();
244
        }
245
 
246
        // All good. Serve the exported data.
247
        $fs = get_file_storage();
248
        $relativepath = implode('/', $args);
249
        $fullpath = "/$context->id/tool_dataprivacy/$filearea/$relativepath";
250
        if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
251
            return false;
252
        }
253
        send_stored_file($file, 0, 0, $forcedownload, $options);
254
    } else {
255
        send_file_not_found();
256
    }
257
}
258
 
259
/**
260
 * Fragment to add a select course.
261
 *
262
 * @param array $args The fragment arguments.
263
 * @return string The rendered mform fragment.
264
 */
265
function tool_dataprivacy_output_fragment_selectcourses_form(array $args): string {
266
    $args = (object)$args;
267
 
268
    $context = context_system::instance();
269
    require_capability('tool/dataprivacy:managedatarequests', $context);
270
 
271
    if (!empty($args->jsonformdata)) {
272
        $serialiseddata = json_decode($args->jsonformdata);
273
    }
274
 
275
    $mform = new exportfilter_form(null, ['requestid' => $serialiseddata->requestid]);
276
 
277
    return $mform->render();
278
}