Example #1
0
 /**
  * Deletes the given file by moving it into the trashbin.
  *
  * @param string $path
  */
 public function unlink($path)
 {
     if (self::$disableTrash) {
         return $this->storage->unlink($path);
     }
     $normalized = Filesystem::normalizePath($this->mountPoint . '/' . $path);
     $result = true;
     if (!isset($this->deletedFiles[$normalized])) {
         $view = Filesystem::getView();
         $this->deletedFiles[$normalized] = $normalized;
         if ($filesPath = $view->getRelativePath($normalized)) {
             $filesPath = trim($filesPath, '/');
             $result = \OCA\Files_Trashbin\Trashbin::move2trash($filesPath);
             // in cross-storage cases the file will be copied
             // but not deleted, so we delete it here
             if ($result) {
                 $this->storage->unlink($path);
             }
         } else {
             $result = $this->storage->unlink($path);
         }
         unset($this->deletedFiles[$normalized]);
     } else {
         if ($this->storage->file_exists($path)) {
             $result = $this->storage->unlink($path);
         }
     }
     return $result;
 }
Example #2
0
 /**
  * Retrieves the contents of a trash bin directory.
  *
  * @param string $dir path to the directory inside the trashbin
  * or empty to retrieve the root of the trashbin
  * @param string $user
  * @param string $sortAttribute attribute to sort on or empty to disable sorting
  * @param bool $sortDescending true for descending sort, false otherwise
  * @return \OCP\Files\FileInfo[]
  */
 public static function getTrashFiles($dir, $user, $sortAttribute = '', $sortDescending = false)
 {
     $result = array();
     $timestamp = null;
     $view = new \OC\Files\View('/' . $user . '/files_trashbin/files');
     if (ltrim($dir, '/') !== '' && !$view->is_dir($dir)) {
         throw new \Exception('Directory does not exists');
     }
     $dirContent = $view->opendir($dir);
     if ($dirContent === false) {
         return $result;
     }
     $mount = $view->getMount($dir);
     $storage = $mount->getStorage();
     $absoluteDir = $view->getAbsolutePath($dir);
     $internalPath = $mount->getInternalPath($absoluteDir);
     if (is_resource($dirContent)) {
         $originalLocations = \OCA\Files_Trashbin\Trashbin::getLocations($user);
         while (($entryName = readdir($dirContent)) !== false) {
             if (!\OC\Files\Filesystem::isIgnoredDir($entryName)) {
                 $id = $entryName;
                 if ($dir === '' || $dir === '/') {
                     $size = $view->filesize($id);
                     $pathparts = pathinfo($entryName);
                     $timestamp = substr($pathparts['extension'], 1);
                     $id = $pathparts['filename'];
                 } else {
                     if ($timestamp === null) {
                         // for subfolders we need to calculate the timestamp only once
                         $size = $view->filesize($dir . '/' . $id);
                         $parts = explode('/', ltrim($dir, '/'));
                         $timestamp = substr(pathinfo($parts[0], PATHINFO_EXTENSION), 1);
                     }
                 }
                 $originalPath = '';
                 if (isset($originalLocations[$id][$timestamp])) {
                     $originalPath = $originalLocations[$id][$timestamp];
                     if (substr($originalPath, -1) === '/') {
                         $originalPath = substr($originalPath, 0, -1);
                     }
                 }
                 $i = array('name' => $id, 'mtime' => $timestamp, 'mimetype' => $view->is_dir($dir . '/' . $entryName) ? 'httpd/unix-directory' : \OC_Helper::getFileNameMimeType($id), 'type' => $view->is_dir($dir . '/' . $entryName) ? 'dir' : 'file', 'directory' => $dir === '/' ? '' : $dir, 'size' => $size);
                 if ($originalPath) {
                     $i['extraData'] = $originalPath . '/' . $id;
                 }
                 $result[] = new FileInfo($absoluteDir . '/' . $i['name'], $storage, $internalPath . '/' . $i['name'], $i, $mount);
             }
         }
         closedir($dirContent);
     }
     if ($sortAttribute !== '') {
         return \OCA\Files\Helper::sortFiles($result, $sortAttribute, $sortDescending);
     }
     return $result;
 }
Example #3
0
 protected function setUp()
 {
     parent::setUp();
     \OCA\Files_Trashbin\Trashbin::registerHooks();
     $this->folder = '/folder_share_storage_test';
     $this->filename = '/share-api-storage.txt';
     $this->view->mkdir($this->folder);
     // save file with content
     $this->view->file_put_contents($this->filename, "root file");
     $this->view->file_put_contents($this->folder . $this->filename, "file in subfolder");
 }
