Skip to content

Commit

Permalink
feat: add before_moveToTrash hook + add fileId to delete hook
Browse files Browse the repository at this point in the history
  • Loading branch information
DeepDiver1975 committed Oct 29, 2021
1 parent 5c1b695 commit e9c105e
Showing 1 changed file with 53 additions and 30 deletions.
83 changes: 53 additions & 30 deletions apps/files_trashbin/lib/Trashbin.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,11 @@
use OCP\Encryption\Keys\IStorage;
use OCP\Files\ForbiddenException;
use OCP\Files\NotFoundException;
use OCP\Files\Storage\IStorageWithTrash;
use OCP\Files\StorageNotAvailableException;
use OCP\Lock\LockedException;
use OCP\User;
use OCP\Util;
use Symfony\Component\EventDispatcher\GenericEvent;
use OCP\Files\Folder;
use OCP\Files\IRootFolder;
Expand Down Expand Up @@ -266,7 +268,7 @@ public static function insertTrashEntry($user, $targetFilename, $targetLocation,
$query = \OC_DB::prepare("INSERT INTO `*PREFIX*files_trash` (`id`,`timestamp`,`location`,`user`) VALUES (?,?,?,?)");
$result = $query->execute([$targetFilename, $timestamp, $targetLocation, $user]);
if (!$result) {
\OCP\Util::writeLog('files_trashbin', 'trash bin database couldn\'t be updated for the files owner', \OCP\Util::ERROR);
Util::writeLog('files_trashbin', 'trash bin database couldn\'t be updated for the files owner', Util::ERROR);
}
}

