allow to restore single files/folder from a deleted folder
This commit is contained in:
parent
3fd28632c4
commit
2c3216266c
|
@ -5,17 +5,24 @@ if(!OC_User::isLoggedIn()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
$files = $_REQUEST['files'];
|
$files = $_REQUEST['files'];
|
||||||
|
$dirlisting = $_REQUEST['dirlisting'];
|
||||||
$list = explode(';', $files);
|
$list = explode(';', $files);
|
||||||
|
|
||||||
$error = array();
|
$error = array();
|
||||||
|
|
||||||
$i = 0;
|
$i = 0;
|
||||||
foreach ($list as $file) {
|
foreach ($list as $file) {
|
||||||
$delimiter = strrpos($file, '.d');
|
if ( $dirlisting=='0') {
|
||||||
$filename = substr($file, 0, $delimiter);
|
$delimiter = strrpos($file, '.d');
|
||||||
$timestamp = substr($file, $delimiter+2);
|
$filename = substr($file, 0, $delimiter);
|
||||||
|
$timestamp = substr($file, $delimiter+2);
|
||||||
|
} else {
|
||||||
|
$path_parts = pathinfo($file);
|
||||||
|
$filename = $path_parts['basename'];
|
||||||
|
$timestamp = null;
|
||||||
|
}
|
||||||
|
|
||||||
if ( !OCA_Trash\Trashbin::restore($filename, $timestamp) ) {
|
if ( !OCA_Trash\Trashbin::restore($file, $filename, $timestamp) ) {
|
||||||
$error[] = $filename;
|
$error[] = $filename;
|
||||||
} else {
|
} else {
|
||||||
$success[$i]['filename'] = $filename;
|
$success[$i]['filename'] = $filename;
|
||||||
|
|
|
@ -28,7 +28,6 @@ if ($dir) {
|
||||||
$tmp = substr($dir, 0, $pos);
|
$tmp = substr($dir, 0, $pos);
|
||||||
$pos = strrpos($tmp, '.d');
|
$pos = strrpos($tmp, '.d');
|
||||||
$timestamp = substr($tmp,$pos+2);
|
$timestamp = substr($tmp,$pos+2);
|
||||||
error_log("timestamp: $timestamp");
|
|
||||||
$result[] = array(
|
$result[] = array(
|
||||||
'id' => $entryName,
|
'id' => $entryName,
|
||||||
'timestamp' => $timestamp,
|
'timestamp' => $timestamp,
|
||||||
|
@ -68,17 +67,23 @@ foreach ($result as $r) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make breadcrumb
|
// Make breadcrumb
|
||||||
$breadcrumb = array('dir' => '', 'name' => 'Trash');
|
$breadcrumb = array(array('dir' => '', 'name' => 'Trash'));
|
||||||
$pathtohere = '';
|
$pathtohere = '';
|
||||||
foreach (explode('/', $dir) as $i) {
|
foreach (explode('/', $dir) as $i) {
|
||||||
if ($i != '') {
|
if ($i != '') {
|
||||||
|
if ( preg_match('/^(.+)\.d[0-9]+$/', $i, $match) ) {
|
||||||
|
error_log("match!");
|
||||||
|
$name = $match[1];
|
||||||
|
} else {
|
||||||
|
$name = $i;
|
||||||
|
}
|
||||||
$pathtohere .= '/' . $i;
|
$pathtohere .= '/' . $i;
|
||||||
$breadcrumb[] = array('dir' => $pathtohere, 'name' => $i);
|
$breadcrumb[] = array('dir' => $pathtohere, 'name' => $name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$breadcrumbNav = new OCP\Template('files', 'part.breadcrumb', '');
|
$breadcrumbNav = new OCP\Template('files', 'part.breadcrumb', '');
|
||||||
$breadcrumbNav->assign('breadcrumb', array(array('dir' => '', 'name' => 'Trash')), false);
|
$breadcrumbNav->assign('breadcrumb', $breadcrumb, false);
|
||||||
$breadcrumbNav->assign('baseURL', OCP\Util::linkTo('files_trashbin', 'index.php') . '?dir=', false);
|
$breadcrumbNav->assign('baseURL', OCP\Util::linkTo('files_trashbin', 'index.php') . '?dir=', false);
|
||||||
|
|
||||||
$list = new OCP\Template('files_trashbin', 'part.list', '');
|
$list = new OCP\Template('files_trashbin', 'part.list', '');
|
||||||
|
|
|
@ -5,7 +5,7 @@ $(document).ready(function() {
|
||||||
FileActions.register('all', 'Undelete', OC.PERMISSION_READ, '', function(filename) {
|
FileActions.register('all', 'Undelete', OC.PERMISSION_READ, '', function(filename) {
|
||||||
var tr=$('tr').filterAttr('data-file', filename);
|
var tr=$('tr').filterAttr('data-file', filename);
|
||||||
$.post(OC.filePath('files_trashbin','ajax','undelete.php'),
|
$.post(OC.filePath('files_trashbin','ajax','undelete.php'),
|
||||||
{files:tr.attr('data-filename')+'.d'+tr.attr('data-timestamp')},
|
{files:tr.attr('data-file'), dirlisting:tr.attr('data-dirlisting') },
|
||||||
function(result){
|
function(result){
|
||||||
for (var i = 0; i < result.data.success.length; i++) {
|
for (var i = 0; i < result.data.success.length; i++) {
|
||||||
var row = document.getElementById(result.data.success[i].filename+'.d'+result.data.success[i].timestamp);
|
var row = document.getElementById(result.data.success[i].filename+'.d'+result.data.success[i].timestamp);
|
||||||
|
@ -64,8 +64,9 @@ $(document).ready(function() {
|
||||||
|
|
||||||
$('.undelete').click('click',function(event) {
|
$('.undelete').click('click',function(event) {
|
||||||
var fileslist=getSelectedFiles('file').join(';');
|
var fileslist=getSelectedFiles('file').join(';');
|
||||||
|
var dirlisting=getSelectedFiles('dirlisting')[0];
|
||||||
$.post(OC.filePath('files_trashbin','ajax','undelete.php'),
|
$.post(OC.filePath('files_trashbin','ajax','undelete.php'),
|
||||||
{files:fileslist},
|
{files:fileslist, dirlisting:dirlisting},
|
||||||
function(result){
|
function(result){
|
||||||
for (var i = 0; i < result.data.success.length; i++) {
|
for (var i = 0; i < result.data.success.length; i++) {
|
||||||
var row = document.getElementById(result.data.success[i].filename+'.d'+result.data.success[i].timestamp);
|
var row = document.getElementById(result.data.success[i].filename+'.d'+result.data.success[i].timestamp);
|
||||||
|
@ -133,7 +134,8 @@ function getSelectedFiles(property){
|
||||||
name:$(element).attr('data-filename'),
|
name:$(element).attr('data-filename'),
|
||||||
file:$(element).attr('data-file'),
|
file:$(element).attr('data-file'),
|
||||||
timestamp:$(element).attr('data-timestamp'),
|
timestamp:$(element).attr('data-timestamp'),
|
||||||
type:$(element).attr('data-type')
|
type:$(element).attr('data-type'),
|
||||||
|
dirlisting:$(element).attr('data-dirlisting')
|
||||||
};
|
};
|
||||||
if(property){
|
if(property){
|
||||||
files.push(file[property]);
|
files.push(file[property]);
|
||||||
|
|
|
@ -73,49 +73,63 @@ class Trashbin {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* restore files from trash bin
|
* restore files from trash bin
|
||||||
|
* @param $file path to the deleted file
|
||||||
* @param $filename name of the file
|
* @param $filename name of the file
|
||||||
* @param $timestamp time when the file was deleted
|
* @param $timestamp time when the file was deleted
|
||||||
*/
|
*/
|
||||||
public static function restore($filename, $timestamp) {
|
public static function restore($file, $filename, $timestamp) {
|
||||||
|
|
||||||
$user = \OCP\User::getUser();
|
$user = \OCP\User::getUser();
|
||||||
$view = new \OC_FilesystemView('/'.$user);
|
$view = new \OC_FilesystemView('/'.$user);
|
||||||
|
|
||||||
$query = \OC_DB::prepare('SELECT location,type FROM *PREFIX*files_trash WHERE user=? AND id=? AND timestamp=?');
|
if ( $timestamp ) {
|
||||||
$result = $query->execute(array($user,$filename,$timestamp))->fetchAll();
|
$query = \OC_DB::prepare('SELECT location,type FROM *PREFIX*files_trash WHERE user=? AND id=? AND timestamp=?');
|
||||||
|
$result = $query->execute(array($user,$filename,$timestamp))->fetchAll();
|
||||||
|
if ( count($result) != 1 ) {
|
||||||
|
\OC_Log::write('files_trashbin', 'trash bin database inconsistent!', OC_Log::ERROR);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if ( count($result) != 1 ) {
|
// if location no longer exists, restore file in the root directory
|
||||||
\OC_Log::write('files_trashbin', 'trash bin database inconsistent!', OC_Log::ERROR);
|
$location = $result[0]['location'];
|
||||||
return false;
|
if ( $result[0]['location'] != '/' && !$view->is_dir('files'.$result[0]['location']) ) {
|
||||||
|
$location = '';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$path_parts = pathinfo($filename);
|
||||||
|
$result[] = array(
|
||||||
|
'location' => $path_parts['dirname'],
|
||||||
|
'type' => $view->is_dir('/files_trashbin/'.$file) ? 'dir' : 'files',
|
||||||
|
);
|
||||||
|
$location = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
// if location no longer exists, restore file in the root directory
|
$source = \OC_Filesystem::normalizePath('files_trashbin/'.$file);
|
||||||
$location = $result[0]['location'];
|
|
||||||
if ( $result[0]['location'] != '/' && !$view->is_dir('files'.$result[0]['location']) ) {
|
|
||||||
$location = '/';
|
|
||||||
}
|
|
||||||
|
|
||||||
$source = 'files_trashbin/'.$filename.'.d'.$timestamp;
|
|
||||||
$target = \OC_Filesystem::normalizePath('files/'.$location.'/'.$filename);
|
$target = \OC_Filesystem::normalizePath('files/'.$location.'/'.$filename);
|
||||||
|
|
||||||
// we need a extension in case a file/dir with the same name already exists
|
// we need a extension in case a file/dir with the same name already exists
|
||||||
$ext = self::getUniqueExtension($location, $filename, $view);
|
$ext = self::getUniqueExtension($location, $filename, $view);
|
||||||
|
|
||||||
if( $view->rename($source, $target.$ext) ) {
|
if( $view->rename($source, $target.$ext) ) {
|
||||||
|
|
||||||
// if versioning app is enabled, copy versions from the trash bin back to the original location
|
// if versioning app is enabled, copy versions from the trash bin back to the original location
|
||||||
if ( $return && \OCP\App::isEnabled('files_versions') ) {
|
if ( \OCP\App::isEnabled('files_versions') ) {
|
||||||
if ( $result[0][type] == 'dir' ) {
|
if ( $result[0]['type'] == 'dir' ) {
|
||||||
$view->rename('versions_trashbin/'. $filename.'.d'.$timestamp, 'files_versions/'.$location.'/'.$filename.$ext);
|
$view->rename(\OC_Filesystem::normalizePath('versions_trashbin/'. $file), \OC_Filesystem::normalizePath('files_versions/'.$location.'/'.$filename.$ext));
|
||||||
} else if ( $versions = self::getVersionsFromTrash($filename, $timestamp) ) {
|
} else if ( $versions = self::getVersionsFromTrash($file, $timestamp) ) {
|
||||||
foreach ($versions as $v) {
|
foreach ($versions as $v) {
|
||||||
$view->rename('versions_trashbin/'.$filename.'.v'.$v.'.d'.$timestamp, 'files_versions/'.$location.'/'.$filename.$ext.'.v'.$v);
|
if ($timestamp ) {
|
||||||
|
$view->rename('versions_trashbin/'.$filename.'.v'.$v.'.d'.$timestamp, 'files_versions/'.$location.'/'.$filename.$ext.'.v'.$v);
|
||||||
|
} else {
|
||||||
|
$view->rename('versions_trashbin/'.$file.'.v'.$v, 'files_versions/'.$location.'/'.$filename.$ext.'.v'.$v);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$query = \OC_DB::prepare('DELETE FROM *PREFIX*files_trash WHERE user=? AND id=? AND timestamp=?');
|
if ( $timestamp ) {
|
||||||
$query->execute(array($user,$filename,$timestamp));
|
$query = \OC_DB::prepare('DELETE FROM *PREFIX*files_trash WHERE user=? AND id=? AND timestamp=?');
|
||||||
|
$query->execute(array($user,$filename,$timestamp));
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -189,12 +203,22 @@ class Trashbin {
|
||||||
$versionsName = \OCP\Config::getSystemValue('datadirectory').$view->getAbsolutePath($filename);
|
$versionsName = \OCP\Config::getSystemValue('datadirectory').$view->getAbsolutePath($filename);
|
||||||
$versions = array();
|
$versions = array();
|
||||||
|
|
||||||
|
if ($timestamp ) {
|
||||||
// fetch for old versions
|
// fetch for old versions
|
||||||
$matches = glob( $versionsName.'.v*.d'.$timestamp );
|
$matches = glob( $versionsName.'.v*.d'.$timestamp );
|
||||||
|
$offset = -strlen($timestamp)-2;
|
||||||
|
} else {
|
||||||
|
$matches = glob( $versionsName.'.v*' );
|
||||||
|
}
|
||||||
|
|
||||||
foreach( $matches as $ma ) {
|
foreach( $matches as $ma ) {
|
||||||
$parts = explode( '.v', substr($ma, 0, -strlen($timestamp)-2) );
|
if ( $timestamp ) {
|
||||||
$versions[] = ( end( $parts ) );
|
$parts = explode( '.v', substr($ma, 0, $offset) );
|
||||||
|
$versions[] = ( end( $parts ) );
|
||||||
|
} else {
|
||||||
|
$parts = explode( '.v', $ma );
|
||||||
|
$versions[] = ( end( $parts ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return $versions;
|
return $versions;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,13 +24,21 @@
|
||||||
$name = str_replace('%2F', '/', $name);
|
$name = str_replace('%2F', '/', $name);
|
||||||
$directory = str_replace('+', '%20', urlencode($file['directory']));
|
$directory = str_replace('+', '%20', urlencode($file['directory']));
|
||||||
$directory = str_replace('%2F', '/', $directory); ?>
|
$directory = str_replace('%2F', '/', $directory); ?>
|
||||||
<tr id="<?php echo $file['name'].'.d'.$file['timestamp'];?>"
|
<tr data-filename="<?php echo $file['name'];?>"
|
||||||
data-file="<?php echo $file['name'].'.d'.$file['timestamp'];?>"
|
|
||||||
data-filename="<?php echo $file['name'];?>"
|
|
||||||
data-type="<?php echo ($file['type'] == 'dir')?'dir':'file'?>"
|
data-type="<?php echo ($file['type'] == 'dir')?'dir':'file'?>"
|
||||||
data-mime="<?php echo $file['mimetype']?>"
|
data-mime="<?php echo $file['mimetype']?>"
|
||||||
|
data-permissions='<?php echo $file['permissions']; ?>'
|
||||||
|
<?php if ( $_['dirlisting'] ): ?>
|
||||||
|
id="<?php echo $file['directory'].'/'.$file['name'];?>"
|
||||||
|
data-file="<?php echo $file['directory'].'/'.$file['name'];?>"
|
||||||
|
data-timestamp=''
|
||||||
|
data-dirlisting=1
|
||||||
|
<?php else: ?>
|
||||||
|
id="<?php echo $file['name'].'.d'.$file['timestamp'];?>"
|
||||||
|
data-file="<?php echo $file['name'].'.d'.$file['timestamp'];?>"
|
||||||
data-timestamp='<?php echo $file['timestamp'];?>'
|
data-timestamp='<?php echo $file['timestamp'];?>'
|
||||||
data-permissions='<?php echo $file['permissions']; ?>'>
|
data-dirlisting=0
|
||||||
|
<?php endif; ?>>
|
||||||
<td class="filename svg"
|
<td class="filename svg"
|
||||||
<?php if($file['type'] == 'dir'): ?>
|
<?php if($file['type'] == 'dir'): ?>
|
||||||
style="background-image:url(<?php echo OCP\mimetype_icon('dir'); ?>)"
|
style="background-image:url(<?php echo OCP\mimetype_icon('dir'); ?>)"
|
||||||
|
|
Loading…
Reference in New Issue