Differences Between: [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403]
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 * Content API File Area definition. 19 * 20 * @package core_files 21 * @copyright 2020 Andrew Nicols <andrew@nicols.co.uk> 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 namespace core; 25 26 use coding_exception; 27 use context; 28 use core\content\export\exporters\course_exporter; 29 use core\content\export\exporters\component_exporter; 30 use core\content\export\exporters\abstract_mod_exporter; 31 use core\content\export\zipwriter; 32 use core_component; 33 use moodle_url; 34 use stdClass; 35 use stored_file; 36 37 /** 38 * The Content API allows all parts of Moodle to determine details about content within a component, or plugintype. 39 * 40 * This includes the description of files. 41 * 42 * @copyright 2020 Andrew Nicols <andrew@nicols.co.uk> 43 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 44 */ 45 class content { 46 47 /** 48 * Check whether the specified user can export content for the specified context. 49 * 50 * @param context $currentcontext 51 * @param stdClass $user 52 * @return bool 53 */ 54 public static function can_export_context(context $currentcontext, stdClass $user): bool { 55 global $CFG; 56 57 $canexport = false; 58 59 if ($currentcontext->contextlevel == CONTEXT_COURSE) { 60 if ($CFG->downloadcoursecontentallowed && 61 has_capability('moodle/course:downloadcoursecontent', $currentcontext, $user)) { 62 63 $courseinfo = get_fast_modinfo($currentcontext->instanceid)->get_course(); 64 65 // If enabled/disabled explicitly set on course, use that as the course setting, otherwise use site default. 66 if (isset($courseinfo->downloadcontent) && $courseinfo->downloadcontent != DOWNLOAD_COURSE_CONTENT_SITE_DEFAULT) { 67 $canexport = $courseinfo->downloadcontent; 68 } else { 69 $canexport = get_config('moodlecourse')->downloadcontentsitedefault; 70 } 71 72 } 73 } else if ($currentcontext->contextlevel == CONTEXT_MODULE) { 74 // Modules can only be exported if exporting is allowed in their course context. 75 $canexport = self::can_export_context($currentcontext->get_course_context(), $user); 76 } 77 78 return $canexport; 79 } 80 81 /** 82 * Export content for the specified context. 83 * 84 * @param context $requestedcontext The context to be exported 85 * @param stdClass $user The user being exported 86 * @param zipwriter $archive The Zip Archive to export to 87 */ 88 public static function export_context(context $requestedcontext, stdClass $user, zipwriter $archive): void { 89 global $USER; 90 91 if ($requestedcontext->contextlevel != CONTEXT_COURSE) { 92 throw new coding_exception('The Content Export API currently only supports the export of courses'); 93 } 94 95 if ($USER->id != $user->id) { 96 throw new coding_exception('The Content Export API currently only supports export of the current user'); 97 } 98 99 // Ensure that the zipwriter is aware of the requested context. 100 $archive->set_root_context($requestedcontext); 101 102 // Fetch all child contexts, indexed by path. 103 $contextlist = [ 104 $requestedcontext->path => $requestedcontext, 105 ]; 106 foreach ($requestedcontext->get_child_contexts() as $context) { 107 $contextlist[$context->path] = $context; 108 } 109 110 // Reverse the order by key - this ensures that child contexts are processed before their parent. 111 krsort($contextlist); 112 113 // Get the course modinfo. 114 $modinfo = get_fast_modinfo($requestedcontext->instanceid); 115 116 // Filter out any context which cannot be exported. 117 $contextlist = array_filter($contextlist, function($context) use ($user, $modinfo): bool { 118 if ($context->contextlevel == CONTEXT_COURSE) { 119 return self::can_export_context($context, $user); 120 } 121 122 if ($context->contextlevel == CONTEXT_MODULE) { 123 if (empty($modinfo->cms[$context->instanceid])) { 124 // Unknown coursemodule in the course. 125 return false; 126 } 127 128 $cm = $modinfo->cms[$context->instanceid]; 129 130 if (!$cm->uservisible) { 131 // This user cannot view the activity. 132 return false; 133 } 134 135 // Defer to setting checks. 136 return self::can_export_context($context, $user); 137 } 138 139 // Only course and activities are supported at this time. 140 return false; 141 }); 142 143 // Export each context. 144 $exportedcontexts = []; 145 $coursecontroller = new course_exporter($requestedcontext->get_course_context(), $user, $archive); 146 foreach ($contextlist as $context) { 147 if ($context->contextlevel === CONTEXT_MODULE) { 148 $cm = $modinfo->cms[$context->instanceid]; 149 $component = "mod_{$cm->modname}"; 150 151 // Check for a specific implementation for this module. 152 // This will export any content specific to this activity. 153 // For example, in mod_folder it will export the list of folders. 154 $classname = component_exporter::get_classname_for_component($component); 155 $exportables = []; 156 if (class_exists($classname) && is_a($classname, abstract_mod_exporter::class, true)) { 157 $controller = new $classname($context, $component, $user, $archive); 158 $exportables = $controller->get_exportables(); 159 } 160 161 // Pass the exportable content to the course controller for export. 162 $coursecontroller->export_mod_content($context, $exportables); 163 164 $exportedcontexts[$context->id] = $context; 165 } else if ($context->contextlevel === CONTEXT_COURSE) { 166 // Export the course content. 167 $coursecontroller->export_course($exportedcontexts); 168 } 169 } 170 171 $archive->finish(); 172 } 173 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body