Example #4
0
 public function handle()
 {
     $userManager = \OC::$server->getUserManager();
     if (!$userManager->userExists($this->user)) {
         // User has been deleted already
         return;
     }
     \OC_Util::tearDownFS();
     \OC_Util::setupFS($this->user);
     Trashbin::expire($this->trashBinSize, $this->user);
     \OC_Util::tearDownFS();
 }
Example #5
0
 protected function setUp()
 {
     parent::setUp();
     \OC_Hook::clear();
     \OCA\Files_Trashbin\Trashbin::registerHooks();
     $this->user = $this->getUniqueId('user');
     \OC::$server->getUserManager()->createUser($this->user, $this->user);
     // this will setup the FS
     $this->loginAsUser($this->user);
     \OCA\Files_Trashbin\Storage::setupStorage();
     $this->rootView = new \OC\Files\View('/');
     $this->userView = new \OC\Files\View('/' . $this->user . '/files/');
     $this->userView->file_put_contents('test.txt', 'foo');
 }
Example #6
0
 /**
  * @param $argument
  * @throws \Exception
  */
 protected function run($argument)
 {
     $maxAge = $this->expiration->getMaxAgeAsTimestamp();
     if (!$maxAge) {
         return;
     }
     $this->userManager->callForAllUsers(function (IUser $user) {
         $uid = $user->getUID();
         if (!$this->setupFS($uid)) {
             return;
         }
         $dirContent = Helper::getTrashFiles('/', $uid, 'mtime');
         Trashbin::deleteExpiredFiles($dirContent, $uid);
     });
     \OC_Util::tearDownFS();
 }
Example #7
0
 /**
  * Retrieves the contents of a trash bin directory.
  *
  * @param string $dir path to the directory inside the trashbin
  * or empty to retrieve the root of the trashbin
  * @param string $user
  * @param string $sortAttribute attribute to sort on or empty to disable sorting
  * @param bool $sortDescending true for descending sort, false otherwise
  * @return \OCP\Files\FileInfo[]
  */
 public static function getTrashFiles($dir, $user, $sortAttribute = '', $sortDescending = false)
 {
     $result = array();
     $timestamp = null;
     $view = new \OC\Files\View('/' . $user . '/files_trashbin/files');
     if (ltrim($dir, '/') !== '' && !$view->is_dir($dir)) {
         throw new \Exception('Directory does not exists');
     }
     $mount = $view->getMount($dir);
     $storage = $mount->getStorage();
     $absoluteDir = $view->getAbsolutePath($dir);
     $internalPath = $mount->getInternalPath($absoluteDir);
     $originalLocations = \OCA\Files_Trashbin\Trashbin::getLocations($user);
     $dirContent = $storage->getCache()->getFolderContents($mount->getInternalPath($view->getAbsolutePath($dir)));
     foreach ($dirContent as $entry) {
         $entryName = $entry->getName();
         $id = $entry->getId();
         $name = $entryName;
         if ($dir === '' || $dir === '/') {
             $pathparts = pathinfo($entryName);
             $timestamp = substr($pathparts['extension'], 1);
             $name = $pathparts['filename'];
         } else {
             if ($timestamp === null) {
                 // for subfolders we need to calculate the timestamp only once
                 $parts = explode('/', ltrim($dir, '/'));
                 $timestamp = substr(pathinfo($parts[0], PATHINFO_EXTENSION), 1);
             }
         }
         $originalPath = '';
         if (isset($originalLocations[$id][$timestamp])) {
             $originalPath = $originalLocations[$id][$timestamp];
             if (substr($originalPath, -1) === '/') {
                 $originalPath = substr($originalPath, 0, -1);
             }
         }
         $i = array('name' => $name, 'mtime' => $timestamp, 'mimetype' => $entry->getMimeType(), 'type' => $entry->getMimeType() === ICacheEntry::DIRECTORY_MIMETYPE ? 'dir' : 'file', 'directory' => $dir === '/' ? '' : $dir, 'size' => $entry->getSize(), 'etag' => '', 'permissions' => Constants::PERMISSION_ALL - Constants::PERMISSION_SHARE);
         if ($originalPath) {
             $i['extraData'] = $originalPath . '/' . $id;
         }
         $result[] = new FileInfo($absoluteDir . '/' . $i['name'], $storage, $internalPath . '/' . $i['name'], $i, $mount);
     }
     if ($sortAttribute !== '') {
         return \OCA\Files\Helper::sortFiles($result, $sortAttribute, $sortDescending);
     }
     return $result;
 }
