/**
* Unpacks a file and verifies it as a Joomla element package
* Supports .gz .tar .tar.gz and .zip
*
* @param string $packageFilename The uploaded package filename or install directory
* @param boolean $alwaysReturnArray If should return false (and leave garbage behind) or return $retval['type']=false
*
* @return array|boolean Array on success or boolean false on failure
*
* @since 3.1
*/
public static function unpack($packageFilename, $alwaysReturnArray = false)
{
// Path to the archive
$archivename = $packageFilename;
// Temporary folder to extract the archive into
$tmpdir = uniqid('install_');
// Clean the paths to use for archive extraction
$extractdir = Path::clean(\dirname($packageFilename) . '/' . $tmpdir);
$archivename = Path::clean($archivename);
// Do the unpacking of the archive
try {
$archive = new Archive(array('tmp_path' => Factory::getApplication()->get('tmp_path')));
$extract = $archive->extract($archivename, $extractdir);
} catch (\Exception $e) {
if ($alwaysReturnArray) {
return array('extractdir' => null, 'packagefile' => $archivename, 'type' => false);
}
return false;
}
if (!$extract) {
if ($alwaysReturnArray) {
return array('extractdir' => null, 'packagefile' => $archivename, 'type' => false);
}
return false;
}
/*
* Let's set the extraction directory and package file in the result array so we can
* cleanup everything properly later on.
*/
$retval['extractdir'] = $extractdir;
$retval['packagefile'] = $archivename;
/*
* Try to find the correct install directory. In case the package is inside a
* subdirectory detect this and set the install directory to the correct path.
*
* List all the items in the installation directory. If there is only one, and
* it is a folder, then we will set that folder to be the installation folder.
*/
$dirList = array_merge((array) Folder::files($extractdir, ''), (array) Folder::folders($extractdir, ''));
if (\count($dirList) === 1) {
if (Folder::exists($extractdir . '/' . $dirList[0])) {
$extractdir = Path::clean($extractdir . '/' . $dirList[0]);
}
}
/*
* We have found the install directory so lets set it and then move on
* to detecting the extension type.
*/
$retval['dir'] = $extractdir;
/*
* Get the extension type and return the directory/type array on success or
* false on fail.
*/
$retval['type'] = self::detectType($extractdir);
if ($alwaysReturnArray || $retval['type']) {
return $retval;
} else {
return false;
}
}