Commit 9b599d3f authored by Richard Mansfield's avatar Richard Mansfield
Browse files

Display progress bar during unzip


Signed-off-by: default avatarRichard Mansfield <richardm@catalyst.net.nz>
parent 03667644
<?php
/**
* Mahara: Electronic portfolio, weblog, resume builder and social networking
* Copyright (C) 2006-2009 Catalyst IT Ltd and others; see:
* http://wiki.mahara.org/Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package mahara
* @subpackage artefact-file
* @author Catalyst IT Ltd
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL
* @copyright (C) 2006-2009 Catalyst IT Ltd http://catalyst.net.nz
*
*/
define('INTERNAL', 1);
require(dirname(dirname(dirname(__FILE__))) . '/init.php');
safe_require('artefact', 'file');
if (!$unzip = $SESSION->get('unzip')) {
redirect('/artefact/file/');
}
$stylesheets = array_reverse($THEME->get_url('style/style.css', true));
?>
<html>
<head>
<title></title>
<?php foreach ($stylesheets as $stylesheet) { ?>
<link rel="stylesheet" type="text/css" href="<?php echo hsc($stylesheet); ?>">
<?php } ?>
<style type="text/css">
html, body {
margin: 0;
padding: 0;
background-color: #808080;
}
</style>
</head>
<body>
<div style="width: 100%; background-color: #808080;" class="progress-bar"></div>
<p class="progress-text"><?php echo get_string('unzipprogress', 'artefact.file', '0/' . $unzip['artefacts']); ?></p>
<?php
flush();
/**
* Progress bar update
*
* @param int $artefacts How many artefacts have been created
*/
function unzip_iframe_progress_handler($artefacts) {
global $unzip;
$percent = $artefacts / $unzip['artefacts'] * 100;
$status = get_string('unzipprogress', 'artefact.file', $artefacts . '/' . $unzip['artefacts']);
// "Erase" the current output with a new background div
echo '<div style="width: 100%; background-color: #808080;" class="progress-bar"></div>';
// The progress bar itself
echo '<div class="progress-bar" style="width: ' . intval($percent) . '%;"></div>' . "\n";
// The status text
echo '<p class="progress-text">' . hsc($status) . "</p>\n";
flush();
}
$file = artefact_instance_from_id($unzip['file']);
$status = $file->unzip('unzip_iframe_progress_handler');
$next = $unzip['from'];
$next .= (strpos($next, '?') === false ? '?' : '&') . 'folder=' . $status->basefolderid;
$SESSION->set('unzip', false);
$message = get_string('extractfilessuccess', 'artefact.file', $status->folders, $status->files);
?>
<div class="progress-bar" style="width: 100%;">
<p><?php echo $message; ?> <a href="<?php echo $next; ?>" target="_top"><?php echo get_string('Continue', 'artefact.file'); ?></a></p>
</div>
</body>
</html>
......@@ -69,11 +69,11 @@ if ($fileid) {
if (!is_resource($zip)) {
throw new NotFoundException();
}
$zipinfo = zip_file_info($zip);
$zipinfo = ArtefactTypeArchive::zip_file_info($zip);
zip_close($zip);
if (!$file->get('owner') || $USER->quota_allowed($zipinfo->totalsize)) {
$name = get_unzip_directory_name($file);
$name = ArtefactTypeArchive::get_unzip_directory_name($file);
$message = get_string('fileswillbeextractedintofolder', 'artefact.file', $name['fullname']);
$goto = files_page($file);
......@@ -109,43 +109,6 @@ if ($fileid) {
$smarty->display('artefact:file:extract.tpl');
}
function zip_file_info($zip) {
$info = (object) array(
'files' => 0,
'folders' => 0,
'totalsize' => 0,
'names' => array(),
);
while ($entry = zip_read($zip)) {
$name = zip_entry_name($entry);
$info->names[] = $name;
if (substr($name, -1) == '/') {
$info->folders++;
}
else {
$info->files++;
if ($size = zip_entry_filesize($entry)) {
$info->totalsize += $size;
}
}
}
$info->displaysize = ArtefactTypeFile::short_size($info->totalsize);
return $info;
}
function get_unzip_directory_name($file) {
$folderdata = ArtefactTypeFileBase::artefactchooser_folder_data($file);
$parent = $file->get('parent');
$strpath = ArtefactTypeFileBase::get_full_path($parent, $folderdata->data);
$extn = $file->get('oldextension');
$name = $file->get('title');
if (substr($name, -1-strlen($extn)) == '.' . $extn) {
$name = substr($name, 0, strlen($name)-1-strlen($extn));
}
$name = ArtefactTypeFileBase::get_new_file_title($name, $parent, $file->get('owner'), $file->get('group'), $file->get('institution'));
return array('basename' => $name, 'fullname' => $strpath . $name);
}
function files_page($file) {
$url = get_config('wwwroot') . 'artefact/file/';
if ($owner = $file->get('owner')) {
......@@ -166,61 +129,21 @@ function files_page($file) {
}
function unzip_artefact_submit(Pieform $form, $values) {
global $file, $USER, $SESSION;
$foldername = get_unzip_directory_name($file);
$foldername = $foldername['basename'];
global $file, $zipinfo, $SESSION;
$data = (object) array(
'owner' => $file->get('owner'),
'group' => $file->get('group'),
'institution' => $file->get('institution'),
'title' => $foldername,
'description' => get_string('filesextractedfromziparchive', 'artefact.file'),
'parent' => $file->get('parent'),
);
$from = files_page($file);
$user = $data->owner ? $USER : null;
$basefolder = new ArtefactTypeFolder(0, $data);
$basefolder->commit();
$folders = array('.' => $basefolder->get('id'));
$created = (object) array('folders' => 1, 'files' => 0);
unset($data->description);
$tempdir = get_config('dataroot') . 'artefact/file/temp';
check_dir_exists($tempdir);
$zip = zip_open($file->get_path());
$tempfile = tempnam($tempdir, '');
while ($entry = zip_read($zip)) {
$name = zip_entry_name($entry);
$folder = dirname($name);
$data->title = basename($name);
$data->parent = $folders[$folder];
if (substr($name, -1) == '/') {
$newfolder = new ArtefactTypeFolder(0, $data);
$newfolder->commit();
$created->folders++;
$folderindex = ($folder == '.' ? '' : ($folder . '/')) . $data->title;
$folders[$folderindex] = $newfolder->get('id');
}
else {
$h = fopen($tempfile, 'w');
$size = zip_entry_filesize($entry);
$contents = zip_entry_read($entry, $size);
fwrite($h, $contents);
fclose($h);
ArtefactTypeFile::save_file($tempfile, $data, $user, true);
$created->files++;
}
if (count($zipinfo->names) > 10) {
$SESSION->set('unzip', array('file' => $file->get('id'), 'from' => $from, 'artefacts' => count($zipinfo->names)));
$smarty = smarty();
$smarty->display('artefact:file:extract-progress.tpl');
exit;
}
$created = $file->unzip();
$SESSION->add_ok_msg(get_string('extractfilessuccess', 'artefact.file', $created->folders, $created->files));
$redirect = files_page($file);
$redirect .= (strpos($redirect, '?') === false ? '?' : '&') . 'folder=' . $basefolder->get('id');
$redirect = $from . (strpos($from, '?') === false ? '?' : '&') . 'folder=' . $created->basefolderid;
redirect($redirect);
}
......
......@@ -213,10 +213,13 @@ $string['wrongfiletypeforblock'] = 'The file you uploaded was not the correct ty
// Unzip
$string['Contents'] = 'Contents';
$string['Continue'] = 'Continue';
$string['extractfilessuccess'] = 'Created %s folders and %s files.';
$string['filesextractedfromziparchive'] = 'Files extracted from Zip archive';
$string['fileswillbeextractedintofolder'] = 'Files will be extracted into %s';
$string['insufficientquotaforunzip'] = 'Your remaining file quota is too small to unzip this file.';
$string['pleasewaitwhileyourfilesarebeingunzipped'] = 'Please wait while your files are being unzipped.';
$string['spacerequired'] = 'Space Required';
$string['Unzip'] = 'Unzip';
$string['unzipprogress'] = '%s files/folders created.';
?>
......@@ -1593,6 +1593,108 @@ class ArtefactTypeArchive extends ArtefactTypeFile {
return $mimetypes;
}
public static function zip_file_info($zip) {
$info = (object) array(
'files' => 0,
'folders' => 0,
'totalsize' => 0,
'names' => array(),
);
while ($entry = zip_read($zip)) {
$name = zip_entry_name($entry);
$info->names[] = $name;
if (substr($name, -1) == '/') {
$info->folders++;
}
else {
$info->files++;
if ($size = zip_entry_filesize($entry)) {
$info->totalsize += $size;
}
}
}
$info->displaysize = ArtefactTypeFile::short_size($info->totalsize);
return $info;
}
public static function get_unzip_directory_name($file) {
$folderdata = ArtefactTypeFileBase::artefactchooser_folder_data($file);
$parent = $file->get('parent');
$strpath = ArtefactTypeFileBase::get_full_path($parent, $folderdata->data);
$extn = $file->get('oldextension');
$name = $file->get('title');
if (substr($name, -1-strlen($extn)) == '.' . $extn) {
$name = substr($name, 0, strlen($name)-1-strlen($extn));
}
$name = ArtefactTypeFileBase::get_new_file_title($name, $parent, $file->get('owner'), $file->get('group'), $file->get('institution'));
return array('basename' => $name, 'fullname' => $strpath . $name);
}
public function unzip($progresscallback=null) {
global $USER;
$foldername = ArtefactTypeArchive::get_unzip_directory_name($this);
$foldername = $foldername['basename'];
$data = (object) array(
'owner' => $this->get('owner'),
'group' => $this->get('group'),
'institution' => $this->get('institution'),
'title' => $foldername,
'description' => get_string('filesextractedfromziparchive', 'artefact.file'),
'parent' => $this->get('parent'),
);
$user = $data->owner ? $USER : null;
$basefolder = new ArtefactTypeFolder(0, $data);
$basefolder->commit();
$folders = array('.' => $basefolder->get('id'));
$status = (object) array('folders' => 1, 'files' => 0, 'basefolderid' => $basefolder->get('id'));
unset($data->description);
$tempdir = get_config('dataroot') . 'artefact/file/temp';
check_dir_exists($tempdir);
$zip = zip_open($this->get_path());
$tempfile = tempnam($tempdir, '');
$i = 0;
while ($entry = zip_read($zip)) {
$name = zip_entry_name($entry);
$folder = dirname($name);
$data->title = basename($name);
$data->parent = $folders[$folder];
if (substr($name, -1) == '/') {
$newfolder = new ArtefactTypeFolder(0, $data);
$newfolder->commit();
$status->folders++;
$folderindex = ($folder == '.' ? '' : ($folder . '/')) . $data->title;
$folders[$folderindex] = $newfolder->get('id');
}
else {
$h = fopen($tempfile, 'w');
$size = zip_entry_filesize($entry);
$contents = zip_entry_read($entry, $size);
fwrite($h, $contents);
fclose($h);
ArtefactTypeFile::save_file($tempfile, $data, $user, true);
$status->files++;
}
if ($progresscallback) {
$i++;
if ($i % 5 == 0) {
call_user_func_array($progresscallback, $i);
}
}
}
return $status;
}
}
?>
{include file="header.tpl"}
<div id="extract">
<h3>{str tag=pleasewaitwhileyourfilesarebeingunzipped section=artefact.file}</h3>
<iframe src="{$WWWROOT}artefact/file/extract-progress.php" id="progress" scrolling="no" frameborder="none"></iframe>
</div>
{include file="footer.tpl"}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment