/** * store a new version of a file. */ public function store($filename) { if (\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED) == 'true') { list($uid, $filename) = self::getUidAndFilename($filename); $files_view = new \OC_FilesystemView('/' . $uid . '/files'); $users_view = new \OC_FilesystemView('/' . $uid); //check if source file already exist as version to avoid recursions. // todo does this check work? if ($users_view->file_exists($filename)) { return false; } // check if filename is a directory if ($files_view->is_dir($filename)) { return false; } // check filetype blacklist $blacklist = explode(' ', \OCP\Config::getSystemValue('files_versionsblacklist', Storage::DEFAULTBLACKLIST)); foreach ($blacklist as $bl) { $parts = explode('.', $filename); $ext = end($parts); if (strtolower($ext) == $bl) { return false; } } // we should have a source file to work with if (!$files_view->file_exists($filename)) { return false; } // check filesize if ($files_view->filesize($filename) > \OCP\Config::getSystemValue('files_versionsmaxfilesize', Storage::DEFAULTMAXFILESIZE)) { return false; } // check mininterval if the file is being modified by the owner (all shared files should be versioned despite mininterval) if ($uid == \OCP\User::getUser()) { $versions_fileview = new \OC_FilesystemView('/' . $uid . '/files_versions'); $versionsName = \OCP\Config::getSystemValue('datadirectory') . $versions_fileview->getAbsolutePath($filename); $versionsFolderName = \OCP\Config::getSystemValue('datadirectory') . $versions_fileview->getAbsolutePath(''); $matches = glob($versionsName . '.v*'); sort($matches); $parts = explode('.v', end($matches)); if (end($parts) + Storage::DEFAULTMININTERVAL > time()) { return false; } } // create all parent folders $info = pathinfo($filename); if (!file_exists($versionsFolderName . '/' . $info['dirname'])) { mkdir($versionsFolderName . '/' . $info['dirname'], 0750, true); } // store a new version of a file $users_view->copy('files' . $filename, 'files_versions' . $filename . '.v' . time()); // expire old revisions if necessary Storage::expire($filename); } }
/** * rollback to an old version of a file. */ public static function rollback($file, $revision) { if (\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED) == 'true') { list($uid, $filename) = self::getUidAndFilename($file); $users_view = new \OC\Files\View('/' . $uid); $files_view = new \OC\Files\View('/' . \OCP\User::getUser() . '/files'); $versionCreated = false; //first create a new version $version = 'files_versions' . $filename . '.v' . $users_view->filemtime('files' . $filename); if (!$users_view->file_exists($version)) { // disable proxy to prevent multiple fopen calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; $users_view->copy('files' . $filename, 'files_versions' . $filename . '.v' . $users_view->filemtime('files' . $filename)); // reset proxy state \OC_FileProxy::$enabled = $proxyStatus; $versionCreated = true; } // rollback if (@$users_view->rename('files_versions' . $filename . '.v' . $revision, 'files' . $filename)) { $files_view->touch($file, $revision); Storage::expire($file); return true; } else { if ($versionCreated) { $users_view->unlink($version); } } } return false; }
/** * store a new version of a file. */ public static function store($filename) { if (\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED) == 'true') { if (\OCP\App::isEnabled('files_sharing') && ($source = \OC_Share::getSource('/' . \OCP\User::getUser() . '/files' . $filename))) { $pos = strpos($source, '/files', 1); $uid = substr($source, 1, $pos - 1); $filename = substr($source, $pos + 6); } else { $uid = \OCP\User::getUser(); } $versionsfoldername = \OCP\Config::getSystemValue('datadirectory') . '/' . $uid . '/' . \OCP\Config::getSystemValue('files_versionsfolder', Storage::DEFAULTFOLDER); $filesfoldername = \OCP\Config::getSystemValue('datadirectory') . '/' . $uid . '/files'; Storage::init(); // check if filename is a directory if (is_dir($filesfoldername . '/' . $filename)) { return false; } // check filetype blacklist $blacklist = explode(' ', \OCP\Config::getSystemValue('files_versionsblacklist', Storage::DEFAULTBLACKLIST)); foreach ($blacklist as $bl) { $parts = explode('.', $filename); $ext = end($parts); if (strtolower($ext) == $bl) { return false; } } // check filesize if (filesize($filesfoldername . '/' . $filename) > \OCP\Config::getSystemValue('files_versionsmaxfilesize', Storage::DEFAULTMAXFILESIZE)) { return false; } // check mininterval if the file is being modified by the owner (all shared files should be versioned despite mininterval) if ($uid == \OCP\User::getUser()) { $matches = glob($versionsfoldername . '/' . $filename . '.v*'); sort($matches); $parts = explode('.v', end($matches)); if (end($parts) + Storage::DEFAULTMININTERVAL > time()) { return false; } } // create all parent folders $info = pathinfo($filename); @mkdir($versionsfoldername . '/' . $info['dirname'], 0700, true); // store a new version of a file copy($filesfoldername . '/' . $filename, $versionsfoldername . '/' . $filename . '.v' . time()); // expire old revisions Storage::expire($filename); } }