See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401]
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 $cm = get_fast_modinfo($currentcontext->get_course_context()->instanceid)->cms[$currentcontext->instanceid]; 75 76 // Do not export course content if disabled at activity level. 77 if (isset($cm->downloadcontent) && $cm->downloadcontent == DOWNLOAD_COURSE_CONTENT_DISABLED) { 78 return false; 79 } 80 81 // Modules can only be exported if exporting is allowed in their course context. 82 $canexport = self::can_export_context($currentcontext->get_course_context(), $user); 83 } 84 85 return $canexport; 86 } 87 88 /** 89 * Export content for the specified context. 90 * 91 * @param context $requestedcontext The context to be exported 92 * @param stdClass $user The user being exported 93 * @param zipwriter $archive The Zip Archive to export to 94 */ 95 public static function export_context(context $requestedcontext, stdClass $user, zipwriter $archive): void { 96 global $USER; 97 98 if ($requestedcontext->contextlevel != CONTEXT_COURSE) { 99 throw new coding_exception('The Content Export API currently only supports the export of courses'); 100 } 101 102 if ($USER->id != $user->id) { 103 throw new coding_exception('The Content Export API currently only supports export of the current user'); 104 } 105 106 // Ensure that the zipwriter is aware of the requested context. 107 $archive->set_root_context($requestedcontext); 108 109 // Fetch all child contexts, indexed by path. 110 $contextlist = [ 111 $requestedcontext->path => $requestedcontext, 112 ]; 113 foreach ($requestedcontext->get_child_contexts() as $context) { 114 $contextlist[$context->path] = $context; 115 } 116 117 // Reverse the order by key - this ensures that child contexts are processed before their parent. 118 krsort($contextlist); 119 120 // Get the course modinfo. 121 $modinfo = get_fast_modinfo($requestedcontext->instanceid); 122 123 // Filter out any context which cannot be exported. 124 $contextlist = array_filter($contextlist, function($context) use ($user, $modinfo): bool { 125 if ($context->contextlevel == CONTEXT_COURSE) { 126 return self::can_export_context($context, $user); 127 } 128 129 if ($context->contextlevel == CONTEXT_MODULE) { 130 if (empty($modinfo->cms[$context->instanceid])) { 131 // Unknown coursemodule in the course. 132 return false; 133 } 134 135 $cm = $modinfo->cms[$context->instanceid]; 136 137 if (!$cm->uservisible) { 138 // This user cannot view the activity. 139 return false; 140 } 141 142 // Defer to setting checks. 143 return self::can_export_context($context, $user); 144 } 145 146 // Only course and activities are supported at this time. 147 return false; 148 }); 149 150 // Export each context. 151 $exportedcontexts = []; 152 $coursecontroller = new course_exporter($requestedcontext->get_course_context(), $user, $archive); 153 foreach ($contextlist as $context) { 154 if ($context->contextlevel === CONTEXT_MODULE) { 155 $cm = $modinfo->cms[$context->instanceid]; 156 $component = "mod_{$cm->modname}"; 157 158 // Check for a specific implementation for this module. 159 // This will export any content specific to this activity. 160 // For example, in mod_folder it will export the list of folders. 161 $classname = component_exporter::get_classname_for_component($component); 162 $exportables = []; 163 if (class_exists($classname) && is_a($classname, abstract_mod_exporter::class, true)) { 164 $controller = new $classname($context, $component, $user, $archive); 165 $exportables = $controller->get_exportables(); 166 } 167 168 // Pass the exportable content to the course controller for export. 169 $coursecontroller->export_mod_content($context, $exportables); 170 171 $exportedcontexts[$context->id] = $context; 172 } else if ($context->contextlevel === CONTEXT_COURSE) { 173 // Export the course content. 174 $coursecontroller->export_course($exportedcontexts); 175 } 176 } 177 178 $archive->finish(); 179 } 180 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body