Commit | Line | Data |
---|---|---|
5efc1f9e DM |
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 | ||
26 | defined('MOODLE_INTERNAL') || die(); | |
27 | ||
28 | /** | |
29 | * Add nodes to myprofile page. | |
30 | * | |
31 | * @param tree $tree Tree object | |
32 | * @param stdClass $user User object | |
33 | * @param bool $iscurrentuser | |
34 | * @param stdClass $course Course object | |
35 | * @return bool | |
36 | * @throws coding_exception | |
37 | * @throws dml_exception | |
38 | * @throws moodle_exception | |
39 | */ | |
40 | function tool_dataprivacy_myprofile_navigation(tree $tree, $user, $iscurrentuser, $course) { | |
41 | global $PAGE, $USER; | |
42 | ||
43 | // Get the Privacy and policies category. | |
44 | if (!array_key_exists('privacyandpolicies', $tree->__get('categories'))) { | |
45 | // Create the category. | |
46 | $categoryname = get_string('privacyandpolicies', 'admin'); | |
47 | $category = new core_user\output\myprofile\category('privacyandpolicies', $categoryname, 'contact'); | |
48 | $tree->add_category($category); | |
49 | } else { | |
50 | // Get the existing category. | |
51 | $category = $tree->__get('categories')['privacyandpolicies']; | |
52 | } | |
53 | ||
54 | // Contact data protection officer link. | |
55 | if (\tool_dataprivacy\api::can_contact_dpo() && $iscurrentuser) { | |
56 | $renderer = $PAGE->get_renderer('tool_dataprivacy'); | |
57 | $content = $renderer->render_contact_dpo_link($USER->email); | |
58 | $node = new core_user\output\myprofile\node('privacyandpolicies', 'contactdpo', null, null, null, $content); | |
59 | $category->add_node($node); | |
60 | $PAGE->requires->js_call_amd('tool_dataprivacy/myrequestactions', 'init'); | |
61 | ||
62 | $url = new moodle_url('/admin/tool/dataprivacy/mydatarequests.php'); | |
63 | $node = new core_user\output\myprofile\node('privacyandpolicies', 'datarequests', | |
64 | get_string('datarequests', 'tool_dataprivacy'), null, $url); | |
65 | $category->add_node($node); | |
66 | } | |
67 | ||
68 | // Add the Privacy category to the tree if it's not empty and it doesn't exist. | |
69 | $nodes = $category->nodes; | |
70 | if (!empty($nodes)) { | |
71 | if (!array_key_exists('privacyandpolicies', $tree->__get('categories'))) { | |
72 | $tree->add_category($category); | |
73 | } | |
74 | return true; | |
75 | } | |
76 | ||
77 | return false; | |
78 | } | |
79 | ||
80 | /** | |
81 | * Fragment to add a new purpose. | |
82 | * | |
83 | * @param array $args The fragment arguments. | |
84 | * @return string The rendered mform fragment. | |
85 | */ | |
86 | function tool_dataprivacy_output_fragment_addpurpose_form($args) { | |
87 | ||
88 | $formdata = []; | |
89 | if (!empty($args['jsonformdata'])) { | |
90 | $serialiseddata = json_decode($args['jsonformdata']); | |
91 | parse_str($serialiseddata, $formdata); | |
92 | } | |
93 | ||
94 | $persistent = new \tool_dataprivacy\purpose(); | |
95 | $mform = new \tool_dataprivacy\form\purpose(null, ['persistent' => $persistent], | |
96 | 'post', '', null, true, $formdata); | |
97 | ||
98 | if (!empty($args['jsonformdata'])) { | |
99 | // Show errors if data was received. | |
100 | $mform->is_validated(); | |
101 | } | |
102 | ||
103 | return $mform->render(); | |
104 | } | |
105 | ||
106 | /** | |
107 | * Fragment to add a new category. | |
108 | * | |
109 | * @param array $args The fragment arguments. | |
110 | * @return string The rendered mform fragment. | |
111 | */ | |
112 | function tool_dataprivacy_output_fragment_addcategory_form($args) { | |
113 | ||
114 | $formdata = []; | |
115 | if (!empty($args['jsonformdata'])) { | |
116 | $serialiseddata = json_decode($args['jsonformdata']); | |
117 | parse_str($serialiseddata, $formdata); | |
118 | } | |
119 | ||
120 | $persistent = new \tool_dataprivacy\category(); | |
121 | $mform = new \tool_dataprivacy\form\category(null, ['persistent' => $persistent], | |
122 | 'post', '', null, true, $formdata); | |
123 | ||
124 | if (!empty($args['jsonformdata'])) { | |
125 | // Show errors if data was received. | |
126 | $mform->is_validated(); | |
127 | } | |
128 | ||
129 | return $mform->render(); | |
130 | } | |
131 | ||
132 | /** | |
133 | * Fragment to edit a context purpose and category. | |
134 | * | |
135 | * @param array $args The fragment arguments. | |
136 | * @return string The rendered mform fragment. | |
137 | */ | |
138 | function tool_dataprivacy_output_fragment_context_form($args) { | |
139 | global $PAGE; | |
140 | ||
141 | $contextid = $args[0]; | |
142 | ||
143 | $context = \context_helper::instance_by_id($contextid); | |
144 | $customdata = \tool_dataprivacy\form\context_instance::get_context_instance_customdata($context); | |
145 | ||
146 | if (!empty($customdata['purposeretentionperiods'])) { | |
a8a69050 DM |
147 | $PAGE->requires->js_call_amd('tool_dataprivacy/effective_retention_period', 'init', |
148 | [$customdata['purposeretentionperiods']]); | |
5efc1f9e DM |
149 | } |
150 | $mform = new \tool_dataprivacy\form\context_instance(null, $customdata); | |
151 | return $mform->render(); | |
152 | } | |
153 | ||
154 | /** | |
155 | * Fragment to edit a contextlevel purpose and category. | |
156 | * | |
157 | * @param array $args The fragment arguments. | |
158 | * @return string The rendered mform fragment. | |
159 | */ | |
160 | function tool_dataprivacy_output_fragment_contextlevel_form($args) { | |
161 | global $PAGE; | |
162 | ||
163 | $contextlevel = $args[0]; | |
164 | $customdata = \tool_dataprivacy\form\contextlevel::get_contextlevel_customdata($contextlevel); | |
165 | ||
166 | if (!empty($customdata['purposeretentionperiods'])) { | |
a8a69050 DM |
167 | $PAGE->requires->js_call_amd('tool_dataprivacy/effective_retention_period', 'init', |
168 | [$customdata['purposeretentionperiods']]); | |
5efc1f9e DM |
169 | } |
170 | ||
171 | $mform = new \tool_dataprivacy\form\contextlevel(null, $customdata); | |
172 | return $mform->render(); | |
173 | } | |
174 | ||
175 | /** | |
176 | * Serves any files associated with the data privacy settings. | |
177 | * | |
178 | * @param stdClass $course Course object | |
179 | * @param stdClass $cm Course module object | |
180 | * @param context $context Context | |
181 | * @param string $filearea File area for data privacy | |
182 | * @param array $args Arguments | |
183 | * @param bool $forcedownload If we are forcing the download | |
184 | * @param array $options More options | |
185 | * @return bool Returns false if we don't find a file. | |
186 | */ | |
187 | function tool_dataprivacy_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = array()) { | |
cb775057 JP |
188 | global $USER; |
189 | ||
5efc1f9e | 190 | if ($context->contextlevel == CONTEXT_USER) { |
cb775057 JP |
191 | // Make sure the user is logged in. |
192 | require_login(null, false); | |
193 | ||
194 | // Validate the user downloading this archive. | |
195 | $usercontext = context_user::instance($USER->id); | |
196 | // The user downloading this is not the user the archive has been prepared for. Check if it's the requester (e.g. parent). | |
197 | if ($usercontext->instanceid !== $context->instanceid) { | |
198 | // Get the data request ID. This should be the first element of the $args array. | |
199 | $itemid = $args[0]; | |
200 | // Fetch the data request object. An invalid ID will throw an exception. | |
201 | $datarequest = new \tool_dataprivacy\data_request($itemid); | |
202 | ||
203 | // Check if the user is the requester and has the capability to make data requests for the target user. | |
204 | $candownloadforuser = has_capability('tool/dataprivacy:makedatarequestsforchildren', $context); | |
205 | if ($USER->id != $datarequest->get('requestedby') || !$candownloadforuser) { | |
206 | return false; | |
207 | } | |
208 | } | |
209 | ||
210 | // All good. Serve the exported data. | |
5efc1f9e DM |
211 | $fs = get_file_storage(); |
212 | $relativepath = implode('/', $args); | |
213 | $fullpath = "/$context->id/tool_dataprivacy/$filearea/$relativepath"; | |
214 | if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { | |
215 | return false; | |
216 | } | |
217 | send_stored_file($file, 0, 0, $forcedownload, $options); | |
218 | } else { | |
219 | send_file_not_found(); | |
220 | } | |
221 | } |