Example #8
0
 /**
  * test deletion of a folder which contains share mount points. Share mount
  * points should be unshared before the folder gets deleted so
  * that the mount point doesn't end up at the trash bin
  */
 function testDeleteParentFolder()
 {
     $status = \OC_App::isEnabled('files_trashbin');
     \OC_App::enable('files_trashbin');
     \OCA\Files_Trashbin\Trashbin::registerHooks();
     OC_FileProxy::register(new OCA\Files\Share\Proxy());
     $fileinfo = \OC\Files\Filesystem::getFileInfo($this->folder);
     $this->assertTrue($fileinfo instanceof \OC\Files\FileInfo);
     \OCP\Share::shareItem('folder', $fileinfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, 31);
     $this->loginHelper(self::TEST_FILES_SHARING_API_USER2);
     $view = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
     // check if user2 can see the shared folder
     $this->assertTrue($view->file_exists($this->folder));
     $foldersShared = \OCP\Share::getItemsSharedWith('folder');
     $this->assertSame(1, count($foldersShared));
     $view->mkdir("localFolder");
     $view->file_put_contents("localFolder/localFile.txt", "local file");
     $view->rename($this->folder, 'localFolder/' . $this->folder);
     // share mount point should now be moved to the subfolder
     $this->assertFalse($view->file_exists($this->folder));
     $this->assertTrue($view->file_exists('localFolder/' . $this->folder));
     $view->unlink('localFolder');
     $this->loginHelper(self::TEST_FILES_SHARING_API_USER2);
     // shared folder should be unshared
     $foldersShared = \OCP\Share::getItemsSharedWith('folder');
     $this->assertTrue(empty($foldersShared));
     // trashbin should contain the local file but not the mount point
     $rootView = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2);
     $trashContent = \OCA\Files_Trashbin\Helper::getTrashFiles('/', self::TEST_FILES_SHARING_API_USER2);
     $this->assertSame(1, count($trashContent));
     $firstElement = reset($trashContent);
     $timestamp = $firstElement['mtime'];
     $this->assertTrue($rootView->file_exists('files_trashbin/files/localFolder.d' . $timestamp . '/localFile.txt'));
     $this->assertFalse($rootView->file_exists('files_trashbin/files/localFolder.d' . $timestamp . '/' . $this->folder));
     //cleanup
     $rootView->deleteAll('files_trashin');
     if ($status === false) {
         \OC_App::disable('files_trashbin');
     }
     \OC\Files\Filesystem::getLoader()->removeStorageWrapper('oc_trashbin');
 }
Example #9
0
 /**
  * @param OCP\Files\FileInfo[] $files
  * @param integer $availableSpace
  */
 public function dummyDeleteFiles($files, $availableSpace)
 {
     return parent::deleteFiles($files, \Test_Trashbin::TEST_TRASHBIN_USER1, $availableSpace);
 }
Example #10
0
 public function handle()
 {
     \OC_Util::tearDownFS();
     \OC_Util::setupFS($this->user);
     Trashbin::expire($this->trashBinSize, $this->user);
 }
Example #11
0
File: app.php Project: hyb148/core
<?php

/**
 * @author Bart Visscher <*****@*****.**>
 * @author Björn Schießle <*****@*****.**>
 * @author Christopher Schäpers <*****@*****.**>
 * @author Florin Peter <*****@*****.**>
 * @author Robin Appelman <*****@*****.**>
 * @author Vincent Petry <*****@*****.**>
 *
 * @copyright Copyright (c) 2015, ownCloud, Inc.
 * @license AGPL-3.0
 *
 * This code is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License, version 3,
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 *
 */
