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 * The definition of a set of files in a filearea to be exported. 19 * 20 * @package core 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 25 declare(strict_types=1); 26 27 namespace core\content\export\exportable_items; 28 29 use context; 30 use core\content\export\exportable_item; 31 use core\content\export\exported_item; 32 use core\content\export\zipwriter; 33 use moodle_url; 34 use stored_file; 35 36 /** 37 * The definition of a set of files in a filearea to be exported. 38 * 39 * All files mustbe in a single filearea and itemid combination. 40 * 41 * @copyright 2020 Andrew Nicols <andrew@nicols.co.uk> 42 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 43 */ 44 class exportable_filearea extends exportable_item { 45 46 /** @var string The destination path of the text content */ 47 protected $folderpath; 48 49 /** @var string $filearea The file to be exported */ 50 protected $filearea; 51 52 /** @var bool|int The itemid in the Files API */ 53 protected $itemid; 54 55 /** @var int The itemid to use in the pluginfile URL */ 56 protected $pluginfileitemid; 57 58 /** 59 * Create a new exportable_item instance. 60 * 61 * If no filearea or itemid is specified the no attempt will be made to export files. 62 * 63 * @param context $context The context that this content belongs to 64 * @param string $component 65 * @param string $uservisiblename The name displayed to the user when filtering 66 * @param string $filearea The file area in the Files API where these files are located 67 * @param int $itemid The itemid in the Files API where these files are located 68 * @param null|int $pluginfileitemid The itemid as used in the Pluginfile URL 69 * @param string $folderpath Any sub-directory to place files in 70 */ 71 public function __construct( 72 context $context, 73 string $component, 74 string $uservisiblename, 75 string $filearea, 76 int $itemid, 77 ?int $pluginfileitemid = null, 78 string $folderpath = '' 79 ) { 80 parent::__construct($context, $component, $uservisiblename); 81 82 $this->filearea = $filearea; 83 $this->itemid = $itemid; 84 $this->pluginfileitemid = $pluginfileitemid; 85 $this->folderpath = $folderpath; 86 } 87 88 /** 89 * Add the content to the archive. 90 * 91 * @param zipwriter $archive 92 */ 93 public function add_to_archive(zipwriter $archive): ?exported_item { 94 $fs = get_file_storage(); 95 96 $files = $fs->get_area_files($this->context->id, $this->component, $this->filearea, $this->itemid); 97 98 $exporteditem = new exported_item(); 99 $exporteditem->set_title($this->get_user_visible_name()); 100 101 foreach ($files as $file) { 102 if ($file->is_directory()) { 103 // Skip folders. The zipwriter cannot handle them. 104 continue; 105 } 106 // Export the content to [contextpath]/[filepath]. 107 $relativefilepath = $this->get_filepath_for_file($file); 108 109 $archive->add_file_from_stored_file( 110 $this->get_context(), 111 $relativefilepath, 112 $file 113 ); 114 115 if ($archive->is_file_in_archive($this->context, $relativefilepath)) { 116 // The file was successfully added to the archive. 117 $exporteditem->add_file($relativefilepath, false); 118 } else { 119 // The file was not added. Link to the live version instead. 120 $exporteditem->add_file( 121 $relativefilepath, 122 false, 123 self::get_pluginfile_url_for_stored_file($file, $this->pluginfileitemid) 124 ); 125 } 126 } 127 128 return $exporteditem; 129 } 130 131 /** 132 * Get the filepath for the specified stored_file. 133 * 134 * @param stored_file $file The file to get a filepath for 135 * @return string The generated filepath 136 */ 137 protected function get_filepath_for_file(stored_file $file): string { 138 $folderpath = rtrim($this->folderpath); 139 140 if (!empty($folderpath)) { 141 $folderpath .= '/'; 142 } 143 return sprintf( 144 '%s%s%s%s', 145 $folderpath, 146 $file->get_filearea(), 147 $file->get_filepath(), 148 $file->get_filename() 149 ); 150 } 151 152 /** 153 * Get the pluginfile URL for a stored file. 154 * 155 * Note: The itemid in the pluginfile may be omitted in some URLs, despite an itemid being present in the database. 156 * Equally, the itemid in the URL may not match the itemid in the files table. 157 * 158 * The pluginfileitemid argument provided to this function is the variant in the URL, and not the one in the files 159 * table. 160 * 161 * @param stored_file $file The file whose link will be generated 162 * @param null|int $pluginfileitemid The itemid of the file in pluginfile URL. 163 * 164 */ 165 protected static function get_pluginfile_url_for_stored_file(stored_file $file, ?int $pluginfileitemid): string { 166 $link = moodle_url::make_pluginfile_url( 167 $file->get_contextid(), 168 $file->get_component(), 169 $file->get_filearea(), 170 $pluginfileitemid, 171 $file->get_filepath(), 172 $file->get_filename(), 173 true, 174 true 175 ); 176 177 return $link->out(false); 178 } 179 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body