From 2c3216266ce067c7e64361909daff4d25a6e32c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Tue, 22 Jan 2013 12:00:04 +0100 Subject: [PATCH] allow to restore single files/folder from a deleted folder --- apps/files_trashbin/ajax/undelete.php | 15 +++-- apps/files_trashbin/index.php | 15 +++-- apps/files_trashbin/js/trash.js | 8 ++- apps/files_trashbin/lib/trash.php | 74 ++++++++++++++------- apps/files_trashbin/templates/part.list.php | 16 +++-- 5 files changed, 87 insertions(+), 41 deletions(-) diff --git a/apps/files_trashbin/ajax/undelete.php b/apps/files_trashbin/ajax/undelete.php index 05b5e7a5ee..5aa6436ae5 100644 --- a/apps/files_trashbin/ajax/undelete.php +++ b/apps/files_trashbin/ajax/undelete.php @@ -5,17 +5,24 @@ if(!OC_User::isLoggedIn()) { } $files = $_REQUEST['files']; +$dirlisting = $_REQUEST['dirlisting']; $list = explode(';', $files); $error = array(); $i = 0; foreach ($list as $file) { - $delimiter = strrpos($file, '.d'); - $filename = substr($file, 0, $delimiter); - $timestamp = substr($file, $delimiter+2); + if ( $dirlisting=='0') { + $delimiter = strrpos($file, '.d'); + $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; } else { $success[$i]['filename'] = $filename; diff --git a/apps/files_trashbin/index.php b/apps/files_trashbin/index.php index 2925223197..97bb64c626 100644 --- a/apps/files_trashbin/index.php +++ b/apps/files_trashbin/index.php @@ -28,7 +28,6 @@ if ($dir) { $tmp = substr($dir, 0, $pos); $pos = strrpos($tmp, '.d'); $timestamp = substr($tmp,$pos+2); - error_log("timestamp: $timestamp"); $result[] = array( 'id' => $entryName, 'timestamp' => $timestamp, @@ -68,17 +67,23 @@ foreach ($result as $r) { } // Make breadcrumb -$breadcrumb = array('dir' => '', 'name' => 'Trash'); +$breadcrumb = array(array('dir' => '', 'name' => 'Trash')); $pathtohere = ''; 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; - $breadcrumb[] = array('dir' => $pathtohere, 'name' => $i); + $breadcrumb[] = array('dir' => $pathtohere, 'name' => $name); } } $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); $list = new OCP\Template('files_trashbin', 'part.list', ''); diff --git a/apps/files_trashbin/js/trash.js b/apps/files_trashbin/js/trash.js index 8f3786f15e..355e25d97d 100644 --- a/apps/files_trashbin/js/trash.js +++ b/apps/files_trashbin/js/trash.js @@ -5,7 +5,7 @@ $(document).ready(function() { FileActions.register('all', 'Undelete', OC.PERMISSION_READ, '', function(filename) { var tr=$('tr').filterAttr('data-file', filename); $.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){ 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); @@ -64,8 +64,9 @@ $(document).ready(function() { $('.undelete').click('click',function(event) { var fileslist=getSelectedFiles('file').join(';'); + var dirlisting=getSelectedFiles('dirlisting')[0]; $.post(OC.filePath('files_trashbin','ajax','undelete.php'), - {files:fileslist}, + {files:fileslist, dirlisting:dirlisting}, function(result){ 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); @@ -133,7 +134,8 @@ function getSelectedFiles(property){ name:$(element).attr('data-filename'), file:$(element).attr('data-file'), timestamp:$(element).attr('data-timestamp'), - type:$(element).attr('data-type') + type:$(element).attr('data-type'), + dirlisting:$(element).attr('data-dirlisting') }; if(property){ files.push(file[property]); diff --git a/apps/files_trashbin/lib/trash.php b/apps/files_trashbin/lib/trash.php index abfcf847ac..9b891e773b 100644 --- a/apps/files_trashbin/lib/trash.php +++ b/apps/files_trashbin/lib/trash.php @@ -73,49 +73,63 @@ class Trashbin { /** * restore files from trash bin + * @param $file path to the deleted file * @param $filename name of the file * @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(); $view = new \OC_FilesystemView('/'.$user); - $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 location no longer exists, restore file in the root directory - $location = $result[0]['location']; - if ( $result[0]['location'] != '/' && !$view->is_dir('files'.$result[0]['location']) ) { - $location = '/'; + if ( $timestamp ) { + $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 location no longer exists, restore file in the root directory + $location = $result[0]['location']; + 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 = ''; } - $source = 'files_trashbin/'.$filename.'.d'.$timestamp; + $source = \OC_Filesystem::normalizePath('files_trashbin/'.$file); $target = \OC_Filesystem::normalizePath('files/'.$location.'/'.$filename); // we need a extension in case a file/dir with the same name already exists $ext = self::getUniqueExtension($location, $filename, $view); if( $view->rename($source, $target.$ext) ) { - // if versioning app is enabled, copy versions from the trash bin back to the original location - if ( $return && \OCP\App::isEnabled('files_versions') ) { - if ( $result[0][type] == 'dir' ) { - $view->rename('versions_trashbin/'. $filename.'.d'.$timestamp, 'files_versions/'.$location.'/'.$filename.$ext); - } else if ( $versions = self::getVersionsFromTrash($filename, $timestamp) ) { + if ( \OCP\App::isEnabled('files_versions') ) { + if ( $result[0]['type'] == 'dir' ) { + $view->rename(\OC_Filesystem::normalizePath('versions_trashbin/'. $file), \OC_Filesystem::normalizePath('files_versions/'.$location.'/'.$filename.$ext)); + } else if ( $versions = self::getVersionsFromTrash($file, $timestamp) ) { 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=?'); - $query->execute(array($user,$filename,$timestamp)); + if ( $timestamp ) { + $query = \OC_DB::prepare('DELETE FROM *PREFIX*files_trash WHERE user=? AND id=? AND timestamp=?'); + $query->execute(array($user,$filename,$timestamp)); + } return true; } @@ -189,12 +203,22 @@ class Trashbin { $versionsName = \OCP\Config::getSystemValue('datadirectory').$view->getAbsolutePath($filename); $versions = array(); + if ($timestamp ) { // 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 ) { - $parts = explode( '.v', substr($ma, 0, -strlen($timestamp)-2) ); - $versions[] = ( end( $parts ) ); + if ( $timestamp ) { + $parts = explode( '.v', substr($ma, 0, $offset) ); + $versions[] = ( end( $parts ) ); + } else { + $parts = explode( '.v', $ma ); + $versions[] = ( end( $parts ) ); + } } return $versions; } diff --git a/apps/files_trashbin/templates/part.list.php b/apps/files_trashbin/templates/part.list.php index 72359da299..6faddcf485 100644 --- a/apps/files_trashbin/templates/part.list.php +++ b/apps/files_trashbin/templates/part.list.php @@ -24,13 +24,21 @@ $name = str_replace('%2F', '/', $name); $directory = str_replace('+', '%20', urlencode($file['directory'])); $directory = str_replace('%2F', '/', $directory); ?> - ' + + id="" + data-file="" + data-timestamp='' + data-dirlisting=1 + + id="" + data-file="" data-timestamp='' - data-permissions=''> + data-dirlisting=0 + > style="background-image:url()"