public function deployArchive(ContainerNodeInterface $containerNode, \SplFileInfo $archive)
{
try {
// create folder names based on the archive's basename
$tmpFolderName = new \SplFileInfo($this->getTmpDir($containerNode) . DIRECTORY_SEPARATOR . $archive->getFilename());
$webappFolderName = new \SplFileInfo($this->getWebappsDir($containerNode) . DIRECTORY_SEPARATOR . basename($archive->getFilename(), $this->getExtensionSuffix()));
// check if archive has not been deployed yet or failed sometime
if ($this->isDeployable($archive)) {
// flag webapp as deploying
$this->flagArchive($archive, ExtractorInterface::FLAG_DEPLOYING);
// backup actual webapp folder, if available
if ($webappFolderName->isDir()) {
// backup files that are NOT part of the archive
$this->backupArchive($containerNode, $archive);
// delete directories previously backed up
$this->removeDir($webappFolderName);
}
// remove old temporary directory
$this->removeDir($tmpFolderName);
// initialize a \Phar instance
$p = new \Phar($archive);
// create a recursive directory iterator
$iterator = new \RecursiveIteratorIterator($p);
// unify the archive filename, because Windows uses a \ instead of /
$archiveFilename = sprintf('phar://%s', str_replace(DIRECTORY_SEPARATOR, '/', $archive->getPathname()));
// iterate over all files
foreach ($iterator as $file) {
// prepare the temporary filename
$target = $tmpFolderName . str_replace($archiveFilename, '', $file->getPathname());
// create the directory if necessary
if (file_exists($directory = dirname($target)) === false) {
if (mkdir($directory, 0755, true) === false) {
throw new \Exception(sprintf('Can\'t create directory %s', $directory));
}
}
// finally copy the file
if (copy($file, $target) === false) {
throw new \Exception(sprintf('Can\'t copy %s file to %s', $file, $target));
}
}
// move extracted content to webapps folder and remove temporary directory
FileSystem::copyDir($tmpFolderName->getPathname(), $webappFolderName->getPathname());
FileSystem::removeDir($tmpFolderName->getPathname());
// we need to set the user/rights for the extracted folder
$this->setUserRights($webappFolderName);
// restore backup if available
$this->restoreBackup($containerNode, $archive);
// flag webapp as deployed
$this->flagArchive($archive, ExtractorInterface::FLAG_DEPLOYED);
// log a message that the application has successfully been deployed
$this->getInitialContext()->getSystemLogger()->info(sprintf('Application archive %s has succussfully been deployed', $archive->getBasename($this->getExtensionSuffix())));
}
} catch (\Exception $e) {
// log error
$this->getInitialContext()->getSystemLogger()->error($e->__toString());
// flag webapp as failed
$this->flagArchive($archive, ExtractorInterface::FLAG_FAILED);
}
}