Expand All @@ -278,6 +280,7 @@ public static function insertTrashEntry($user, $targetFilename, $targetLocation,
* isn't any trashbin available
*/
public static function move2trash($file_path) {

// get the user for which the filesystem is setup
$root = Filesystem::getRoot();
list(, $user) = \explode('/', $root);
Expand Down Expand Up @@ -315,11 +318,25 @@ public static function move2trash($file_path) {
$timestamp = \time();

$trashPath = '/files_trashbin/files/' . $filename . '.d' . $timestamp;
$trashVersionsPath = '/files_trashbin/versions/' . $filename . '.d' . $timestamp;

/** @var \OC\Files\Storage\Storage $trashStorage */
list($trashStorage, $trashInternalPath) = $ownerView->resolvePath($trashPath);
list($trashVersionStorage, $trashVersionInternalPath) = $ownerView->resolvePath($trashVersionsPath);
/** @var \OC\Files\Storage\Storage $sourceStorage */
list($sourceStorage, $sourceInternalPath) = $ownerView->resolvePath('/files/' . $ownerPath);

Util::emitHook('\OCA\Files_Trashbin\Trashbin', 'before_moveToTrash', [
'filePath' => Filesystem::normalizePath($file_path),
'trashPath' => Filesystem::normalizePath($filename . '.d' . $timestamp),
'sourceStorage' => $sourceStorage,
'sourceInternalPath' => $sourceInternalPath,
'trashStorage' => $trashStorage,
'trashInternalPath' => $trashInternalPath,
'trashVersionStorage' => $trashVersionStorage,
'trashVersionInternalPath' => $trashVersionInternalPath,
]);

try {
$moveSuccessful = true;
if ($trashStorage->file_exists($trashInternalPath)) {
Expand All @@ -331,7 +348,7 @@ public static function move2trash($file_path) {
if ($trashStorage->file_exists($trashInternalPath)) {
$trashStorage->unlink($trashInternalPath);
}
\OCP\Util::writeLog('files_trashbin', 'Couldn\'t move ' . $file_path . ' to the trash bin', \OCP\Util::ERROR);
Util::writeLog('files_trashbin', 'Couldn\'t move ' . $file_path . ' to the trash bin', Util::ERROR);
}

if ($sourceStorage->file_exists($sourceInternalPath)) { // failed to delete the original file, abort
Expand All @@ -349,9 +366,9 @@ public static function move2trash($file_path) {
$query = \OC_DB::prepare("INSERT INTO `*PREFIX*files_trash` (`id`,`timestamp`,`location`,`user`) VALUES (?,?,?,?)");
$result = $query->execute([$filename, $timestamp, $location, $owner]);
if (!$result) {
\OCP\Util::writeLog('files_trashbin', 'trash bin database couldn\'t be updated', \OCP\Util::ERROR);
Util::writeLog('files_trashbin', 'trash bin database couldn\'t be updated', Util::ERROR);
}
\OCP\Util::emitHook('\OCA\Files_Trashbin\Trashbin', 'post_moveToTrash', ['filePath' => Filesystem::normalizePath($file_path),
Util::emitHook('\OCA\Files_Trashbin\Trashbin', 'post_moveToTrash', ['filePath' => Filesystem::normalizePath($file_path),
'trashPath' => Filesystem::normalizePath($filename . '.d' . $timestamp)]);

self::retainVersions($filename, $owner, $ownerPath, $timestamp, $sourceStorage);
Expand Down Expand Up @@ -491,8 +508,8 @@ public static function restore($file, $filename, $timestamp, $targetLocation = n
if ($timestamp) {
$location = self::getLocation($user, $filename, $timestamp);
if ($location === false) {
\OCP\Util::writeLog('files_trashbin', 'Original location of file ' . $filename .
' not found in database, hence restoring into user\'s root instead', \OCP\Util::DEBUG);
Util::writeLog('files_trashbin', 'Original location of file ' . $filename .
' not found in database, hence restoring into user\'s root instead', Util::DEBUG);
} else {
// if location no longer exists, restore file in the root directory
if ($location !== '/' &&
Expand Down Expand Up @@ -525,8 +542,10 @@ public static function restore($file, $filename, $timestamp, $targetLocation = n
$view->chroot('/' . $user . '/files');
$view->touch('/' . $targetLocation, $mtime);
$view->chroot($fakeRoot);
\OCP\Util::emitHook('\OCA\Files_Trashbin\Trashbin', 'post_restore', ['filePath' => Filesystem::normalizePath('/' . $targetLocation),
'trashPath' => Filesystem::normalizePath($file)]);
Util::emitHook('\OCA\Files_Trashbin\Trashbin', 'post_restore', [
'filePath' => Filesystem::normalizePath('/' . $targetLocation),
'trashPath' => Filesystem::normalizePath($file)
]);

self::restoreVersions($view, $file, $filename, $targetLocation, $timestamp);

Expand Down Expand Up @@ -597,16 +616,16 @@ public static function deleteAll() {
// Array to store the relative path in (after the file is deleted, the view won't be able to relativise the path anymore)
$filePaths = [];
foreach ($fileInfos as $fileInfo) {
$filePaths[] = $view->getRelativePath($fileInfo->getPath());
$filePaths[$fileInfo->getId()] = $view->getRelativePath($fileInfo->getPath());
}
unset($fileInfos); // save memory

// Bulk PreDelete-Hook
\OC_Hook::emit('\OCP\Trashbin', 'preDeleteAll', ['paths' => $filePaths]);

// Single-File Hooks
foreach ($filePaths as $path) {
self::emitTrashbinPreDelete($user, $path);
foreach ($filePaths as $fileId => $path) {
self::emitTrashbinPreDelete($user, $path, $fileId);
}

// actual file deletion
Expand All @@ -618,8 +637,8 @@ public static function deleteAll() {
\OC_Hook::emit('\OCP\Trashbin', 'deleteAll', ['paths' => $filePaths]);

// Single-File Hooks
foreach ($filePaths as $path) {
self::emitTrashbinPostDelete($user, $path);
foreach ($filePaths as $fileId => $path) {
self::emitTrashbinPostDelete($user, $path, $fileId);
}

$view->mkdir('files_trashbin');
Expand All @@ -634,12 +653,14 @@ public static function deleteAll() {
* @param string $uid
* @param string $path
*/
protected static function emitTrashbinPreDelete($uid, $path) {
protected static function emitTrashbinPreDelete($uid, $path, $fileId) {
\OC_Hook::emit(
'\OCP\Trashbin',
'preDelete',
['path' => $path, 'user' => $uid]
);
'preDelete', [
'path' => $path,
'user' => $uid,
'fileId' => $fileId
]);
}

/**
Expand All @@ -648,12 +669,13 @@ protected static function emitTrashbinPreDelete($uid, $path) {
* @param string $uid
* @param string $path
*/
protected static function emitTrashbinPostDelete($uid, $path) {
protected static function emitTrashbinPostDelete($uid, $path, $fileId) {
\OC_Hook::emit(
'\OCP\Trashbin',
'delete',
['path' => $path, 'user' => $uid]
);
'delete', [
'path' => $path,
'user' => $uid,
'fileId' => $fileId]);
}

/**
Expand Down Expand Up @@ -688,9 +710,10 @@ public static function delete($filename, $user, $timestamp = null) {
} else {
$size += $view->filesize('/files_trashbin/files/' . $file);
}
self::emitTrashbinPreDelete($user, "/files_trashbin/files/$file");
$fileId = $view->getFileInfo('/files_trashbin/files/' . $file);
self::emitTrashbinPreDelete($user, "/files_trashbin/files/$file", $fileId);
$view->unlink('/files_trashbin/files/' . $file);
self::emitTrashbinPostDelete($user, "/files_trashbin/files/$file");
self::emitTrashbinPostDelete($user, "/files_trashbin/files/$file", $fileId);

return $size;
}
Expand Down Expand Up @@ -960,15 +983,15 @@ function (GenericEvent $event) {
*/
public static function registerHooks() {
// create storage wrapper on setup
\OCP\Util::connectHook('OC_Filesystem', 'preSetup', 'OCA\Files_Trashbin\Storage', 'setupStorage');
Util::connectHook('OC_Filesystem', 'preSetup', 'OCA\Files_Trashbin\Storage', 'setupStorage');
//Listen to delete user signal
\OCP\Util::connectHook('OC_User', 'pre_deleteUser', 'OCA\Files_Trashbin\Hooks', 'deleteUser_hook');
Util::connectHook('OC_User', 'pre_deleteUser', 'OCA\Files_Trashbin\Hooks', 'deleteUser_hook');
//Listen to post write hook
\OCP\Util::connectHook('OC_Filesystem', 'post_write', 'OCA\Files_Trashbin\Hooks', 'post_write_hook');
Util::connectHook('OC_Filesystem', 'post_write', 'OCA\Files_Trashbin\Hooks', 'post_write_hook');
// pre and post-rename, disable trash logic for the copy+unlink case
\OCP\Util::connectHook('OC_Filesystem', 'delete', 'OCA\Files_Trashbin\Trashbin', 'ensureFileScannedHook');
\OCP\Util::connectHook('OC_Filesystem', 'rename', 'OCA\Files_Trashbin\Storage', 'preRenameHook');
\OCP\Util::connectHook('OC_Filesystem', 'post_rename', 'OCA\Files_Trashbin\Storage', 'postRenameHook');
Util::connectHook('OC_Filesystem', 'delete', 'OCA\Files_Trashbin\Trashbin', 'ensureFileScannedHook');
Util::connectHook('OC_Filesystem', 'rename', 'OCA\Files_Trashbin\Storage', 'preRenameHook');
Util::connectHook('OC_Filesystem', 'post_rename', 'OCA\Files_Trashbin\Storage', 'postRenameHook');
}

/**
Expand Down Expand Up @@ -1025,6 +1048,6 @@ public static function isEmpty($user) {
* @return string
*/
public static function preview_icon($path) {
return \OCP\Util::linkToRoute('core_ajax_trashbin_preview', ['x' => 32, 'y' => 32, 'file' => $path]);
return Util::linkToRoute('core_ajax_trashbin_preview', ['x' => 32, 'y' => 32, 'file' => $path]);
}
}

0 comments on commit e9c105e

Please sign in to comment.