Skip to content

Commit

Permalink
Added library compression to speed up export on high latency file sys…
Browse files Browse the repository at this point in the history
…tems
  • Loading branch information
Peterburnett committed Nov 25, 2020
1 parent 4385320 commit 03b82c4
Showing 1 changed file with 75 additions and 15 deletions.
90 changes: 75 additions & 15 deletions classes/file_storage.php
Original file line number Diff line number Diff line change
Expand Up @@ -494,30 +494,71 @@ public function removeContentFile($file, $content) {
* Path to source directory
* @param array $options
* For Moodle's file record
* @param \ZipArchive $archive
* A currently open archive to store complete libraries. Used in recursive calls.
* @param string $relativepath
* The current relative path from the base function call. Used in recursive calls.
*
* @throws \Exception Unable to copy
*/
// @codingStandardsIgnoreLine
private static function readFileTree($source, $options) {
private static function readFileTree($source, $options, $archive = null, $relativepath = '') {
$dir = opendir($source);
if ($dir === false) {
trigger_error('Unable to open directory ' . $source, E_USER_WARNING);
throw new \Exception('unabletocopy');
}

// Create an empty zip to store a full lib archive as well.
if (empty($archive)) {
$archive = new \ZipArchive();
$path = tempnam(get_request_storage_directory(),'libdir');
$archive->open($path, \ZipArchive::CREATE || \ZipArchive::OVERWRITE);
// Set recursion flag.
$top = true;
} else {
$top = false;
}

while (false !== ($file = readdir($dir))) {
if (($file != '.') && ($file != '..') && $file != '.git' && $file != '.gitignore') {
if (is_dir($source . DIRECTORY_SEPARATOR . $file)) {
$suboptions = $options;
$suboptions['filepath'] .= $file . '/';
self::readFileTree($source . '/' . $file, $suboptions);
$pathchunk = $file . '/';
$suboptions['filepath'] .= $pathchunk;

// Setup the relative path from the root dir.
$origpath = $relativepath;
$relativepath = !empty($relativepath) ? $relativepath . $pathchunk : $pathchunk;
self::readFileTree($source . '/' . $file, $suboptions, $archive, $relativepath);
// Reset path after recursing.
$relativepath = $origpath;
} else {
$record = $options;
$record['filename'] = $file;
$fs = get_file_storage();
$fs->create_file_from_pathname($record, $source . '/' . $file);

$zippath = !empty($relativepath) ? $relativepath . $file : $file;
// Also add file to open archive.
$archive->addFile($source . '/' . $file, $zippath);
}
}
}

// Store the zipfile alongside the lib files.
if ($top) {
if (empty($fs)) {
$fs = get_file_storage();
}
$record = $options;
$record['filearea'] = 'library-archives';
$record['filename'] = 'lib-export.zip';
$archive->close();
$fs->create_file_from_pathname($record, $path);
unlink($path);
}

closedir($dir);
}

Expand Down Expand Up @@ -546,19 +587,38 @@ private static function exportFileTree($target, $contextid, $filearea, $filepath
$fs = get_file_storage();
$files = $fs->get_directory_files($contextid, 'mod_hvp', $filearea, $itemid, $filepath, true);

foreach ($files as $file) {
// Correct target path for file.
$path = $target . str_replace($filepath, '/', $file->get_filepath());

if ($file->is_directory()) {
// Create directory.
$path = rtrim($path, '/');
if (!file_exists($path)) {
mkdir($path, 0777, true);
if ($filearea === 'libraries' && $file = $fs->get_file(
$contextid,
'mod_hvp',
'library-archives',
$itemid,
$filepath,
'lib-export.zip'
)) {
// Libraries may have a precompiled zip to extract(
$temppath = $file->copy_content_to_temp();

// Extract the archive to the required dir.
$zip = new \ZipArchive();
$zip->open($temppath);
$zip->extractTo($target);
$zip->close();
unlink($temppath);
} else {
foreach ($files as $file) {
// Correct target path for file.
$path = $target . str_replace($filepath, '/', $file->get_filepath());

if ($file->is_directory()) {
// Create directory.
$path = rtrim($path, '/');
if (!file_exists($path)) {
mkdir($path, 0777, true);
}
} else {
// Copy file.
$file->copy_content_to($path . $file->get_filename());
}
} else {
// Copy file.
$file->copy_content_to($path . $file->get_filename());
}
}
}
Expand Down

0 comments on commit 03b82c4

Please sign in to comment.