Commit ed950b40 authored by Richard Mansfield's avatar Richard Mansfield
Browse files

Merge branch 'unzip'

parents f9fb310e 9b599d3f
......@@ -239,6 +239,28 @@ function xmldb_artefact_file_upgrade($oldversion=0) {
add_key($table, $key);
}
if ($oldversion < 2009092300) {
insert_record('artefact_installed_type', (object) array('plugin' => 'file', 'name' => 'archive'));
// update old files
if (function_exists('zip_open')) {
$files = get_records_select_array('artefact_file_files', "filetype IN ('application/zip', 'application/x-zip')");
if ($files) {
$checked = array();
foreach ($files as $file) {
$path = get_config('dataroot') . 'artefact/file/originals/' . ($file->fileid % 256) . '/' . $file->fileid;
$zip = zip_open($path);
if (is_resource($zip)) {
$checked[] = $file->artefact;
zip_close($zip);
}
}
if (!empty($checked)) {
set_field_select('artefact', 'artefacttype', 'archive', "artefacttype = 'file' AND id IN (" . join(',', $checked) . ')', array());
}
}
}
}
return $status;
}
......
<?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>
<?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);
define('MENUITEM', 'myportfolio/files');
require(dirname(dirname(dirname(__FILE__))) . '/init.php');
safe_require('artefact', 'file');
$fileid = param_integer('file');
// @todo provide upload form when fileid not set.
$smartyconfig = array(
'sideblocks' => array(
array(
'name' => 'quota',
'weight' => -10,
'data' => array(),
),
),
);
if ($fileid) {
$file = artefact_instance_from_id($fileid);
if ($group = $file->get('group')) {
require_once(get_config('libroot') . 'group.php');
define('GROUP', $group);
$group = group_current_group();
define('TITLE', $group->name);
}
else {
define('TITLE', get_string('Unzip', 'artefact.file'));
}
if (!($file instanceof ArtefactTypeArchive)) {
throw new NotFoundException();
}
if (!$USER->can_edit_artefact($file)) {
throw new AccessDeniedException();
}
$zip = zip_open($file->get_path());
if (!is_resource($zip)) {
throw new NotFoundException();
}
$zipinfo = ArtefactTypeArchive::zip_file_info($zip);
zip_close($zip);
if (!$file->get('owner') || $USER->quota_allowed($zipinfo->totalsize)) {
$name = ArtefactTypeArchive::get_unzip_directory_name($file);
$message = get_string('fileswillbeextractedintofolder', 'artefact.file', $name['fullname']);
$goto = files_page($file);
if ($parent = $file->get('parent')) {
$goto .= (strpos($goto, '?') === false ? '?' : '&') . 'folder=' . $parent;
}
$form = pieform(array(
'name' => 'unzip_artefact',
'elements' => array(
'fileid' => array(
'type' => 'hidden',
'value' => $fileid,
),
'submit' => array(
'type' => 'submitcancel',
'value' => array(get_string('Unzip', 'artefact.file'), get_string('cancel')),
'goto' => $goto,
)
),
));
}
else {
$message = get_string('insufficientquotaforunzip', 'artefact.file');
}
$smarty = smarty(array(), array(), array(), $smartyconfig);
$smarty->assign('file', $file);
$smarty->assign('zipinfo', $zipinfo);
$smarty->assign('message', $message);
$smarty->assign('form', $form);
$smarty->assign('PAGEHEADING', hsc(TITLE));
$smarty->display('artefact:file:extract.tpl');
}
function files_page($file) {
$url = get_config('wwwroot') . 'artefact/file/';
if ($owner = $file->get('owner')) {
$url .= 'index.php';
}
else if ($group = $file->get('group')) {
$url .= 'groupfiles.php?group=' . $group;
}
if ($institution = $file->get('institution')) {
if ($institution == 'mahara') {
$url .= 'sitefiles.php';
}
else {
$url .= 'institutionfiles.php?institution=' . $institution;
}
}
return $url;
}
function unzip_artefact_submit(Pieform $form, $values) {
global $file, $zipinfo, $SESSION;
$from = files_page($file);
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 = $from . (strpos($from, '?') === false ? '?' : '&') . 'folder=' . $created->basefolderid;
redirect($redirect);
}
?>
......@@ -211,4 +211,15 @@ $string['usenodefault'] = 'Use no default';
$string['usingnodefaultprofileicon'] = 'Now using no default profile icon';
$string['wrongfiletypeforblock'] = 'The file you uploaded was not the correct type for this block.';
// 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.';
?>
......@@ -35,6 +35,7 @@ class PluginArtefactFile extends PluginArtefact {
'folder',
'image',
'profileicon',
'archive',
);
}
......@@ -213,11 +214,12 @@ class PluginArtefactFile extends PluginArtefact {
'file' => array('file'),
'image' => array('file', 'image'),
'profileicon' => array('image'),
'archive' => array('file'),
);
}
public static function get_attachment_types() {
return array('file', 'image');
return array('file', 'image', 'archive');
}
}
......@@ -754,6 +756,17 @@ class ArtefactTypeFile extends ArtefactTypeFileBase {
$data->height = $imageinfo[1];
return new ArtefactTypeImage(0, $data);
}
if ((!isset($data->filetype) || in_array($data->filetype, ArtefactTypeArchive::zip_mime_types()))
&& function_exists('zip_open')) {
$zip = zip_open($path);
if (is_resource($zip)) {
zip_close($zip);
if (!isset($data->filetype)) {
$data->filetype = 'application/zip';
}
return new ArtefactTypeArchive(0, $data);
}
}
return new ArtefactTypeFile(0, $data);
}
......@@ -1565,5 +1578,123 @@ class ArtefactTypeProfileIcon extends ArtefactTypeImage {
}
class ArtefactTypeArchive extends ArtefactTypeFile {
public static function get_icon($options=null) {
global $THEME;
return $THEME->get_url('images/archive.gif');
}
public static function zip_mime_types() {
static $mimetypes = null;
if (is_null($mimetypes)) {
$mimetypes = get_column('artefact_file_mime_types', 'mimetype', 'description', 'zip');
}
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"}
{include file="header.tpl"}
{if $file}
<h5>{$file->get('title')|escape}</h5>
<p>
<span><label>{str tag=Files section=artefact.file}:</label> {$zipinfo->files}&nbsp;</span>
<span><label>{str tag=Folders section=artefact.file}:</label> {$zipinfo->folders}</span>
<span><label>{str tag=spacerequired section=artefact.file}:</label> {$zipinfo->displaysize}</span>
</p>
<p>
<div><label>{str tag=Contents section=artefact.file}:</label></div>
{foreach from=$zipinfo->names item=name}
<div>{$name|escape}</div>
{/foreach}
</p>
<p>{$message|escape}</p>
{$form}
{/if}
{include file="footer.tpl"}
......@@ -38,8 +38,9 @@
<td>{$file->description|escape}</td>
<td>{$file->size}</td>
<td>{$file->mtime}</td>
<td>
<td class="right">
{if $editable && !$file->isparent}
{if $file->artefacttype == 'archive'}<a href="{$WWWROOT}artefact/file/extract.php?file={$file->id}">{str tag=Unzip section=artefact.file}</a>{/if}
{if !isset($file->can_edit) || $file->can_edit !== 0}<input type="submit" class="submit btn-edit s" name="{$prefix}_edit[{$file->id}]" value="{str tag=edit}" />
<input type="submit" class="submit btn-del s" name="{$prefix}_delete[{$file->id}]" value="{str tag=delete}" />{/if}
{/if}
......
......@@ -28,7 +28,7 @@
defined('INTERNAL') || die();
$config = new StdClass;
$config->version = 2009091701;
$config->version = 2009092300;
$config->release = '1.1.0';
?>
......@@ -562,6 +562,7 @@ class HtmlExportOutputFilter {
return '<a href="' . $this->basepath . '/files/blog/' . PluginExportHtml::text_to_path($artefact->get('title')) . '/' . $page . '.html">' . $matches[5] . '</a>';
case 'file':
case 'image':
case 'archive':
$folderpath = $this->get_folder_path_for_file($artefact);
return '<a href="' . $this->basepath . '/files/file/' . $folderpath . PluginExportHtml::sanitise_path($artefact->get('title')) . '">' . $matches[5] . '</a>';
default:
......
......@@ -45,7 +45,7 @@
{foreach from=$data.artefacts item=artefact}
{if $artefact->artefacttype == 'blog'}
<li><a href="{$WWWROOT}artefact/blog/view/?id={$artefact->id}">{$artefact->title|escape}</a></li>
{elseif $artefact->artefacttype == 'file' || $artefact->artefacttype == 'image'}
{elseif $artefact->artefacttype == 'file' || $artefact->artefacttype == 'image' || $artefact->artefacttype == 'archive'}
<li><a href="{$WWWROOT}artefact/file/download.php?file={$artefact->id}">{$artefact->title|escape}</a></li>
{elseif $artefact->artefacttype == 'folder'}
<li><a href="{$WWWROOT}artefact/file/?folder={$artefact->id}">{$artefact->title|escape}</a></li>
......
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