$l = \OC::$server->getL10N('files_trashbin');
// register hooks
\OCA\Files_Trashbin\Trashbin::registerHooks();
\OCA\Files\App::getNavigationManager()->add(array("id" => 'trashbin', "appname" => 'files_trashbin', "script" => 'list.php', "order" => 50, "name" => $l->t('Deleted files')));
Example #12
0
    $tmpl->printPage();
} else {
    // information about storage capacities
    $storageInfo = OC_Helper::getStorageInfo($dir);
    $maxUploadFilesize = OCP\Util::maxUploadFilesize($dir);
    $publicUploadEnabled = \OC_Appconfig::getValue('core', 'shareapi_allow_public_upload', 'yes');
    // if the encryption app is disabled, than everything is fine (INIT_SUCCESSFUL status code)
    $encryptionInitStatus = 2;
    if (OC_App::isEnabled('files_encryption')) {
        $session = new \OCA\Encryption\Session(new \OC\Files\View('/'));
        $encryptionInitStatus = $session->getInitialized();
    }
    $trashEnabled = \OCP\App::isEnabled('files_trashbin');
    $trashEmpty = true;
    if ($trashEnabled) {
        $trashEmpty = \OCA\Files_Trashbin\Trashbin::isEmpty($user);
    }
    $isCreatable = \OC\Files\Filesystem::isCreatable($dir . '/');
    $fileHeader = (!isset($files) or count($files) > 0);
    $emptyContent = ($isCreatable and !$fileHeader) or $ajaxLoad;
    OCP\Util::addscript('files', 'fileactions');
    OCP\Util::addscript('files', 'files');
    OCP\Util::addscript('files', 'keyboardshortcuts');
    $tmpl = new OCP\Template('files', 'index', 'user');
    $tmpl->assign('fileList', $list->fetchPage());
    $tmpl->assign('breadcrumb', $breadcrumbNav->fetchPage());
    $tmpl->assign('dir', $dir);
    $tmpl->assign('isCreatable', $isCreatable);
    $tmpl->assign('permissions', $permissions);
    $tmpl->assign('files', $files);
    $tmpl->assign('trash', $trashEnabled);
Example #13
0
 /**
  * @medium
  * @brief test delete file forever
  */
 function testPermanentDeleteFile()
 {
     // generate filename
     $filename = 'tmp-' . time() . '.txt';
     // save file with content
     $cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/' . $filename, $this->dataShort);
     // test that data was successfully written
     $this->assertTrue(is_int($cryptedFile));
     // check if key for admin exists
     $this->assertTrue($this->view->file_exists('/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keyfiles/' . $filename . '.key'));
     // check if share key for admin exists
     $this->assertTrue($this->view->file_exists('/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/share-keys/' . $filename . '.' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey'));
     // delete file
     \OC\FIles\Filesystem::unlink($filename);
     // check if file not exists
     $this->assertFalse($this->view->file_exists('/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $filename));
     // check if key for admin not exists
     $this->assertFalse($this->view->file_exists('/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keyfiles/' . $filename . '.key'));
     // check if share key for admin not exists
     $this->assertFalse($this->view->file_exists('/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/share-keys/' . $filename . '.' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey'));
     // find created file with timestamp
     $query = \OC_DB::prepare('SELECT `timestamp`,`type` FROM `*PREFIX*files_trash`' . ' WHERE `id`=?');
     $result = $query->execute(array($filename))->fetchRow();
     $this->assertTrue(is_array($result));
     // build suffix
     $trashFileSuffix = 'd' . $result['timestamp'];
     // check if key for admin exists
     $this->assertTrue($this->view->file_exists('/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/keyfiles/' . $filename . '.key.' . $trashFileSuffix));
     // check if share key for admin exists
     $this->assertTrue($this->view->file_exists('/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/share-keys/' . $filename . '.' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey.' . $trashFileSuffix));
     // get timestamp from file
     $timestamp = str_replace('d', '', $trashFileSuffix);
     // delete file forever
     $this->assertGreaterThan(0, \OCA\Files_Trashbin\Trashbin::delete($filename, $timestamp));
     // check if key for admin not exists
     $this->assertFalse($this->view->file_exists('/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/files/' . $filename . '.' . $trashFileSuffix));
     // check if key for admin not exists
     $this->assertFalse($this->view->file_exists('/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/keyfiles/' . $filename . '.key.' . $trashFileSuffix));
     // check if share key for admin not exists
     $this->assertFalse($this->view->file_exists('/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/share-keys/' . $filename . '.' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey.' . $trashFileSuffix));
 }
Example #14
0
 /**
  * Run the delete operation with the given method
  *
  * @param string $path path of file or folder to delete
  * @param string $method either "unlink" or "rmdir"
  *
  * @return bool true if the operation succeeded, false otherwise
  */
 private function doDelete($path, $method)
 {
     if (self::$disableTrash || !\OC_App::isEnabled('files_trashbin') || pathinfo($path, PATHINFO_EXTENSION) === 'part' || $this->shouldMoveToTrash($path) === false) {
         return call_user_func_array([$this->storage, $method], [$path]);
     }
     // check permissions before we continue, this is especially important for
     // shared files
     if (!$this->isDeletable($path)) {
         return false;
     }
     $normalized = Filesystem::normalizePath($this->mountPoint . '/' . $path);
     $result = true;
     if (!isset($this->deletedFiles[$normalized])) {
         $view = Filesystem::getView();
         $this->deletedFiles[$normalized] = $normalized;
         if ($filesPath = $view->getRelativePath($normalized)) {
             $filesPath = trim($filesPath, '/');
             $result = \OCA\Files_Trashbin\Trashbin::move2trash($filesPath);
             // in cross-storage cases the file will be copied
             // but not deleted, so we delete it here
             if ($result) {
                 call_user_func_array([$this->storage, $method], [$path]);
             }
         } else {
             $result = call_user_func_array([$this->storage, $method], [$path]);
         }
         unset($this->deletedFiles[$normalized]);
     } else {
         if ($this->storage->file_exists($path)) {
             $result = call_user_func_array([$this->storage, $method], [$path]);
         }
     }
     return $result;
 }
Example #15
0
 function testDeleteSharedFile()
 {
     // generate filename
     $filename = 'tmp-' . $this->getUniqueID() . '.txt';
     // save file with content
     $cryptedFile = file_put_contents('crypt:///' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $filename, $this->dataShort);
     // test that data was successfully written
     $this->assertTrue(is_int($cryptedFile));
     // get the file info from previous created file
     $fileInfo = $this->view->getFileInfo('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $filename);
     // check if we have a valid file info
     $this->assertTrue($fileInfo instanceof \OC\Files\FileInfo);
     // share the file
     $this->assertTrue(\OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_ENCRYPTION_TRASHBIN_USER2, OCP\PERMISSION_ALL));
     self::loginHelper(self::TEST_ENCRYPTION_TRASHBIN_USER2);
     $this->assertTrue(\OC\Files\Filesystem::file_exists($filename));
     \OCA\Files_Trashbin\Trashbin::move2trash($filename);
     $query = \OC_DB::prepare('SELECT `timestamp` FROM `*PREFIX*files_trash`' . ' WHERE `id`=?');
     $result = $query->execute(array($filename))->fetchRow();
     $this->assertNotEmpty($result);
     $timestamp = $result['timestamp'];
     // check if key for both users exists
     $this->assertTrue($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/keyfiles/' . $filename . '.key.d' . $timestamp));
     // check if key for admin exists
     $this->assertTrue($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER2 . '/files_trashbin/keyfiles/' . $filename . '.key.d' . $timestamp));
     // check if share key for both users exists
     $this->assertTrue($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/share-keys/' . $filename . '.' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey.d' . $timestamp));
     $this->assertTrue($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER2 . '/files_trashbin/share-keys/' . $filename . '.' . self::TEST_ENCRYPTION_TRASHBIN_USER2 . '.shareKey.d' . $timestamp));
 }
Example #16
0
 /**
  * @param $argument
  * @throws \Exception
  */
 protected function run($argument)
 {
     $maxAge = $this->expiration->getMaxAgeAsTimestamp();
     if (!$maxAge) {
         return;
     }
     $offset = $this->config->getAppValue('files_trashbin', 'cronjob_user_offset', 0);
     $users = $this->userManager->search('', self::USERS_PER_SESSION, $offset);
     if (!count($users)) {
         // No users found, reset offset and retry
         $offset = 0;
         $users = $this->userManager->search('', self::USERS_PER_SESSION);
     }
     $offset += self::USERS_PER_SESSION;
     $this->config->setAppValue('files_trashbin', 'cronjob_user_offset', $offset);
     foreach ($users as $user) {
         $uid = $user->getUID();
         if (!$this->setupFS($uid)) {
             continue;
         }
         $dirContent = Helper::getTrashFiles('/', $uid, 'mtime');
         Trashbin::deleteExpiredFiles($dirContent, $uid);
     }
     \OC_Util::tearDownFS();
 }
Example #17
0
 /**
  * Restores a trashed note
  *
  * We try to mimic undelete.php to get all versions restored too.
  * @see owncloud/core/apps/files_trashbin/ajax/undelete.php
  *
  * @NoAdminRequired
  * @NoCSRFRequired
  * @CORS
  *
  * @return string
  */
 public function restoreTrashedNote()
 {
     $filename = $this->request->getParam("file_name");
     $timestamp = (int) $this->request->getParam("timestamp");
     $path = $filename . ".d{$timestamp}";
     $pathParts = pathinfo($path);
     $path = "//" . $pathParts['basename'];
     $pathParts = pathinfo($filename);
     $filename = $pathParts['basename'];
     $restoreResult = Trashbin::restore($path, $filename, $timestamp);
     $data = array();
     $data['result'] = $restoreResult;
     $data['path'] = $path;
     $data['filename'] = $filename;
     return $data;
 }