mirror of
https://github.com/moodle/moodle.git
synced 2025-03-13 20:26:32 +01:00
MDL-38509 Add new tool_installaddon_installer::extract_installfromzip_file() method
This commit is contained in:
parent
585b64a607
commit
07083b230b
@ -43,7 +43,7 @@ class tool_installaddon_installer {
|
||||
* @return tool_installaddon_installer
|
||||
*/
|
||||
public static function instance() {
|
||||
return new self();
|
||||
return new static();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -113,6 +113,37 @@ class tool_installaddon_installer {
|
||||
return $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the saved file previously saved by {self::save_installfromzip_file()}
|
||||
*
|
||||
* The list of files found in the ZIP is returned via $zipcontentfiles parameter
|
||||
* by reference. The format of that list is array of (string)filerelpath => (bool|string)
|
||||
* where the array value is either true or a string describing the problematic file.
|
||||
*
|
||||
* @see zip_packer::extract_to_pathname()
|
||||
* @param string $zipfilepath full path to the saved ZIP file
|
||||
* @param string $targetdir full path to the directory to extract the ZIP file to
|
||||
* @param string $rootdir explicitly rename the root directory of the ZIP into this non-empty value
|
||||
* @param array list of extracted files as returned by {@link zip_packer::extract_to_pathname()}
|
||||
*/
|
||||
public function extract_installfromzip_file($zipfilepath, $targetdir, $rootdir = '') {
|
||||
global $CFG;
|
||||
require_once($CFG->libdir.'/filelib.php');
|
||||
|
||||
$fp = get_file_packer('application/zip');
|
||||
$files = $fp->extract_to_pathname($zipfilepath, $targetdir);
|
||||
|
||||
if ($files) {
|
||||
if (!empty($rootdir)) {
|
||||
$files = $this->rename_extracted_rootdir($targetdir, $rootdir, $files);
|
||||
}
|
||||
return $files;
|
||||
|
||||
} else {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns localised list of available plugin types
|
||||
*
|
||||
@ -185,6 +216,12 @@ class tool_installaddon_installer {
|
||||
|
||||
//// End of external API ///////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @see self::instance()
|
||||
*/
|
||||
protected function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string this site full name
|
||||
*/
|
||||
@ -235,4 +272,56 @@ class tool_installaddon_installer {
|
||||
protected function should_send_site_info() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames the root directory of the extracted ZIP package.
|
||||
*
|
||||
* This method does not validate the presence of the single root directory
|
||||
* (the validator does it later). It just searches for the first directory
|
||||
* under the given location and renames it.
|
||||
*
|
||||
* The method will not rename the root if the requested location already
|
||||
* exists.
|
||||
*
|
||||
* @param string $dirname the location of the extracted ZIP package
|
||||
* @param string $rootdir the requested name of the root directory
|
||||
* @param array $files list of extracted files
|
||||
* @return array eventually amended list of extracted files
|
||||
*/
|
||||
protected function rename_extracted_rootdir($dirname, $rootdir, array $files) {
|
||||
|
||||
if (!is_dir($dirname)) {
|
||||
debugging('Unable to rename rootdir of non-existing content', DEBUG_DEVELOPER);
|
||||
return $files;
|
||||
}
|
||||
|
||||
if (file_exists($dirname.'/'.$rootdir)) {
|
||||
debugging('Unable to rename rootdir to already existing folder', DEBUG_DEVELOPER);
|
||||
return $files;
|
||||
}
|
||||
|
||||
$found = null; // The name of the first subdirectory under the $dirname.
|
||||
foreach (scandir($dirname) as $item) {
|
||||
if (substr($item, 0, 1) === '.') {
|
||||
continue;
|
||||
}
|
||||
if (is_dir($dirname.'/'.$item)) {
|
||||
$found = $item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_null($found)) {
|
||||
if (rename($dirname.'/'.$found, $dirname.'/'.$rootdir)) {
|
||||
$newfiles = array();
|
||||
foreach ($files as $filepath => $status) {
|
||||
$newpath = preg_replace('~^'.preg_quote($found.'/').'~', preg_quote($rootdir.'/'), $filepath);
|
||||
$newfiles[$newpath] = $status;
|
||||
}
|
||||
return $newfiles;
|
||||
}
|
||||
}
|
||||
|
||||
return $files;
|
||||
}
|
||||
}
|
||||
|
BIN
admin/tool/installaddon/tests/fixtures/zips/invalidroot.zip
vendored
Normal file
BIN
admin/tool/installaddon/tests/fixtures/zips/invalidroot.zip
vendored
Normal file
Binary file not shown.
@ -39,7 +39,7 @@ require_once($CFG->dirroot.'/'.$CFG->admin.'/tool/installaddon/classes/installer
|
||||
class tool_installaddon_installer_test extends advanced_testcase {
|
||||
|
||||
public function test_get_addons_repository_url() {
|
||||
$installer = new testable_tool_installaddon_installer();
|
||||
$installer = testable_tool_installaddon_installer::instance();
|
||||
$url = $installer->get_addons_repository_url();
|
||||
$query = parse_url($url, PHP_URL_QUERY);
|
||||
$this->assertEquals(1, preg_match('~^site=(.+)$~', $query, $matches));
|
||||
@ -51,6 +51,29 @@ class tool_installaddon_installer_test extends advanced_testcase {
|
||||
$this->assertSame($installer->get_site_url(), $site['url']);
|
||||
$this->assertSame($installer->get_site_major_version(), $site['major_version']);
|
||||
}
|
||||
|
||||
public function test_extract_installfromzip_file() {
|
||||
$jobid = md5(rand().uniqid('test_', true));
|
||||
$sourcedir = make_temp_directory('tool_installaddon/'.$jobid.'/source');
|
||||
$contentsdir = make_temp_directory('tool_installaddon/'.$jobid.'/contents');
|
||||
copy(dirname(__FILE__).'/fixtures/zips/invalidroot.zip', $sourcedir.'/testinvalidroot.zip');
|
||||
|
||||
$installer = tool_installaddon_installer::instance();
|
||||
$files = $installer->extract_installfromzip_file($sourcedir.'/testinvalidroot.zip', $contentsdir, 'fixed_root');
|
||||
$this->assertEquals('array', gettype($files));
|
||||
$this->assertEquals(4, count($files));
|
||||
$this->assertSame(true, $files['fixed_root/']);
|
||||
$this->assertSame(true, $files['fixed_root/lang/']);
|
||||
$this->assertSame(true, $files['fixed_root/lang/en/']);
|
||||
$this->assertSame(true, $files['fixed_root/lang/en/fixed_root.php']);
|
||||
foreach ($files as $file => $status) {
|
||||
if (substr($file, -1) === '/') {
|
||||
$this->assertTrue(is_dir($contentsdir.'/'.$file));
|
||||
} else {
|
||||
$this->assertTrue(is_file($contentsdir.'/'.$file));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user