diff --git a/.jshintrc b/.jshintrc index 77f9e9f143d4c155ea03549df18202cef36decd4..d5da3e30828193581ecb113f423a69ab83e02bf6 100644 --- a/.jshintrc +++ b/.jshintrc @@ -26,6 +26,7 @@ "fakeServer": true, "_": true, "OC": true, + "OCA": true, "t": true, "n": true } diff --git a/apps/files/ajax/list.php b/apps/files/ajax/list.php index 2d76b685018fec0f690b154672ae0f5c149774bd..bae3628402f73d4303b3625f8555b51a77d8cd84 100644 --- a/apps/files/ajax/list.php +++ b/apps/files/ajax/list.php @@ -17,8 +17,11 @@ $baseUrl = OCP\Util::linkTo('files', 'index.php') . '?dir='; $permissions = $dirInfo->getPermissions(); +$sortAttribute = isset( $_GET['sort'] ) ? $_GET['sort'] : 'name'; +$sortDirection = isset( $_GET['sortdirection'] ) ? ($_GET['sortdirection'] === 'desc') : false; + // make filelist -$files = \OCA\Files\Helper::getFiles($dir); +$files = \OCA\Files\Helper::getFiles($dir, $sortAttribute, $sortDirection); $data['directory'] = $dir; $data['files'] = \OCA\Files\Helper::formatFileInfos($files); diff --git a/apps/files/appinfo/app.php b/apps/files/appinfo/app.php index 15a29133789d33a82a3f687aba758d09884e1718..4b0db457ada50bb8812d216b6fd9438be8dee033 100644 --- a/apps/files/appinfo/app.php +++ b/apps/files/appinfo/app.php @@ -19,3 +19,13 @@ $templateManager->registerTemplate('text/html', 'core/templates/filetemplates/te $templateManager->registerTemplate('application/vnd.oasis.opendocument.presentation', 'core/templates/filetemplates/template.odp'); $templateManager->registerTemplate('application/vnd.oasis.opendocument.text', 'core/templates/filetemplates/template.odt'); $templateManager->registerTemplate('application/vnd.oasis.opendocument.spreadsheet', 'core/templates/filetemplates/template.ods'); + +\OCA\Files\App::getNavigationManager()->add( + array( + "id" => 'files', + "appname" => 'files', + "script" => 'list.php', + "order" => 0, + "name" => $l->t('All files') + ) +); diff --git a/apps/files/appinfo/update.php b/apps/files/appinfo/update.php deleted file mode 100644 index f920f842166700a16c8c75ad059f28117998adbc..0000000000000000000000000000000000000000 --- a/apps/files/appinfo/update.php +++ /dev/null @@ -1,46 +0,0 @@ -getDatabasePlatform()-> - getConcatExpression( '\'{DAV:}\'', '`propertyname`' ); - $query = OC_DB::prepare(' - UPDATE `*PREFIX*properties` - SET `propertyname` = ' . $concat . ' - WHERE `propertyname` NOT LIKE \'{%\' - '); - $query->execute(); -} - -//update from OC 3 - -//try to remove remaining files. -//Give a warning if not possible - -$filesToRemove = array( - 'ajax', - 'appinfo', - 'css', - 'js', - 'l10n', - 'templates', - 'admin.php', - 'download.php', - 'index.php', - 'settings.php' -); - -foreach($filesToRemove as $file) { - $filepath = OC::$SERVERROOT . '/files/' . $file; - if(!file_exists($filepath)) { - continue; - } - $success = OCP\Files::rmdirr($filepath); - if($success === false) { - //probably not sufficient privileges, give up and give a message. - OCP\Util::writeLog('files', 'Could not clean /files/ directory.' - .' Please remove everything except webdav.php from ' . OC::$SERVERROOT . '/files/', OCP\Util::ERROR); - break; - } -} diff --git a/apps/files/css/files.css b/apps/files/css/files.css index 533050691d5e75b94bce6bcf047eec6828dfa1ea..009cb355ba7d33a01720539900ca3c2f5c5c17c3 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -3,10 +3,11 @@ See the COPYING-README file. */ /* FILE MENU */ -.actions { padding:5px; height:32px; width: 100%; } +.actions { padding:5px; height:32px; display: inline-block; float: left; } .actions input, .actions button, .actions .button { margin:0; float:left; } .actions .button a { color: #555; } .actions .button a:hover, .actions .button a:active { color: #333; } +.actions.hidden { display: none; } #new { z-index: 1010; @@ -75,6 +76,7 @@ top: 44px; width: 100%; } + /* make sure there's enough room for the file actions */ #body-user #filestable { min-width: 688px; /* 768 (mobile break) - 80 (nav width) */ @@ -83,6 +85,40 @@ min-width: 688px; /* 768 (mobile break) - 80 (nav width) */ } +#filestable tbody tr { background-color:#fff; height:51px; } + +.app-files #app-content { + position: relative; +} + +/** + * Override global #controls styles + * to be more flexible / relative + */ +#body-user .app-files #controls { + left: 310px; /* main nav bar + sidebar */ + position: fixed; + padding-left: 0px; +} + +/* this is mostly for file viewer apps, text editor, etc */ +#body-user .app-files.no-sidebar #controls { + left: 0px; + padding-left: 80px; /* main nav bar */ +} + +.app-files #app-navigation { + width: 230px; +} + +.app-files #app-settings { + width: 229px; /* DUH */ +} + +.app-files #app-settings input { + width: 90%; +} + #filestable tbody tr { background-color:#fff; height:40px; } #filestable tbody tr:hover, tbody tr:active { background-color: rgb(240,240,240); @@ -116,10 +152,29 @@ tr:hover span.extension { table tr.mouseOver td { background-color:#eee; } table th { height:24px; padding:0 8px; color:#999; } -table th .name { - position: absolute; - left: 55px; - top: 15px; +table th .columntitle { + display: inline-block; + padding: 15px; + width: 100%; + height: 50px; + box-sizing: border-box; + -moz-box-sizing: border-box; + vertical-align: middle; +} +table th .columntitle.name { + padding-left: 5px; + margin-left: 50px; + max-width: 300px; +} +/* hover effect on sortable column */ +table th a.columntitle:hover { + background-color: #F0F0F0; +} +table th .sort-indicator { + width: 10px; + height: 8px; + margin-left: 10px; + display: inline-block; } table th, table td { border-bottom:1px solid #ddd; text-align:left; font-weight:normal; } table td { @@ -139,8 +194,11 @@ table th#headerName { } table th#headerSize, table td.filesize { min-width: 48px; - padding: 0 16px; text-align: right; + padding: 0; +} +table table td.filesize { + padding: 0 16px; } table th#headerDate, table td.date { -moz-box-sizing: border-box; @@ -161,9 +219,7 @@ table.multiselect thead { z-index: 10; -moz-box-sizing: border-box; box-sizing: border-box; - left: 0; - padding-left: 80px; - width: 100%; + left: 310px; /* main nav bar + sidebar */ } table.multiselect thead th { @@ -197,10 +253,6 @@ table td.filename input.filename { table td.filename a, table td.login, table td.logout, table td.download, table td.upload, table td.create, table td.delete { padding:3px 8px 8px 3px; } table td.filename .nametext, .uploadtext, .modified { float:left; padding:14px 0; } -#modified { - position: absolute; - top: 15px; -} .modified { position: relative; padding-left: 8px; @@ -254,7 +306,7 @@ table td.filename form { font-size:14px; margin-left:48px; margin-right:48px; } /* Use label to have bigger clickable size for checkbox */ #fileList tr td.filename>input[type="checkbox"] + label, -#select_all + label { +.select-all + label { height: 50px; position: absolute; width: 50px; @@ -268,10 +320,10 @@ table td.filename form { font-size:14px; margin-left:48px; margin-right:48px; } #fileList tr td.filename>input[type="checkbox"] + label { left: 0; } -#select_all + label { +.select-all + label { top: 0; } -#select_all { +.select-all { position: absolute; top: 18px; left: 18px; @@ -319,6 +371,9 @@ a.action>img { max-height:16px; max-width:16px; vertical-align:text-bottom; } display: inline; padding: 17px 5px; } +.selectedActions a.hidden { + display: none; +} .selectedActions a img { position:relative; top:5px; @@ -394,7 +449,7 @@ table.dragshadow td.size { } .mask { z-index: 50; - position: fixed; + position: absolute; top: 0; left: 0; right: 0; diff --git a/apps/files/index.php b/apps/files/index.php index a4e9a938507c36541cb7df9f0f600d577095074a..e24c535cb208cab1488194ddadc29bb5e444b970 100644 --- a/apps/files/index.php +++ b/apps/files/index.php @@ -28,6 +28,7 @@ OCP\User::checkLoggedIn(); OCP\Util::addStyle('files', 'files'); OCP\Util::addStyle('files', 'upload'); OCP\Util::addStyle('files', 'mobile'); +OCP\Util::addscript('files', 'app'); OCP\Util::addscript('files', 'file-upload'); OCP\Util::addscript('files', 'jquery.iframe-transport'); OCP\Util::addscript('files', 'jquery.fileupload'); @@ -37,28 +38,23 @@ OCP\Util::addscript('files', 'breadcrumb'); OCP\Util::addscript('files', 'filelist'); OCP\App::setActiveNavigationEntry('files_index'); -// Load the files -$dir = isset($_GET['dir']) ? stripslashes($_GET['dir']) : ''; -$dir = \OC\Files\Filesystem::normalizePath($dir); -$dirInfo = \OC\Files\Filesystem::getFileInfo($dir, false); -// Redirect if directory does not exist -if (!$dirInfo || !$dirInfo->getType() === 'dir') { - header('Location: ' . OCP\Util::getScriptName() . ''); - exit(); -} $isIE8 = false; preg_match('/MSIE (.*?);/', $_SERVER['HTTP_USER_AGENT'], $matches); -if (count($matches) > 0 && $matches[1] <= 8){ +if (count($matches) > 0 && $matches[1] <= 9) { $isIE8 = true; } -// if IE8 and "?dir=path" was specified, reformat the URL to use a hash like "#?dir=path" -if ($isIE8 && isset($_GET['dir'])){ - if ($dir === ''){ - $dir = '/'; +// if IE8 and "?dir=path&view=someview" was specified, reformat the URL to use a hash like "#?dir=path&view=someview" +if ($isIE8 && (isset($_GET['dir']) || isset($_GET['view']))) { + $hash = '#?'; + $dir = isset($_GET['dir']) ? $_GET['dir'] : '/'; + $view = isset($_GET['view']) ? $_GET['view'] : 'files'; + $hash = '#?dir=' . \OCP\Util::encodePath($dir); + if ($view !== 'files') { + $hash .= '&view=' . urlencode($view); } - header('Location: ' . OCP\Util::linkTo('files', 'index.php') . '#?dir=' . \OCP\Util::encodePath($dir)); + header('Location: ' . OCP\Util::linkTo('files', 'index.php') . $hash); exit(); } @@ -66,49 +62,62 @@ $user = OC_User::getUser(); $config = \OC::$server->getConfig(); -// needed for share init, permissions will be reloaded -// anyway with ajax load -$permissions = $dirInfo->getPermissions(); - -// information about storage capacities -$storageInfo=OC_Helper::getStorageInfo($dir, $dirInfo); -$freeSpace=$storageInfo['free']; -$uploadLimit=OCP\Util::uploadLimit(); -$maxUploadFilesize=OCP\Util::maxUploadFilesize($dir, $freeSpace); -$publicUploadEnabled = $config->getAppValue('core', 'shareapi_allow_public_upload', 'yes'); +// mostly for the home storage's free space +$dirInfo = \OC\Files\Filesystem::getFileInfo('/', false); +$storageInfo=OC_Helper::getStorageInfo('/', $dirInfo); // 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(); + $session = new \OCA\Encryption\Session(new \OC\Files\View('/')); + $encryptionInitStatus = $session->getInitialized(); +} + +$nav = new OCP\Template('files', 'appnavigation', ''); + +$navItems = \OCA\Files\App::getNavigationManager()->getAll(); +$nav->assign('navigationItems', $navItems); + +$contentItems = array(); + +function renderScript($appName, $scriptName) { + $content = ''; + $appPath = OC_App::getAppPath($appName); + $scriptPath = $appPath . '/' . $scriptName; + if (file_exists($scriptPath)) { + // TODO: sanitize path / script name ? + ob_start(); + include $scriptPath; + $content = ob_get_contents(); + @ob_end_clean(); + } + return $content; } -$trashEnabled = \OCP\App::isEnabled('files_trashbin'); -$trashEmpty = true; -if ($trashEnabled) { - $trashEmpty = \OCA\Files_Trashbin\Trashbin::isEmpty($user); +// render the container content for every navigation item +foreach ($navItems as $item) { + $content = ''; + if (isset($item['script'])) { + $content = renderScript($item['appname'], $item['script']); + } + $contentItem = array(); + $contentItem['id'] = $item['id']; + $contentItem['content'] = $content; + $contentItems[] = $contentItem; } OCP\Util::addscript('files', 'fileactions'); OCP\Util::addscript('files', 'files'); +OCP\Util::addscript('files', 'navigation'); OCP\Util::addscript('files', 'keyboardshortcuts'); $tmpl = new OCP\Template('files', 'index', 'user'); -$tmpl->assign('dir', $dir); -$tmpl->assign('permissions', $permissions); -$tmpl->assign('trash', $trashEnabled); -$tmpl->assign('trashEmpty', $trashEmpty); -$tmpl->assign('uploadMaxFilesize', $maxUploadFilesize); // minimium of freeSpace and uploadLimit -$tmpl->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize)); -$tmpl->assign('freeSpace', $freeSpace); -$tmpl->assign('uploadLimit', $uploadLimit); // PHP upload limit -$tmpl->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true))); $tmpl->assign('usedSpacePercent', (int)$storageInfo['relative']); $tmpl->assign('isPublic', false); -$tmpl->assign('publicUploadEnabled', $publicUploadEnabled); $tmpl->assign("encryptedFiles", \OCP\Util::encryptedFiles()); $tmpl->assign("mailNotificationEnabled", $config->getAppValue('core', 'shareapi_allow_mail_notification', 'yes')); $tmpl->assign("allowShareWithLink", $config->getAppValue('core', 'shareapi_allow_links', 'yes')); $tmpl->assign("encryptionInitStatus", $encryptionInitStatus); -$tmpl->assign('disableSharing', false); +$tmpl->assign('appNavigation', $nav); +$tmpl->assign('appContents', $contentItems); +$tmpl->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true))); $tmpl->printPage(); diff --git a/apps/files/js/app.js b/apps/files/js/app.js new file mode 100644 index 0000000000000000000000000000000000000000..9155fb38cdbeee986ac6d21194e92651c98d47e1 --- /dev/null +++ b/apps/files/js/app.js @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2014 + * + * @author Vincent Petry + * @copyright 2014 Vincent Petry + * + * This file is licensed under the Affero General Public License version 3 + * or later. + * + * See the COPYING-README file. + * + */ + +/* global dragOptions, folderDropOptions */ +(function() { + + if (!OCA.Files) { + OCA.Files = {}; + } + + var App = { + navigation: null, + + initialize: function() { + this.navigation = new OCA.Files.Navigation($('#app-navigation')); + + // TODO: ideally these should be in a separate class / app (the embedded "all files" app) + this.fileActions = OCA.Files.FileActions; + this.files = OCA.Files.Files; + + this.fileList = new OCA.Files.FileList( + $('#app-content-files'), { + scrollContainer: $('#app-content'), + dragOptions: dragOptions, + folderDropOptions: folderDropOptions + } + ); + this.files.initialize(); + this.fileActions.registerDefaultActions(this.fileList); + this.fileList.setFileActions(this.fileActions); + + // for backward compatibility, the global FileList will + // refer to the one of the "files" view + window.FileList = this.fileList; + + this._setupEvents(); + // trigger URL change event handlers + this._onPopState(OC.Util.History.parseUrlQuery()); + }, + + /** + * Returns the container of the currently visible app. + * + * @return app container + */ + getCurrentAppContainer: function() { + return this.navigation.getActiveContainer(); + }, + + /** + * Setup events based on URL changes + */ + _setupEvents: function() { + OC.Util.History.addOnPopStateHandler(_.bind(this._onPopState, this)); + + // detect when app changed their current directory + $('#app-content').delegate('>div', 'changeDirectory', _.bind(this._onDirectoryChanged, this)); + $('#app-content').delegate('>div', 'changeViewerMode', _.bind(this._onChangeViewerMode, this)); + + $('#app-navigation').on('itemChanged', _.bind(this._onNavigationChanged, this)); + }, + + /** + * Event handler for when the current navigation item has changed + */ + _onNavigationChanged: function(e) { + var params; + if (e && e.itemId) { + params = { + view: e.itemId, + dir: '/' + }; + this._changeUrl(params.view, params.dir); + this.navigation.getActiveContainer().trigger(new $.Event('urlChanged', params)); + } + }, + + /** + * Event handler for when an app notified that its directory changed + */ + _onDirectoryChanged: function(e) { + if (e.dir) { + this._changeUrl(this.navigation.getActiveItem(), e.dir); + } + }, + + /** + * Event handler for when an app notifies that it needs space + * for viewer mode. + */ + _onChangeViewerMode: function(e) { + var state = !!e.viewerModeEnabled; + $('#app-navigation').toggleClass('hidden', state); + $('.app-files').toggleClass('viewer-mode no-sidebar', state); + }, + + /** + * Event handler for when the URL changed + */ + _onPopState: function(params) { + params = _.extend({ + dir: '/', + view: 'files' + }, params); + var lastId = this.navigation.getActiveItem(); + if (!this.navigation.itemExists(params.view)) { + params.view = 'files'; + } + this.navigation.setActiveItem(params.view, {silent: true}); + if (lastId !== this.navigation.getActiveItem()) { + this.navigation.getActiveContainer().trigger(new $.Event('show')); + } + this.navigation.getActiveContainer().trigger(new $.Event('urlChanged', params)); + }, + + /** + * Change the URL to point to the given dir and view + */ + _changeUrl: function(view, dir) { + var params = {dir: dir}; + if (view !== 'files') { + params.view = view; + } + OC.Util.History.pushState(params); + } + }; + OCA.Files.App = App; +})(); + +$(document).ready(function() { + // wait for other apps/extensions to register their event handlers + // in the "ready" clause + _.defer(function() { + OCA.Files.App.initialize(); + }); +}); + diff --git a/apps/files/js/breadcrumb.js b/apps/files/js/breadcrumb.js index 5bc2fac13695d29940872c4dfa6e76931035e923..c017d710d6decad7830193b7a3d4bccc53bc4c02 100644 --- a/apps/files/js/breadcrumb.js +++ b/apps/files/js/breadcrumb.js @@ -159,7 +159,11 @@ this.totalWidth = 64; // FIXME: this class should not know about global elements if ( $('#navigation').length ) { - this.totalWidth += $('#navigation').get(0).offsetWidth; + this.totalWidth += $('#navigation').outerWidth(); + } + + if ( $('#app-navigation').length && !$('#app-navigation').hasClass('hidden')) { + this.totalWidth += $('#app-navigation').outerWidth(); } this.hiddenBreadcrumbs = 0; @@ -167,8 +171,8 @@ this.totalWidth += $(this.breadcrumbs[i]).get(0).offsetWidth; } - $.each($('#controls .actions>div'), function(index, action) { - self.totalWidth += $(action).get(0).offsetWidth; + $.each($('#controls .actions'), function(index, action) { + self.totalWidth += $(action).outerWidth(); }); }, @@ -236,6 +240,6 @@ } }; - window.BreadCrumb = BreadCrumb; + OCA.Files.BreadCrumb = BreadCrumb; })(); diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js index 963fc6478287fa5f26ef2d426c2fbfbcefcbdf36..6b0ca793681089edd304deae6ae05d531546b15e 100644 --- a/apps/files/js/file-upload.js +++ b/apps/files/js/file-upload.js @@ -18,7 +18,7 @@ * - TODO music upload button */ -/* global OC, t, n */ +/* global Files, FileList, jQuery, oc_requesttoken, humanFileSize, getUniqueName */ /** * Function that will allow us to know if Ajax uploads are supported @@ -65,7 +65,7 @@ OC.Upload = { */ cancelUploads:function() { this.log('canceling uploads'); - jQuery.each(this._uploads,function(i, jqXHR) { + jQuery.each(this._uploads, function(i, jqXHR) { jqXHR.abort(); }); this._uploads = []; @@ -83,7 +83,7 @@ OC.Upload = { isProcessing:function() { var count = 0; - jQuery.each(this._uploads,function(i, data) { + jQuery.each(this._uploads, function(i, data) { if (data.state() === 'pending') { count++; } @@ -205,14 +205,16 @@ OC.Upload = { */ add: function(e, data) { OC.Upload.log('add', e, data); - var that = $(this); - var freeSpace; + var that = $(this), freeSpace; - // we need to collect all data upload objects before starting the upload so we can check their existence - // and set individual conflict actions. unfortunately there is only one variable that we can use to identify - // the selection a data upload is part of, so we have to collect them in data.originalFiles - // turning singleFileUploads off is not an option because we want to gracefully handle server errors like - // already exists + // we need to collect all data upload objects before + // starting the upload so we can check their existence + // and set individual conflict actions. Unfortunately, + // there is only one variable that we can use to identify + // the selection a data upload is part of, so we have to + // collect them in data.originalFiles turning + // singleFileUploads off is not an option because we want + // to gracefully handle server errors like 'already exists' // create a container where we can store the data objects if ( ! data.originalFiles.selection ) { @@ -244,14 +246,15 @@ OC.Upload = { // in case folder drag and drop is not supported file will point to a directory // http://stackoverflow.com/a/20448357 - if (!file.type && file.size%4096 === 0 && file.size <= 102400) { + if ( ! file.type && file.size%4096 === 0 && file.size <= 102400) { try { - reader = new FileReader(); - reader.readAsBinaryString(f); + var reader = new FileReader(); + reader.readAsBinaryString(file); } catch (NS_ERROR_FILE_ACCESS_DENIED) { //file is a directory data.textStatus = 'dirorzero'; - data.errorThrown = t('files', 'Unable to upload {filename} as it is a directory or has 0 bytes', + data.errorThrown = t('files', + 'Unable to upload {filename} as it is a directory or has 0 bytes', {filename: file.name} ); } @@ -263,7 +266,8 @@ OC.Upload = { // check PHP upload limit if (selection.totalBytes > $('#upload_limit').val()) { data.textStatus = 'sizeexceedlimit'; - data.errorThrown = t('files', 'Total file size {size1} exceeds upload limit {size2}', { + data.errorThrown = t('files', + 'Total file size {size1} exceeds upload limit {size2}', { 'size1': humanFileSize(selection.totalBytes), 'size2': humanFileSize($('#upload_limit').val()) }); @@ -273,7 +277,8 @@ OC.Upload = { freeSpace = $('#free_space').val(); if (freeSpace >= 0 && selection.totalBytes > freeSpace) { data.textStatus = 'notenoughspace'; - data.errorThrown = t('files', 'Not enough free space, you are uploading {size1} but only {size2} is left', { + data.errorThrown = t('files', + 'Not enough free space, you are uploading {size1} but only {size2} is left', { 'size1': humanFileSize(selection.totalBytes), 'size2': humanFileSize($('#free_space').val()) }); @@ -341,7 +346,7 @@ OC.Upload = { // noone set update parameters, we set the minimum data.formData = { requesttoken: oc_requesttoken, - dir: $('#dir').val(), + dir: FileList.getCurrentDirectory(), file_directory: fileDirectory }; } @@ -384,31 +389,29 @@ OC.Upload = { //fetch response from iframe response = data.result[0].body.innerText; } - var result=$.parseJSON(response); + var result = $.parseJSON(response); delete data.jqXHR; + var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload'); + if (result.status === 'error' && result.data && result.data.message){ data.textStatus = 'servererror'; data.errorThrown = result.data.message; - var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload'); fu._trigger('fail', e, data); } else if (typeof result[0] === 'undefined') { data.textStatus = 'servererror'; data.errorThrown = t('files', 'Could not get result from server.'); - var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload'); fu._trigger('fail', e, data); } else if (result[0].status === 'existserror') { //show "file already exists" dialog var original = result[0]; var replacement = data.files[0]; - var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload'); OC.dialogs.fileexists(data, original, replacement, OC.Upload, fu); } else if (result[0].status !== 'success') { //delete data.jqXHR; data.textStatus = 'servererror'; data.errorThrown = result[0].data.message; // error message has been translated on server - var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload'); fu._trigger('fail', e, data); } }, @@ -440,7 +443,7 @@ OC.Upload = { fileupload.on('fileuploadstart', function(e, data) { OC.Upload.log('progress handle fileuploadstart', e, data); $('#uploadprogresswrapper input.stop').show(); - $('#uploadprogressbar').progressbar({value:0}); + $('#uploadprogressbar').progressbar({value: 0}); $('#uploadprogressbar').fadeIn(); }); fileupload.on('fileuploadprogress', function(e, data) { @@ -457,7 +460,6 @@ OC.Upload = { $('#uploadprogresswrapper input.stop').fadeOut(); $('#uploadprogressbar').fadeOut(); - Files.updateStorageStatistics(); }); fileupload.on('fileuploadfail', function(e, data) { OC.Upload.log('progress handle fileuploadfail', e, data); @@ -468,8 +470,6 @@ OC.Upload = { } }); - } else { - console.log('skipping file progress because your browser is broken'); } } @@ -509,7 +509,7 @@ OC.Upload = { $('#new li').each(function(i,element) { if ($(element).children('p').length === 0) { $(element).children('form').remove(); - $(element).append('

'+$(element).data('text')+'

'); + $(element).append('

' + $(element).data('text') + '

'); } }); }); @@ -527,16 +527,16 @@ OC.Upload = { $('#new .error').tipsy('hide'); - $('#new li').each(function(i,element) { + $('#new li').each(function(i, element) { if ($(element).children('p').length === 0) { $(element).children('form').remove(); - $(element).append('

'+$(element).data('text')+'

'); + $(element).append('

' + $(element).data('text') + '

'); } }); - var type=$(this).data('type'); - var text=$(this).children('p').text(); - $(this).data('text',text); + var type = $(this).data('type'); + var text = $(this).children('p').text(); + $(this).data('text', text); $(this).children('p').remove(); // add input field @@ -553,7 +553,7 @@ OC.Upload = { var filename = input.val(); if (type === 'web' && filename.length === 0) { throw t('files', 'URL cannot be empty'); - } else if (type !== 'web' && !Files.isFileNameValid(filename)) { + } else if (type !== 'web' && ! Files.isFileNameValid(filename)) { // Files.isFileNameValid(filename) throws an exception itself } else if (FileList.inList(filename)) { throw t('files', '{new_name} already exists', {new_name: filename}); @@ -592,7 +592,7 @@ OC.Upload = { if (FileList.lastAction) { FileList.lastAction(); } - var name = getUniqueName(newname); + var name = FileList.getUniqueName(newname); if (newname !== name) { FileList.checkName(name, newname, true); var hidden = true; @@ -603,7 +603,10 @@ OC.Upload = { case 'file': $.post( OC.filePath('files', 'ajax', 'newfile.php'), - {dir:$('#dir').val(), filename:name}, + { + dir: FileList.getCurrentDirectory(), + filename: name + }, function(result) { if (result.status === 'success') { FileList.add(result.data, {hidden: hidden, animate: true}); @@ -616,7 +619,10 @@ OC.Upload = { case 'folder': $.post( OC.filePath('files','ajax','newfolder.php'), - {dir:$('#dir').val(), foldername:name}, + { + dir: FileList.getCurrentDirectory(), + foldername: name + }, function(result) { if (result.status === 'success') { FileList.add(result.data, {hidden: hidden, animate: true}); @@ -627,39 +633,46 @@ OC.Upload = { ); break; case 'web': - if (name.substr(0,8) !== 'https://' && name.substr(0,7) !== 'http://') { + if (name.substr(0, 8) !== 'https://' && name.substr(0, 7) !== 'http://') { name = 'http://' + name; } - var localName=name; - if (localName.substr(localName.length-1,1)==='/') {//strip / - localName=localName.substr(0,localName.length-1); + var localName = name; + if (localName.substr(localName.length-1, 1) === '/') {//strip / + localName = localName.substr(0, localName.length-1); } - if (localName.indexOf('/')) {//use last part of url - localName=localName.split('/').pop(); + if (localName.indexOf('/')) { //use last part of url + localName = localName.split('/').pop(); } else { //or the domain - localName=(localName.match(/:\/\/(.[^\/]+)/)[1]).replace('www.',''); + localName = (localName.match(/:\/\/(.[^\/]+)/)[1]).replace('www.', ''); } - localName = getUniqueName(localName); + localName = FileList.getUniqueName(localName); //IE < 10 does not fire the necessary events for the progress bar. if ($('html.lte9').length === 0) { - $('#uploadprogressbar').progressbar({value:0}); + $('#uploadprogressbar').progressbar({value: 0}); $('#uploadprogressbar').fadeIn(); } - var eventSource=new OC.EventSource(OC.filePath('files','ajax','newfile.php'),{dir:$('#dir').val(),source:name,filename:localName}); - eventSource.listen('progress',function(progress) { + var eventSource = new OC.EventSource( + OC.filePath('files', 'ajax', 'newfile.php'), + { + dir: FileList.getCurrentDirectory(), + source: name, + filename: localName + } + ); + eventSource.listen('progress', function(progress) { //IE < 10 does not fire the necessary events for the progress bar. if ($('html.lte9').length === 0) { $('#uploadprogressbar').progressbar('value',progress); } }); - eventSource.listen('success',function(data) { + eventSource.listen('success', function(data) { var file = data; $('#uploadprogressbar').fadeOut(); FileList.add(file, {hidden: hidden, animate: true}); }); - eventSource.listen('error',function(error) { + eventSource.listen('error', function(error) { $('#uploadprogressbar').fadeOut(); var message = (error && error.message) || t('core', 'Error fetching URL'); OC.Notification.show(message); @@ -670,12 +683,12 @@ OC.Upload = { }); break; } - var li=form.parent(); + var li = form.parent(); form.remove(); /* workaround for IE 9&10 click event trap, 2 lines: */ $('input').first().focus(); $('#content').focus(); - li.append('

'+li.data('text')+'

'); + li.append('

' + li.data('text') + '

'); $('#new>a').click(); } catch (error) { input.attr('title', error); diff --git a/apps/files/js/fileactions.js b/apps/files/js/fileactions.js index ecdfa72a477eb00d7b8f0b07a892ec8b6e6d35b0..b9cd9816d4c8bed99fde48bf3d003f11a3940c11 100644 --- a/apps/files/js/fileactions.js +++ b/apps/files/js/fileactions.js @@ -8,242 +8,255 @@ * */ -/* global OC, FileList, Files */ /* global trashBinApp */ -var FileActions = { - actions: {}, - defaults: {}, - icons: {}, - currentFile: null, - register: function (mime, name, permissions, icon, action, displayName) { - if (!FileActions.actions[mime]) { - FileActions.actions[mime] = {}; - } - if (!FileActions.actions[mime][name]) { - FileActions.actions[mime][name] = {}; - } - if (!displayName) { - displayName = t('files', name); - } - FileActions.actions[mime][name]['action'] = action; - FileActions.actions[mime][name]['permissions'] = permissions; - FileActions.actions[mime][name]['displayName'] = displayName; - FileActions.icons[name] = icon; - }, - setDefault: function (mime, name) { - FileActions.defaults[mime] = name; - }, - get: function (mime, type, permissions) { - var actions = this.getActions(mime, type, permissions); - var filteredActions = {}; - $.each(actions, function (name, action) { - filteredActions[name] = action.action; - }); - return filteredActions; - }, - getActions: function (mime, type, permissions) { - var actions = {}; - if (FileActions.actions.all) { - actions = $.extend(actions, FileActions.actions.all); - } - if (type) {//type is 'dir' or 'file' - if (FileActions.actions[type]) { - actions = $.extend(actions, FileActions.actions[type]); +(function() { + + var FileActions = { + actions: {}, + defaults: {}, + icons: {}, + currentFile: null, + register: function (mime, name, permissions, icon, action, displayName) { + if (!this.actions[mime]) { + this.actions[mime] = {}; } - } - if (mime) { - var mimePart = mime.substr(0, mime.indexOf('/')); - if (FileActions.actions[mimePart]) { - actions = $.extend(actions, FileActions.actions[mimePart]); + if (!this.actions[mime][name]) { + this.actions[mime][name] = {}; } - if (FileActions.actions[mime]) { - actions = $.extend(actions, FileActions.actions[mime]); + if (!displayName) { + displayName = t('files', name); } - } - var filteredActions = {}; - $.each(actions, function (name, action) { - if (action.permissions & permissions) { - filteredActions[name] = action; + this.actions[mime][name]['action'] = action; + this.actions[mime][name]['permissions'] = permissions; + this.actions[mime][name]['displayName'] = displayName; + this.icons[name] = icon; + }, + clear: function() { + this.actions = {}; + this.defaults = {}; + this.icons = {}; + this.currentFile = null; + }, + setDefault: function (mime, name) { + this.defaults[mime] = name; + }, + get: function (mime, type, permissions) { + var actions = this.getActions(mime, type, permissions); + var filteredActions = {}; + $.each(actions, function (name, action) { + filteredActions[name] = action.action; + }); + return filteredActions; + }, + getActions: function (mime, type, permissions) { + var actions = {}; + if (this.actions.all) { + actions = $.extend(actions, this.actions.all); } - }); - return filteredActions; - }, - getDefault: function (mime, type, permissions) { - var mimePart; - if (mime) { - mimePart = mime.substr(0, mime.indexOf('/')); - } - var name = false; - if (mime && FileActions.defaults[mime]) { - name = FileActions.defaults[mime]; - } else if (mime && FileActions.defaults[mimePart]) { - name = FileActions.defaults[mimePart]; - } else if (type && FileActions.defaults[type]) { - name = FileActions.defaults[type]; - } else { - name = FileActions.defaults.all; - } - var actions = this.get(mime, type, permissions); - return actions[name]; - }, - /** - * Display file actions for the given element - * @param parent "td" element of the file for which to display actions - * @param triggerEvent if true, triggers the fileActionsReady on the file - * list afterwards (false by default) - */ - display: function (parent, triggerEvent) { - FileActions.currentFile = parent; - var actions = FileActions.getActions(FileActions.getCurrentMimeType(), FileActions.getCurrentType(), FileActions.getCurrentPermissions()); - var file = FileActions.getCurrentFile(); - var nameLinks; - if (FileList.findFileEl(file).data('renaming')) { - return; - } + if (type) {//type is 'dir' or 'file' + if (this.actions[type]) { + actions = $.extend(actions, this.actions[type]); + } + } + if (mime) { + var mimePart = mime.substr(0, mime.indexOf('/')); + if (this.actions[mimePart]) { + actions = $.extend(actions, this.actions[mimePart]); + } + if (this.actions[mime]) { + actions = $.extend(actions, this.actions[mime]); + } + } + var filteredActions = {}; + $.each(actions, function (name, action) { + if (action.permissions & permissions) { + filteredActions[name] = action; + } + }); + return filteredActions; + }, + getDefault: function (mime, type, permissions) { + var mimePart; + if (mime) { + mimePart = mime.substr(0, mime.indexOf('/')); + } + var name = false; + if (mime && this.defaults[mime]) { + name = this.defaults[mime]; + } else if (mime && this.defaults[mimePart]) { + name = this.defaults[mimePart]; + } else if (type && this.defaults[type]) { + name = this.defaults[type]; + } else { + name = this.defaults.all; + } + var actions = this.get(mime, type, permissions); + return actions[name]; + }, + /** + * Display file actions for the given element + * @param parent "td" element of the file for which to display actions + * @param triggerEvent if true, triggers the fileActionsReady on the file + * list afterwards (false by default) + */ + display: function (parent, triggerEvent) { + this.currentFile = parent; + var self = this; + var actions = this.getActions(this.getCurrentMimeType(), this.getCurrentType(), this.getCurrentPermissions()); + var file = this.getCurrentFile(); + var nameLinks; + if (parent.closest('tr').data('renaming')) { + return; + } + + // recreate fileactions + nameLinks = parent.children('a.name'); + nameLinks.find('.fileactions, .nametext .action').remove(); + nameLinks.append(''); + var defaultAction = this.getDefault(this.getCurrentMimeType(), this.getCurrentType(), this.getCurrentPermissions()); - // recreate fileactions - nameLinks = parent.children('a.name'); - nameLinks.find('.fileactions, .nametext .action').remove(); - nameLinks.append(''); - var defaultAction = FileActions.getDefault(FileActions.getCurrentMimeType(), FileActions.getCurrentType(), FileActions.getCurrentPermissions()); + var actionHandler = function (event) { + event.stopPropagation(); + event.preventDefault(); - var actionHandler = function (event) { - event.stopPropagation(); - event.preventDefault(); + self.currentFile = event.data.elem; + var file = self.getCurrentFile(); - FileActions.currentFile = event.data.elem; - var file = FileActions.getCurrentFile(); + event.data.actionFunc(file); + }; - event.data.actionFunc(file); - }; + var addAction = function (name, action, displayName) { - var addAction = function (name, action, displayName) { + if ((name === 'Download' || action !== defaultAction) && name !== 'Delete') { - if ((name === 'Download' || action !== defaultAction) && name !== 'Delete') { + var img = self.icons[name], + actionText = displayName, + actionContainer = 'a.name>span.fileactions'; - var img = FileActions.icons[name], - actionText = displayName, - actionContainer = 'a.name>span.fileactions'; + if (name === 'Rename') { + // rename has only an icon which appears behind + // the file name + actionText = ''; + actionContainer = 'a.name span.nametext'; + } + if (img.call) { + img = img(file); + } + var html = ''; + if (img) { + html += ''; + } + html += ' ' + actionText + ''; - if (name === 'Rename') { - // rename has only an icon which appears behind - // the file name - actionText = ''; - actionContainer = 'a.name span.nametext'; + var element = $(html); + element.data('action', name); + element.on('click', {a: null, elem: parent, actionFunc: actions[name].action}, actionHandler); + parent.find(actionContainer).append(element); } + + }; + + $.each(actions, function (name, action) { + if (name !== 'Share') { + displayName = action.displayName; + ah = action.action; + + addAction(name, ah, displayName); + } + }); + if(actions.Share){ + displayName = t('files', 'Share'); + addAction('Share', actions.Share, displayName); + } + + // remove the existing delete action + parent.parent().children().last().find('.action.delete').remove(); + if (actions['Delete']) { + var img = self.icons['Delete']; + var html; if (img.call) { img = img(file); } - var html = ''; - if (img) { - html += ''; + if (typeof trashBinApp !== 'undefined' && trashBinApp) { + html = ''; + } else { + html = ''; } - html += ' ' + actionText + ''; - var element = $(html); - element.data('action', name); - element.on('click', {a: null, elem: parent, actionFunc: actions[name].action}, actionHandler); - parent.find(actionContainer).append(element); + element.data('action', actions['Delete']); + element.on('click', {a: null, elem: parent, actionFunc: actions['Delete'].action}, actionHandler); + parent.parent().children().last().append(element); } - }; + if (triggerEvent){ + $('#fileList').trigger(jQuery.Event("fileActionsReady")); + } + }, + getCurrentFile: function () { + return this.currentFile.parent().attr('data-file'); + }, + getCurrentMimeType: function () { + return this.currentFile.parent().attr('data-mime'); + }, + getCurrentType: function () { + return this.currentFile.parent().attr('data-type'); + }, + getCurrentPermissions: function () { + return this.currentFile.parent().data('permissions'); + }, - $.each(actions, function (name, action) { - if (name !== 'Share') { - displayName = action.displayName; - ah = action.action; + /** + * Register the actions that are used by default for the files app. + */ + registerDefaultActions: function(fileList) { + // TODO: try to find a way to not make it depend on fileList, + // maybe get a handler or listener to trigger events on + this.register('all', 'Delete', OC.PERMISSION_DELETE, function () { + return OC.imagePath('core', 'actions/delete'); + }, function (filename) { + fileList.do_delete(filename); + $('.tipsy').remove(); + }); - addAction(name, ah, displayName); - } - }); - if(actions.Share){ - displayName = t('files', 'Share'); - addAction('Share', actions.Share, displayName); - } + // t('files', 'Rename') + this.register('all', 'Rename', OC.PERMISSION_UPDATE, function () { + return OC.imagePath('core', 'actions/rename'); + }, function (filename) { + fileList.rename(filename); + }); - // remove the existing delete action - parent.parent().children().last().find('.action.delete').remove(); - if (actions['Delete']) { - var img = FileActions.icons['Delete']; - var html; - if (img.call) { - img = img(file); - } - if (typeof trashBinApp !== 'undefined' && trashBinApp) { - html = ''; + this.register('dir', 'Open', OC.PERMISSION_READ, '', function (filename) { + var dir = fileList.getCurrentDirectory(); + if (dir !== '/') { + dir = dir + '/'; + } + fileList.changeDirectory(dir + filename); + }); + + this.setDefault('dir', 'Open'); + var downloadScope; + if ($('#allowZipDownload').val() == 1) { + downloadScope = 'all'; } else { - html = ''; + downloadScope = 'file'; } - var element = $(html); - element.data('action', actions['Delete']); - element.on('click', {a: null, elem: parent, actionFunc: actions['Delete'].action}, actionHandler); - parent.parent().children().last().append(element); - } - if (triggerEvent){ - $('#fileList').trigger(jQuery.Event("fileActionsReady")); + this.register(downloadScope, 'Download', OC.PERMISSION_READ, function () { + return OC.imagePath('core', 'actions/download'); + }, function (filename) { + var url = OCA.Files.Files.getDownloadUrl(filename, fileList.getCurrentDirectory()); + if (url) { + OC.redirect(url); + } + }); + + fileList.$fileList.trigger(jQuery.Event("fileActionsReady")); } - }, - getCurrentFile: function () { - return FileActions.currentFile.parent().attr('data-file'); - }, - getCurrentMimeType: function () { - return FileActions.currentFile.parent().attr('data-mime'); - }, - getCurrentType: function () { - return FileActions.currentFile.parent().attr('data-type'); - }, - getCurrentPermissions: function () { - return FileActions.currentFile.parent().data('permissions'); - } -}; - -$(document).ready(function () { - var downloadScope; - if ($('#allowZipDownload').val() == 1) { - downloadScope = 'all'; - } else { - downloadScope = 'file'; - } - - if (typeof disableDownloadActions == 'undefined' || !disableDownloadActions) { - FileActions.register(downloadScope, 'Download', OC.PERMISSION_READ, function () { - return OC.imagePath('core', 'actions/download'); - }, function (filename) { - var url = Files.getDownloadUrl(filename); - if (url) { - OC.redirect(url); - } - }); - } - $('#fileList tr').each(function () { - FileActions.display($(this).children('td.filename')); - }); - - $('#fileList').trigger(jQuery.Event("fileActionsReady")); - -}); - -FileActions.register('all', 'Delete', OC.PERMISSION_DELETE, function () { - return OC.imagePath('core', 'actions/delete'); -}, function (filename) { - FileList.do_delete(filename); - $('.tipsy').remove(); -}); - -// t('files', 'Rename') -FileActions.register('all', 'Rename', OC.PERMISSION_UPDATE, function () { - return OC.imagePath('core', 'actions/rename'); -}, function (filename) { - FileList.rename(filename); -}); - -FileActions.register('dir', 'Open', OC.PERMISSION_READ, '', function (filename) { - var dir = $('#dir').val() || '/'; - if (dir !== '/') { - dir = dir + '/'; - } - FileList.changeDirectory(dir + filename); -}); - -FileActions.setDefault('dir', 'Open'); + }; + + OCA.Files.FileActions = FileActions; +})(); + +// for backward compatibility +window.FileActions = OCA.Files.FileActions; + diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 8896a8e23a87d53674f6e7b7c8f6b07baedcca85..38766e2b80128357a86c4403ce0488f70f84f00c 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -8,1540 +8,1770 @@ * */ -/* global OC, t, n, FileList, FileActions, Files, FileSummary, BreadCrumb */ -/* global dragOptions, folderDropOptions */ -window.FileList = { - appName: t('files', 'Files'), - isEmpty: true, - useUndo:true, - $el: $('#filestable'), - $fileList: $('#fileList'), - breadcrumb: null, - +(function() { /** - * Instance of FileSummary + * The FileList class manages a file list view. + * A file list view consists of a controls bar and + * a file list table. */ - fileSummary: null, - initialized: false, - - // number of files per page - pageSize: 20, + var FileList = function($el, options) { + this.initialize($el, options); + }; + FileList.prototype = { + SORT_INDICATOR_ASC_CLASS: 'icon-triangle-s', + SORT_INDICATOR_DESC_CLASS: 'icon-triangle-n', + + id: 'files', + appName: t('files', 'Files'), + isEmpty: true, + useUndo:true, + + /** + * Top-level container with controls and file list + */ + $el: null, + + /** + * Files table + */ + $table: null, + + /** + * List of rows (table tbody) + */ + $fileList: null, + + breadcrumb: null, + + /** + * Instance of FileSummary + */ + fileSummary: null, + initialized: false, + + // number of files per page + pageSize: 20, + + /** + * Array of files in the current folder. + * The entries are of file data. + */ + files: [], + + /** + * File actions handler, defaults to OCA.Files.FileActions + */ + fileActions: null, + + /** + * Map of file id to file data + */ + _selectedFiles: {}, + + /** + * Summary of selected files. + * Instance of FileSummary. + */ + _selectionSummary: null, + + /** + * Sort attribute + */ + _sort: 'name', + + /** + * Sort direction: 'asc' or 'desc' + */ + _sortDirection: 'asc', + + /** + * Sort comparator function for the current sort + */ + _sortComparator: null, + + /** + * Current directory + */ + _currentDirectory: null, + + _dragOptions: null, + _folderDropOptions: null, + + /** + * Initialize the file list and its components + * + * @param $el container element with existing markup for the #controls + * and a table + * @param options map of options, see other parameters + * @param scrollContainer scrollable container, defaults to $(window) + * @param dragOptions drag options, disabled by default + * @param folderDropOptions folder drop options, disabled by default + */ + initialize: function($el, options) { + var self = this; + options = options || {}; + if (this.initialized) { + return; + } - /** - * Array of files in the current folder. - * The entries are of file data. - */ - files: [], + if (options.dragOptions) { + this._dragOptions = options.dragOptions; + } + if (options.folderDropOptions) { + this._folderDropOptions = options.folderDropOptions; + } - /** - * Map of file id to file data - */ - _selectedFiles: {}, + this.$el = $el; + this.$container = options.scrollContainer || $(window); + this.$table = $el.find('table:first'); + this.$fileList = $el.find('#fileList'); + this.fileActions = OCA.Files.FileActions; + this.files = []; + this._selectedFiles = {}; + this._selectionSummary = new OCA.Files.FileSummary(); - /** - * Summary of selected files. - * Instance of FileSummary. - */ - _selectionSummary: null, + this.fileSummary = this._createSummary(); - /** - * Compare two file info objects, sorting by - * folders first, then by name. - */ - _fileInfoCompare: function(fileInfo1, fileInfo2) { - if (fileInfo1.type === 'dir' && fileInfo2.type !== 'dir') { - return -1; - } - if (fileInfo1.type !== 'dir' && fileInfo2.type === 'dir') { - return 1; - } - return fileInfo1.name.localeCompare(fileInfo2.name); - }, + this.setSort('name', 'asc'); - /** - * Initialize the file list and its components - */ - initialize: function() { - var self = this; - if (this.initialized) { - return; - } + var breadcrumbOptions = { + onClick: _.bind(this._onClickBreadCrumb, this), + getCrumbUrl: function(part) { + return self.linkTo(part.dir); + } + }; + // if dropping on folders is allowed, then also allow on breadcrumbs + if (this._folderDropOptions) { + breadcrumbOptions.onDrop = _.bind(this._onDropOnBreadCrumb, this); + } + this.breadcrumb = new OCA.Files.BreadCrumb(breadcrumbOptions); - // TODO: FileList should not know about global elements - this.$el = $('#filestable'); - this.$fileList = $('#fileList'); - this.files = []; - this._selectedFiles = {}; - this._selectionSummary = new FileSummary(); + this.$el.find('#controls').prepend(this.breadcrumb.$el); - this.fileSummary = this._createSummary(); + this.$el.find('thead th .columntitle').click(_.bind(this._onClickHeader, this)); - this.breadcrumb = new BreadCrumb({ - onClick: this._onClickBreadCrumb, - onDrop: _.bind(this._onDropOnBreadCrumb, this), - getCrumbUrl: function(part, index) { - return self.linkTo(part.dir); - } - }); + $(window).resize(function() { + // TODO: debounce this ? + var width = $(this).width(); + self.breadcrumb.resize(width, false); + }); - $('#controls').prepend(this.breadcrumb.$el); + this.$fileList.on('click','td.filename>a.name', _.bind(this._onClickFile, this)); + this.$fileList.on('change', 'td.filename>input:checkbox', _.bind(this._onClickFileCheckbox, this)); + this.$el.on('urlChanged', _.bind(this._onUrlChanged, this)); + this.$el.find('.select-all').click(_.bind(this._onClickSelectAll, this)); + this.$el.find('.download').click(_.bind(this._onClickDownloadSelected, this)); + this.$el.find('.delete-selected').click(_.bind(this._onClickDeleteSelected, this)); - $(window).resize(function() { - // TODO: debounce this ? - var width = $(this).width(); - FileList.breadcrumb.resize(width, false); - }); + this.setupUploadEvents(); - this.$fileList.on('click','td.filename>a.name', _.bind(this._onClickFile, this)); - this.$fileList.on('change', 'td.filename>input:checkbox', _.bind(this._onClickFileCheckbox, this)); - this.$el.find('#select_all').click(_.bind(this._onClickSelectAll, this)); - this.$el.find('.download').click(_.bind(this._onClickDownloadSelected, this)); - this.$el.find('.delete-selected').click(_.bind(this._onClickDeleteSelected, this)); - }, + this.$container.on('scroll', _.bind(this._onScroll, this)); + }, - /** - * Selected/deselects the given file element and updated - * the internal selection cache. - * - * @param $tr single file row element - * @param state true to select, false to deselect - */ - _selectFileEl: function($tr, state) { - var $checkbox = $tr.find('td.filename>input:checkbox'); - var oldData = !!this._selectedFiles[$tr.data('id')]; - var data; - $checkbox.prop('checked', state); - $tr.toggleClass('selected', state); - // already selected ? - if (state === oldData) { - return; - } - data = this.elementToFile($tr); - if (state) { - this._selectedFiles[$tr.data('id')] = data; - this._selectionSummary.add(data); - } - else { - delete this._selectedFiles[$tr.data('id')]; - this._selectionSummary.remove(data); - } - this.$el.find('#select_all').prop('checked', this._selectionSummary.getTotal() === this.files.length); - }, + /** + * Event handler for when the URL changed + */ + _onUrlChanged: function(e) { + if (e && e.dir) { + this.changeDirectory(e.dir, false, true); + } + }, + + /** + * Selected/deselects the given file element and updated + * the internal selection cache. + * + * @param $tr single file row element + * @param state true to select, false to deselect + */ + _selectFileEl: function($tr, state) { + var $checkbox = $tr.find('td.filename>input:checkbox'); + var oldData = !!this._selectedFiles[$tr.data('id')]; + var data; + $checkbox.prop('checked', state); + $tr.toggleClass('selected', state); + // already selected ? + if (state === oldData) { + return; + } + data = this.elementToFile($tr); + if (state) { + this._selectedFiles[$tr.data('id')] = data; + this._selectionSummary.add(data); + } + else { + delete this._selectedFiles[$tr.data('id')]; + this._selectionSummary.remove(data); + } + this.$el.find('.select-all').prop('checked', this._selectionSummary.getTotal() === this.files.length); + }, + + /** + * Event handler for when clicking on files to select them + */ + _onClickFile: function(event) { + var $tr = $(event.target).closest('tr'); + if (event.ctrlKey || event.shiftKey) { + event.preventDefault(); + if (event.shiftKey) { + var $lastTr = $(this._lastChecked); + var lastIndex = $lastTr.index(); + var currentIndex = $tr.index(); + var $rows = this.$fileList.children('tr'); + + // last clicked checkbox below current one ? + if (lastIndex > currentIndex) { + var aux = lastIndex; + lastIndex = currentIndex; + currentIndex = aux; + } - /** - * Event handler for when clicking on files to select them - */ - _onClickFile: function(event) { - var $tr = $(event.target).closest('tr'); - if (event.ctrlKey || event.shiftKey) { - event.preventDefault(); - if (event.shiftKey) { - var $lastTr = $(this._lastChecked); - var lastIndex = $lastTr.index(); - var currentIndex = $tr.index(); - var $rows = this.$fileList.children('tr'); - - // last clicked checkbox below current one ? - if (lastIndex > currentIndex) { - var aux = lastIndex; - lastIndex = currentIndex; - currentIndex = aux; + // auto-select everything in-between + for (var i = lastIndex + 1; i < currentIndex; i++) { + this._selectFileEl($rows.eq(i), true); + } } - - // auto-select everything in-between - for (var i = lastIndex + 1; i < currentIndex; i++) { - this._selectFileEl($rows.eq(i), true); + else { + this._lastChecked = $tr; + } + var $checkbox = $tr.find('td.filename>input:checkbox'); + this._selectFileEl($tr, !$checkbox.prop('checked')); + this.updateSelectionSummary(); + } else { + var filename = $tr.attr('data-file'); + var renaming = $tr.data('renaming'); + if (!renaming) { + this.fileActions.currentFile = $tr.find('td'); + var mime = this.fileActions.getCurrentMimeType(); + var type = this.fileActions.getCurrentType(); + var permissions = this.fileActions.getCurrentPermissions(); + var action = this.fileActions.getDefault(mime,type, permissions); + if (action) { + event.preventDefault(); + action(filename); + } } } - else { - this._lastChecked = $tr; + }, + + /** + * Event handler for when clicking on a file's checkbox + */ + _onClickFileCheckbox: function(e) { + var $tr = $(e.target).closest('tr'); + this._selectFileEl($tr, !$tr.hasClass('selected')); + this._lastChecked = $tr; + this.updateSelectionSummary(); + }, + + /** + * Event handler for when selecting/deselecting all files + */ + _onClickSelectAll: function(e) { + var checked = $(e.target).prop('checked'); + this.$fileList.find('td.filename>input:checkbox').prop('checked', checked) + .closest('tr').toggleClass('selected', checked); + this._selectedFiles = {}; + this._selectionSummary.clear(); + if (checked) { + for (var i = 0; i < this.files.length; i++) { + var fileData = this.files[i]; + this._selectedFiles[fileData.id] = fileData; + this._selectionSummary.add(fileData); + } } - var $checkbox = $tr.find('td.filename>input:checkbox'); - this._selectFileEl($tr, !$checkbox.prop('checked')); this.updateSelectionSummary(); - } else { - var filename = $tr.attr('data-file'); - var renaming = $tr.data('renaming'); - if (!renaming) { - FileActions.currentFile = $tr.find('td'); - var mime=FileActions.getCurrentMimeType(); - var type=FileActions.getCurrentType(); - var permissions = FileActions.getCurrentPermissions(); - var action=FileActions.getDefault(mime,type, permissions); - if (action) { - event.preventDefault(); - action(filename); + }, + + /** + * Event handler for when clicking on "Download" for the selected files + */ + _onClickDownloadSelected: function(event) { + var files; + var dir = this.getCurrentDirectory(); + if (this.isAllSelected()) { + files = OC.basename(dir); + dir = OC.dirname(dir) || '/'; + } + else { + files = _.pluck(this.getSelectedFiles(), 'name'); + } + OC.Notification.show(t('files','Your download is being prepared. This might take some time if the files are big.')); + OC.redirect(this.getDownloadUrl(files, dir)); + return false; + }, + + /** + * Event handler for when clicking on "Delete" for the selected files + */ + _onClickDeleteSelected: function(event) { + var files = null; + if (!this.isAllSelected()) { + files = _.pluck(this.getSelectedFiles(), 'name'); + } + this.do_delete(files); + event.preventDefault(); + return false; + }, + + /** + * Event handler when clicking on a table header + */ + _onClickHeader: function(e) { + var $target = $(e.target); + var sort; + if (!$target.is('a')) { + $target = $target.closest('a'); + } + sort = $target.attr('data-sort'); + if (sort) { + if (this._sort === sort) { + this.setSort(sort, (this._sortDirection === 'desc')?'asc':'desc'); } + else { + this.setSort(sort, 'asc'); + } + this.reload(); + } + }, + + /** + * Event handler when clicking on a bread crumb + */ + _onClickBreadCrumb: function(e) { + var $el = $(e.target).closest('.crumb'), + $targetDir = $el.data('dir'); + + if ($targetDir !== undefined) { + e.preventDefault(); + this.changeDirectory($targetDir); + } + }, + + /** + * Event handler for when scrolling the list container. + * This appends/renders the next page of entries when reaching the bottom. + */ + _onScroll: function(e) { + if (this.$container.scrollTop() + this.$container.height() > this.$el.height() - 100) { + this._nextPage(true); + } + }, + + /** + * Event handler when dropping on a breadcrumb + */ + _onDropOnBreadCrumb: function( event, ui ) { + var $target = $(event.target); + if (!$target.is('.crumb')) { + $target = $target.closest('.crumb'); + } + var targetPath = $(event.target).data('dir'); + var dir = this.getCurrentDirectory(); + while (dir.substr(0,1) === '/') {//remove extra leading /'s + dir = dir.substr(1); + } + dir = '/' + dir; + if (dir.substr(-1,1) !== '/') { + dir = dir + '/'; + } + // do nothing if dragged on current dir + if (targetPath === dir || targetPath + '/' === dir) { + return; } - } - }, - - /** - * Event handler for when clicking on a file's checkbox - */ - _onClickFileCheckbox: function(e) { - var $tr = $(e.target).closest('tr'); - this._selectFileEl($tr, !$tr.hasClass('selected')); - this._lastChecked = $tr; - this.updateSelectionSummary(); - }, - /** - * Event handler for when selecting/deselecting all files - */ - _onClickSelectAll: function(e) { - var checked = $(e.target).prop('checked'); - this.$fileList.find('td.filename>input:checkbox').prop('checked', checked) - .closest('tr').toggleClass('selected', checked); - this._selectedFiles = {}; - this._selectionSummary.clear(); - if (checked) { - for (var i = 0; i < this.files.length; i++) { - var fileData = this.files[i]; - this._selectedFiles[fileData.id] = fileData; - this._selectionSummary.add(fileData); + var files = this.getSelectedFiles(); + if (files.length === 0) { + // single one selected without checkbox? + files = _.map(ui.helper.find('tr'), this.elementToFile); } - } - this.updateSelectionSummary(); - }, - /** - * Event handler for when clicking on "Download" for the selected files - */ - _onClickDownloadSelected: function(event) { - var files; - var dir = this.getCurrentDirectory(); - if (this.isAllSelected()) { - files = OC.basename(dir); - dir = OC.dirname(dir) || '/'; - } - else { - files = _.pluck(this.getSelectedFiles(), 'name'); - } - OC.Notification.show(t('files','Your download is being prepared. This might take some time if the files are big.')); - OC.redirect(Files.getDownloadUrl(files, dir)); - return false; - }, + this.move(_.pluck(files, 'name'), targetPath); + }, - /** - * Event handler for when clicking on "Delete" for the selected files - */ - _onClickDeleteSelected: function(event) { - var files = null; - if (!FileList.isAllSelected()) { - files = _.pluck(this.getSelectedFiles(), 'name'); - } - this.do_delete(files); - event.preventDefault(); - return false; - }, + /** + * Sets a new page title + */ + setPageTitle: function(title){ + if (title) { + title += ' - '; + } else { + title = ''; + } + title += this.appName; + // Sets the page title with the " - ownCloud" suffix as in templates + window.document.title = title + ' - ' + oc_defaults.title; - /** - * Event handler when clicking on a bread crumb - */ - _onClickBreadCrumb: function(e) { - var $el = $(e.target).closest('.crumb'), - $targetDir = $el.data('dir'); + return true; + }, + /** + * Returns the tr element for a given file name + * @param fileName file name + */ + findFileEl: function(fileName){ + // use filterAttr to avoid escaping issues + return this.$fileList.find('tr').filterAttr('data-file', fileName); + }, + + /** + * Returns the file data from a given file element. + * @param $el file tr element + * @return file data + */ + elementToFile: function($el){ + $el = $($el); + return { + id: parseInt($el.attr('data-id'), 10), + name: $el.attr('data-file'), + mimetype: $el.attr('data-mime'), + type: $el.attr('data-type'), + size: parseInt($el.attr('data-size'), 10), + etag: $el.attr('data-etag') + }; + }, + + /** + * Appends the next page of files into the table + * @param animate true to animate the new elements + */ + _nextPage: function(animate) { + var index = this.$fileList.children().length, + count = this.pageSize, + tr, + fileData, + newTrs = [], + isAllSelected = this.isAllSelected(); + + if (index >= this.files.length) { + return; + } - if ($targetDir !== undefined) { - e.preventDefault(); - FileList.changeDirectory($targetDir); - } - }, + while (count > 0 && index < this.files.length) { + fileData = this.files[index]; + tr = this._renderRow(fileData, {updateSummary: false}); + this.$fileList.append(tr); + if (isAllSelected || this._selectedFiles[fileData.id]) { + tr.addClass('selected'); + tr.find('input:checkbox').prop('checked', true); + } + if (animate) { + tr.addClass('appear transparent'); + newTrs.push(tr); + } + index++; + count--; + } - _onScroll: function(e) { - if ($(window).scrollTop() + $(window).height() > $(document).height() - 500) { - this._nextPage(true); - } - }, + if (animate) { + // defer, for animation + window.setTimeout(function() { + for (var i = 0; i < newTrs.length; i++ ) { + newTrs[i].removeClass('transparent'); + } + }, 0); + } + }, - /** - * Event handler when dropping on a breadcrumb - */ - _onDropOnBreadCrumb: function( event, ui ) { - var $target = $(event.target); - if (!$target.is('.crumb')) { - $target = $target.closest('.crumb'); - } - var targetPath = $(event.target).data('dir'); - var dir = this.getCurrentDirectory(); - while (dir.substr(0,1) === '/') {//remove extra leading /'s - dir = dir.substr(1); - } - dir = '/' + dir; - if (dir.substr(-1,1) !== '/') { - dir = dir + '/'; - } - // do nothing if dragged on current dir - if (targetPath === dir || targetPath + '/' === dir) { - return; - } + /** + * Sets the files to be displayed in the list. + * This operation will re-render the list and update the summary. + * @param filesArray array of file data (map) + */ + setFiles: function(filesArray) { + // detach to make adding multiple rows faster + this.files = filesArray; - var files = this.getSelectedFiles(); - if (files.length === 0) { - // single one selected without checkbox? - files = _.map(ui.helper.find('tr'), FileList.elementToFile); - } + this.$fileList.detach(); + this.$fileList.empty(); - FileList.move(_.pluck(files, 'name'), targetPath); - }, + // clear "Select all" checkbox + this.$el.find('.select-all').prop('checked', false); - /** - * Sets a new page title - */ - setPageTitle: function(title){ - if (title) { - title += ' - '; - } else { - title = ''; - } - title += FileList.appName; - // Sets the page title with the " - ownCloud" suffix as in templates - window.document.title = title + ' - ' + oc_defaults.title; + this.isEmpty = this.files.length === 0; + this._nextPage(); - return true; - }, - /** - * Returns the tr element for a given file name - * @param fileName file name - */ - findFileEl: function(fileName){ - // use filterAttr to avoid escaping issues - return this.$fileList.find('tr').filterAttr('data-file', fileName); - }, + this.$el.find('thead').after(this.$fileList); - /** - * Returns the file data from a given file element. - * @param $el file tr element - * @return file data - */ - elementToFile: function($el){ - $el = $($el); - return { - id: parseInt($el.attr('data-id'), 10), - name: $el.attr('data-file'), - mimetype: $el.attr('data-mime'), - type: $el.attr('data-type'), - size: parseInt($el.attr('data-size'), 10), - etag: $el.attr('data-etag') - }; - }, + this.updateEmptyContent(); + this.$fileList.trigger(jQuery.Event("fileActionsReady")); - /** - * Appends the next page of files into the table - * @param animate true to animate the new elements - */ - _nextPage: function(animate) { - var index = this.$fileList.children().length, - count = this.pageSize, - tr, - fileData, - newTrs = [], - isAllSelected = this.isAllSelected(); - - if (index >= this.files.length) { - return; - } + this.fileSummary.calculate(filesArray); - while (count > 0 && index < this.files.length) { - fileData = this.files[index]; - tr = this._renderRow(fileData, {updateSummary: false}); - this.$fileList.append(tr); - if (isAllSelected || this._selectedFiles[fileData.id]) { - tr.addClass('selected'); - tr.find('input:checkbox').prop('checked', true); - } - if (animate) { - tr.addClass('appear transparent'); - newTrs.push(tr); + this.updateSelectionSummary(); + $(window).scrollTop(0); + + this.$fileList.trigger(jQuery.Event("updated")); + }, + /** + * Creates a new table row element using the given file data. + * @param fileData map of file attributes + * @param options map of attribute "loading" whether the entry is currently loading + * @return new tr element (not appended to the table) + */ + _createRow: function(fileData, options) { + var td, simpleSize, basename, extension, sizeColor, + icon = OC.Util.replaceSVGIcon(fileData.icon), + name = fileData.name, + type = fileData.type || 'file', + mtime = parseInt(fileData.mtime, 10) || new Date().getTime(), + mime = fileData.mimetype, + linkUrl; + options = options || {}; + + if (type === 'dir') { + mime = mime || 'httpd/unix-directory'; } - index++; - count--; - } - - if (animate) { - // defer, for animation - window.setTimeout(function() { - for (var i = 0; i < newTrs.length; i++ ) { - newTrs[i].removeClass('transparent'); - } - }, 0); - } - }, - - /** - * Sets the files to be displayed in the list. - * This operation will re-render the list and update the summary. - * @param filesArray array of file data (map) - */ - setFiles: function(filesArray) { - // detach to make adding multiple rows faster - this.files = filesArray; - this.$fileList.detach(); - this.$fileList.empty(); + // user should always be able to rename a share mount point + var allowRename = 0; + if (fileData.isShareMountPoint) { + allowRename = OC.PERMISSION_UPDATE; + } - // clear "Select all" checkbox - this.$el.find('#select_all').prop('checked', false); + //containing tr + var tr = $('').attr({ + "data-id" : fileData.id, + "data-type": type, + "data-size": fileData.size, + "data-file": name, + "data-mime": mime, + "data-mtime": mtime, + "data-etag": fileData.etag, + "data-permissions": fileData.permissions | allowRename || this.getDirectoryPermissions() + }); - this.isEmpty = this.files.length === 0; - this._nextPage(); + if (type === 'dir') { + // use default folder icon + icon = icon || OC.imagePath('core', 'filetypes/folder'); + } + else { + icon = icon || OC.imagePath('core', 'filetypes/file'); + } - this.$el.find('thead').after(this.$fileList); + // filename td + td = $('').attr({ + "class": "filename", + "style": 'background-image:url(' + icon + '); background-size: 32px;' + }); - this.updateEmptyContent(); - this.$fileList.trigger(jQuery.Event("fileActionsReady")); - // "Files" might not be loaded in extending apps - if (window.Files) { - Files.setupDragAndDrop(); - } + // linkUrl + if (type === 'dir') { + linkUrl = this.linkTo(this.getCurrentDirectory() + '/' + name); + } + else { + linkUrl = this.getDownloadUrl(name, this.getCurrentDirectory()); + } + td.append(''); + var linkElem = $('').attr({ + "class": "name", + "href": linkUrl + }); - this.fileSummary.calculate(filesArray); + // from here work on the display name + name = fileData.displayName || name; - FileList.updateSelectionSummary(); - $(window).scrollTop(0); + // split extension from filename for non dirs + if (type !== 'dir' && name.indexOf('.') !== -1) { + basename = name.substr(0, name.lastIndexOf('.')); + extension = name.substr(name.lastIndexOf('.')); + } else { + basename = name; + extension = false; + } + var nameSpan=$('').addClass('nametext').text(basename); + linkElem.append(nameSpan); + if (extension) { + nameSpan.append($('').addClass('extension').text(extension)); + } + // dirs can show the number of uploaded files + if (type === 'dir') { + linkElem.append($('').attr({ + 'class': 'uploadtext', + 'currentUploads': 0 + })); + } + td.append(linkElem); + tr.append(td); - this.$fileList.trigger(jQuery.Event("updated")); - }, - /** - * Creates a new table row element using the given file data. - * @param fileData map of file attributes - * @param options map of attribute "loading" whether the entry is currently loading - * @return new tr element (not appended to the table) - */ - _createRow: function(fileData, options) { - var td, simpleSize, basename, extension, sizeColor, - icon = OC.Util.replaceSVGIcon(fileData.icon), - name = fileData.name, - type = fileData.type || 'file', - mtime = parseInt(fileData.mtime, 10) || new Date().getTime(), - mime = fileData.mimetype, - linkUrl; - options = options || {}; - - if (type === 'dir') { - mime = mime || 'httpd/unix-directory'; - } + // size column + if (typeof(fileData.size) !== 'undefined' && fileData.size >= 0) { + simpleSize = humanFileSize(parseInt(fileData.size, 10)); + sizeColor = Math.round(160-Math.pow((fileData.size/(1024*1024)),2)); + } else { + simpleSize = t('files', 'Pending'); + } - // user should always be able to rename a share mount point - var allowRename = 0; - if (fileData.isShareMountPoint) { - allowRename = OC.PERMISSION_UPDATE; - } + td = $('').attr({ + "class": "filesize", + "style": 'color:rgb(' + sizeColor + ',' + sizeColor + ',' + sizeColor + ')' + }).text(simpleSize); + tr.append(td); + + // date column + var modifiedColor = Math.round((Math.round((new Date()).getTime() / 1000) - mtime)/60/60/24*5); + td = $('').attr({ "class": "date" }); + td.append($('').attr({ + "class": "modified", + "title": formatDate(mtime), + "style": 'color:rgb('+modifiedColor+','+modifiedColor+','+modifiedColor+')' + }).text( relative_modified_date(mtime / 1000) )); + tr.find('.filesize').text(simpleSize); + tr.append(td); + return tr; + }, + + /** + * Adds an entry to the files array and also into the DOM + * in a sorted manner. + * + * @param fileData map of file attributes + * @param options map of attributes: + * - "updateSummary" true to update the summary after adding (default), false otherwise + * @return new tr element (not appended to the table) + */ + add: function(fileData, options) { + var index = -1; + var $tr; + var $rows; + var $insertionPoint; + options = options || {}; + + // there are three situations to cover: + // 1) insertion point is visible on the current page + // 2) insertion point is on a not visible page (visible after scrolling) + // 3) insertion point is at the end of the list + + $rows = this.$fileList.children(); + index = this._findInsertionIndex(fileData); + if (index > this.files.length) { + index = this.files.length; + } + else { + $insertionPoint = $rows.eq(index); + } - //containing tr - var tr = $('').attr({ - "data-id" : fileData.id, - "data-type": type, - "data-size": fileData.size, - "data-file": name, - "data-mime": mime, - "data-mtime": mtime, - "data-etag": fileData.etag, - "data-permissions": fileData.permissions | allowRename || this.getDirectoryPermissions() - }); - - if (type === 'dir') { - // use default folder icon - icon = icon || OC.imagePath('core', 'filetypes/folder'); - } - else { - icon = icon || OC.imagePath('core', 'filetypes/file'); - } + // is the insertion point visible ? + if ($insertionPoint.length) { + // only render if it will really be inserted + $tr = this._renderRow(fileData, options); + $insertionPoint.before($tr); + } + else { + // if insertion point is after the last visible + // entry, append + if (index === $rows.length) { + $tr = this._renderRow(fileData, options); + this.$fileList.append($tr); + } + } - // filename td - td = $('').attr({ - "class": "filename", - "style": 'background-image:url(' + icon + '); background-size: 32px;' - }); + this.isEmpty = false; + this.files.splice(index, 0, fileData); - // linkUrl - if (type === 'dir') { - linkUrl = FileList.linkTo(FileList.getCurrentDirectory() + '/' + name); - } - else { - linkUrl = Files.getDownloadUrl(name, FileList.getCurrentDirectory()); - } - td.append(''); - var linkElem = $('').attr({ - "class": "name", - "href": linkUrl - }); - - // from here work on the display name - name = fileData.displayName || name; - - // split extension from filename for non dirs - if (type !== 'dir' && name.indexOf('.') !== -1) { - basename = name.substr(0, name.lastIndexOf('.')); - extension = name.substr(name.lastIndexOf('.')); - } else { - basename = name; - extension = false; - } - var nameSpan=$('').addClass('nametext').text(basename); - linkElem.append(nameSpan); - if (extension) { - nameSpan.append($('').addClass('extension').text(extension)); - } - // dirs can show the number of uploaded files - if (type === 'dir') { - linkElem.append($('').attr({ - 'class': 'uploadtext', - 'currentUploads': 0 - })); - } - td.append(linkElem); - tr.append(td); - - // size column - if (typeof(fileData.size) !== 'undefined' && fileData.size >= 0) { - simpleSize = humanFileSize(parseInt(fileData.size, 10)); - sizeColor = Math.round(160-Math.pow((fileData.size/(1024*1024)),2)); - } else { - simpleSize = t('files', 'Pending'); - } + if ($tr && options.animate) { + $tr.addClass('appear transparent'); + window.setTimeout(function() { + $tr.removeClass('transparent'); + }); + } - td = $('').attr({ - "class": "filesize", - "style": 'color:rgb(' + sizeColor + ',' + sizeColor + ',' + sizeColor + ')' - }).text(simpleSize); - tr.append(td); - - // date column - var modifiedColor = Math.round((Math.round((new Date()).getTime() / 1000) - mtime)/60/60/24*5); - td = $('').attr({ "class": "date" }); - td.append($('').attr({ - "class": "modified", - "title": formatDate(mtime), - "style": 'color:rgb('+modifiedColor+','+modifiedColor+','+modifiedColor+')' - }).text( relative_modified_date(mtime / 1000) )); - tr.find('.filesize').text(simpleSize); - tr.append(td); - return tr; - }, + // defaults to true if not defined + if (typeof(options.updateSummary) === 'undefined' || !!options.updateSummary) { + this.fileSummary.add(fileData, true); + this.updateEmptyContent(); + } - /** - * Adds an entry to the files array and also into the DOM - * in a sorted manner. - * - * @param fileData map of file attributes - * @param options map of attributes: - * - "updateSummary" true to update the summary after adding (default), false otherwise - * @return new tr element (not appended to the table) - */ - add: function(fileData, options) { - var index = -1; - var $tr; - var $rows; - var $insertionPoint; - options = options || {}; - - // there are three situations to cover: - // 1) insertion point is visible on the current page - // 2) insertion point is on a not visible page (visible after scrolling) - // 3) insertion point is at the end of the list - - $rows = this.$fileList.children(); - index = this._findInsertionIndex(fileData); - if (index > this.files.length) { - index = this.files.length; - } - else { - $insertionPoint = $rows.eq(index); - } + return $tr; + }, + + /** + * Creates a new row element based on the given attributes + * and returns it. + * + * @param fileData map of file attributes + * @param options map of attributes: + * - "index" optional index at which to insert the element + * - "updateSummary" true to update the summary after adding (default), false otherwise + * @return new tr element (not appended to the table) + */ + _renderRow: function(fileData, options) { + options = options || {}; + var type = fileData.type || 'file', + mime = fileData.mimetype, + permissions = parseInt(fileData.permissions, 10) || 0; + + if (fileData.isShareMountPoint) { + permissions = permissions | OC.PERMISSION_UPDATE; + } - // is the insertion point visible ? - if ($insertionPoint.length) { - // only render if it will really be inserted - $tr = this._renderRow(fileData, options); - $insertionPoint.before($tr); - } - else { - // if insertion point is after the last visible - // entry, append - if (index === $rows.length) { - $tr = this._renderRow(fileData, options); - this.$fileList.append($tr); + if (type === 'dir') { + mime = mime || 'httpd/unix-directory'; + } + var tr = this._createRow( + fileData, + options + ); + var filenameTd = tr.find('td.filename'); + + // TODO: move dragging to FileActions ? + // enable drag only for deletable files + if (this._dragOptions && permissions & OC.PERMISSION_DELETE) { + filenameTd.draggable(this._dragOptions); + } + // allow dropping on folders + if (this._folderDropOptions && fileData.type === 'dir') { + filenameTd.droppable(this._folderDropOptions); } - } - this.isEmpty = false; - this.files.splice(index, 0, fileData); + if (options.hidden) { + tr.addClass('hidden'); + } - if ($tr && options.animate) { - $tr.addClass('appear transparent'); - window.setTimeout(function() { - $tr.removeClass('transparent'); - }); - } + // display actions + this.fileActions.display(filenameTd, false); + + if (fileData.isPreviewAvailable) { + // lazy load / newly inserted td ? + if (!fileData.icon) { + this.lazyLoadPreview({ + path: this.getCurrentDirectory() + '/' + fileData.name, + mime: mime, + etag: fileData.etag, + callback: function(url) { + filenameTd.css('background-image', 'url(' + url + ')'); + } + }); + } + else { + // set the preview URL directly + var urlSpec = { + file: this.getCurrentDirectory() + '/' + fileData.name, + c: fileData.etag + }; + var previewUrl = this.generatePreviewUrl(urlSpec); + previewUrl = previewUrl.replace('(', '%28').replace(')', '%29'); + filenameTd.css('background-image', 'url(' + previewUrl + ')'); + } + } + return tr; + }, + /** + * Returns the current directory + * @return current directory + */ + getCurrentDirectory: function(){ + return this._currentDirectory || this.$el.find('#dir').val() || '/'; + }, + /** + * Returns the directory permissions + * @return permission value as integer + */ + getDirectoryPermissions: function() { + return parseInt(this.$el.find('#permissions').val(), 10); + }, + /** + * @brief Changes the current directory and reload the file list. + * @param targetDir target directory (non URL encoded) + * @param changeUrl false if the URL must not be changed (defaults to true) + * @param {boolean} force set to true to force changing directory + */ + changeDirectory: function(targetDir, changeUrl, force) { + var currentDir = this.getCurrentDirectory(); + targetDir = targetDir || '/'; + if (!force && currentDir === targetDir) { + return; + } + this._setCurrentDir(targetDir, changeUrl); + this.reload(); + }, + linkTo: function(dir) { + return OC.linkTo('files', 'index.php')+"?dir="+ encodeURIComponent(dir).replace(/%2F/g, '/'); + }, + + /** + * Sets the file actions handler + */ + setFileActions: function(fileActions) { + this.fileActions = fileActions; + }, + + /** + * Sets the current directory name and updates the breadcrumb. + * @param targetDir directory to display + * @param changeUrl true to also update the URL, false otherwise (default) + */ + _setCurrentDir: function(targetDir, changeUrl) { + var previousDir = this.getCurrentDirectory(), + baseDir = OC.basename(targetDir); + + if (baseDir !== '') { + this.setPageTitle(baseDir); + } + else { + this.setPageTitle(); + } - // defaults to true if not defined - if (typeof(options.updateSummary) === 'undefined' || !!options.updateSummary) { - this.fileSummary.add(fileData, true); - this.updateEmptyContent(); - } + this._currentDirectory = targetDir; - return $tr; - }, + // legacy stuff + this.$el.find('#dir').val(targetDir); - /** - * Creates a new row element based on the given attributes - * and returns it. - * - * @param fileData map of file attributes - * @param options map of attributes: - * - "index" optional index at which to insert the element - * - "updateSummary" true to update the summary after adding (default), false otherwise - * @return new tr element (not appended to the table) - */ - _renderRow: function(fileData, options) { - options = options || {}; - var type = fileData.type || 'file', - mime = fileData.mimetype, - permissions = parseInt(fileData.permissions, 10) || 0; - - if (fileData.isShareMountPoint) { - permissions = permissions | OC.PERMISSION_UPDATE; - } + if (changeUrl !== false) { + this.$el.trigger(jQuery.Event('changeDirectory', { + dir: targetDir, + previousDir: previousDir + })); + } + this.breadcrumb.setDirectory(this.getCurrentDirectory()); + }, + /** + * Sets the current sorting and refreshes the list + * + * @param sort sort attribute name + * @param direction sort direction, one of "asc" or "desc" + */ + setSort: function(sort, direction) { + var comparator = FileList.Comparators[sort] || FileList.Comparators.name; + this._sort = sort; + this._sortDirection = (direction === 'desc')?'desc':'asc'; + this._sortComparator = comparator; + if (direction === 'desc') { + this._sortComparator = function(fileInfo1, fileInfo2) { + return -comparator(fileInfo1, fileInfo2); + }; + } + this.$el.find('thead th .sort-indicator') + .removeClass(this.SORT_INDICATOR_ASC_CLASS + ' ' + this.SORT_INDICATOR_DESC_CLASS); + this.$el.find('thead th.column-' + sort + ' .sort-indicator') + .addClass(direction === 'desc' ? this.SORT_INDICATOR_DESC_CLASS : this.SORT_INDICATOR_ASC_CLASS); + }, + /** + * @brief Reloads the file list using ajax call + */ + reload: function() { + var self = this; + this._selectedFiles = {}; + this._selectionSummary.clear(); + this.$el.find('.select-all').prop('checked', false); + this.showMask(); + if (this._reloadCall) { + this._reloadCall.abort(); + } + this._reloadCall = $.ajax({ + url: this.getAjaxUrl('list'), + data: { + dir : this.getCurrentDirectory(), + sort: this._sort, + sortdirection: this._sortDirection + }, + error: function(result) { + self.reloadCallback(result); + }, + success: function(result) { + self.reloadCallback(result); + } + }); + }, + reloadCallback: function(result) { + delete this._reloadCall; + this.hideMask(); + + if (!result || result.status === 'error') { + OC.Notification.show(result.data.message); + return; + } - if (type === 'dir') { - mime = mime || 'httpd/unix-directory'; - } - var tr = this._createRow( - fileData, - options - ); - var filenameTd = tr.find('td.filename'); - - // TODO: move dragging to FileActions ? - // enable drag only for deletable files - if (permissions & OC.PERMISSION_DELETE) { - filenameTd.draggable(dragOptions); - } - // allow dropping on folders - if (fileData.type === 'dir') { - filenameTd.droppable(folderDropOptions); - } + if (result.status === 404) { + // go back home + this.changeDirectory('/'); + return; + } + // aborted ? + if (result.status === 0){ + return; + } - if (options.hidden) { - tr.addClass('hidden'); - } + // TODO: should rather return upload file size through + // the files list ajax call + this.updateStorageStatistics(true); - // display actions - FileActions.display(filenameTd, false); + if (result.data.permissions) { + this.setDirectoryPermissions(result.data.permissions); + } - if (fileData.isPreviewAvailable) { - // lazy load / newly inserted td ? - if (!fileData.icon) { - Files.lazyLoadPreview(getPathForPreview(fileData.name), mime, function(url) { - filenameTd.css('background-image', 'url(' + url + ')'); - }, null, null, fileData.etag); + this.setFiles(result.data.files); + }, + + updateStorageStatistics: function(force) { + OCA.Files.Files.updateStorageStatistics(this.getCurrentDirectory(), force); + }, + + getAjaxUrl: function(action, params) { + return OCA.Files.Files.getAjaxUrl(action, params); + }, + + getDownloadUrl: function(files, dir) { + return OCA.Files.Files.getDownloadUrl(files, dir || this.getCurrentDirectory()); + }, + + /** + * Generates a preview URL based on the URL space. + * @param urlSpec map with {x: width, y: height, file: file path} + * @return preview URL + */ + generatePreviewUrl: function(urlSpec) { + urlSpec = urlSpec || {}; + if (!urlSpec.x) { + urlSpec.x = this.$table.data('preview-x') || 36; } - else { - // set the preview URL directly - var urlSpec = { - file: FileList.getCurrentDirectory() + '/' + fileData.name, - c: fileData.etag - }; - var previewUrl = Files.generatePreviewUrl(urlSpec); - previewUrl = previewUrl.replace('(', '%28').replace(')', '%29'); - filenameTd.css('background-image', 'url(' + previewUrl + ')'); + if (!urlSpec.y) { + urlSpec.y = this.$table.data('preview-y') || 36; } - } - return tr; - }, - /** - * Returns the current directory - * @return current directory - */ - getCurrentDirectory: function(){ - return $('#dir').val() || '/'; - }, - /** - * Returns the directory permissions - * @return permission value as integer - */ - getDirectoryPermissions: function() { - return parseInt($('#permissions').val(), 10); - }, - /** - * @brief Changes the current directory and reload the file list. - * @param targetDir target directory (non URL encoded) - * @param changeUrl false if the URL must not be changed (defaults to true) - * @param {boolean} force set to true to force changing directory - */ - changeDirectory: function(targetDir, changeUrl, force) { - var $dir = $('#dir'), - currentDir = $dir.val() || '/'; - targetDir = targetDir || '/'; - if (!force && currentDir === targetDir) { - return; - } - FileList._setCurrentDir(targetDir, changeUrl); - $('#fileList').trigger( - jQuery.Event('changeDirectory', { - dir: targetDir, - previousDir: currentDir - } - )); - this._selectedFiles = {}; - this._selectionSummary.clear(); - this.reload(); - }, - linkTo: function(dir) { - return OC.linkTo('files', 'index.php')+"?dir="+ encodeURIComponent(dir).replace(/%2F/g, '/'); - }, - - /** - * Sets the current directory name and updates the breadcrumb. - * @param targetDir directory to display - * @param changeUrl true to also update the URL, false otherwise (default) - */ - _setCurrentDir: function(targetDir, changeUrl) { - var url, - baseDir = OC.basename(targetDir); + urlSpec.y *= window.devicePixelRatio; + urlSpec.x *= window.devicePixelRatio; + urlSpec.forceIcon = 0; + return OC.generateUrl('/core/preview.png?') + $.param(urlSpec); + }, + + /** + * Lazy load a file's preview. + * + * @param path path of the file + * @param mime mime type + * @param callback callback function to call when the image was loaded + * @param etag file etag (for caching) + */ + lazyLoadPreview : function(options) { + var self = this; + var path = options.path; + var mime = options.mime; + var ready = options.callback; + var etag = options.etag; + + // get mime icon url + OCA.Files.Files.getMimeIcon(mime, function(iconURL) { + var previewURL, + urlSpec = {}; + ready(iconURL); // set mimeicon URL + + urlSpec.file = OCA.Files.Files.fixPath(path); + + if (etag){ + // use etag as cache buster + urlSpec.c = etag; + } + else { + console.warn('OCA.Files.FileList.lazyLoadPreview(): missing etag argument'); + } - if (baseDir !== '') { - FileList.setPageTitle(baseDir); - } - else { - FileList.setPageTitle(); - } + previewURL = self.generatePreviewUrl(urlSpec); + previewURL = previewURL.replace('(', '%28'); + previewURL = previewURL.replace(')', '%29'); + + // preload image to prevent delay + // this will make the browser cache the image + var img = new Image(); + img.onload = function(){ + // if loading the preview image failed (no preview for the mimetype) then img.width will < 5 + if (img.width > 5) { + ready(previewURL); + } + }; + img.src = previewURL; + }); + }, - $('#dir').val(targetDir); - if (changeUrl !== false) { - if (window.history.pushState && changeUrl !== false) { - url = FileList.linkTo(targetDir); - window.history.pushState({dir: targetDir}, '', url); + setDirectoryPermissions: function(permissions) { + var isCreatable = (permissions & OC.PERMISSION_CREATE) !== 0; + this.$el.find('#permissions').val(permissions); + this.$el.find('.creatable').toggleClass('hidden', !isCreatable); + this.$el.find('.notCreatable').toggleClass('hidden', isCreatable); + }, + /** + * Shows/hides action buttons + * + * @param show true for enabling, false for disabling + */ + showActions: function(show){ + this.$el.find('.actions,#file_action_panel').toggleClass('hidden', !show); + if (show){ + // make sure to display according to permissions + var permissions = this.getDirectoryPermissions(); + var isCreatable = (permissions & OC.PERMISSION_CREATE) !== 0; + this.$el.find('.creatable').toggleClass('hidden', !isCreatable); + this.$el.find('.notCreatable').toggleClass('hidden', isCreatable); + // remove old style breadcrumbs (some apps might create them) + this.$el.find('#controls .crumb').remove(); + // refresh breadcrumbs in case it was replaced by an app + this.breadcrumb.render(); } - // use URL hash for IE8 else{ - window.location.hash = '?dir='+ encodeURIComponent(targetDir).replace(/%2F/g, '/'); + this.$el.find('.creatable, .notCreatable').addClass('hidden'); + } + }, + /** + * Enables/disables viewer mode. + * In viewer mode, apps can embed themselves under the controls bar. + * In viewer mode, the actions of the file list will be hidden. + * @param show true for enabling, false for disabling + */ + setViewerMode: function(show){ + this.showActions(!show); + this.$el.find('#filestable').toggleClass('hidden', show); + this.$el.trigger(new $.Event('changeViewerMode', {viewerModeEnabled: show})); + }, + /** + * Removes a file entry from the list + * @param name name of the file to remove + * @param options optional options as map: + * "updateSummary": true to update the summary (default), false otherwise + * @return deleted element + */ + remove: function(name, options){ + options = options || {}; + var fileEl = this.findFileEl(name); + var index = fileEl.index(); + if (!fileEl.length) { + return null; + } + if (this._selectedFiles[fileEl.data('id')]) { + // remove from selection first + this._selectFileEl(fileEl, false); + this.updateSelectionSummary(); + } + if (this._dragOptions && (fileEl.data('permissions') & OC.PERMISSION_DELETE)) { + // file is only draggable when delete permissions are set + fileEl.find('td.filename').draggable('destroy'); + } + this.files.splice(index, 1); + fileEl.remove(); + // TODO: improve performance on batch update + this.isEmpty = !this.files.length; + if (typeof(options.updateSummary) === 'undefined' || !!options.updateSummary) { + this.updateEmptyContent(); + this.fileSummary.remove({type: fileEl.attr('data-type'), size: fileEl.attr('data-size')}, true); } - } - this.breadcrumb.setDirectory(this.getCurrentDirectory()); - }, - /** - * @brief Reloads the file list using ajax call - */ - reload: function() { - FileList.showMask(); - if (FileList._reloadCall) { - FileList._reloadCall.abort(); - } - FileList._reloadCall = $.ajax({ - url: Files.getAjaxUrl('list'), - data: { - dir : $('#dir').val() - }, - error: function(result) { - FileList.reloadCallback(result); - }, - success: function(result) { - FileList.reloadCallback(result); - } - }); - }, - reloadCallback: function(result) { - delete this._reloadCall; - this.hideMask(); - - if (!result || result.status === 'error') { - OC.Notification.show(result.data.message); - return; - } - if (result.status === 404) { - // go back home - this.changeDirectory('/'); - return; - } - // aborted ? - if (result.status === 0){ - return; - } + var lastIndex = this.$fileList.children().length; + // if there are less elements visible than one page + // but there are still pending elements in the array, + // then directly append the next page + if (lastIndex < this.files.length && lastIndex < this.pageSize) { + this._nextPage(true); + } - // TODO: should rather return upload file size through - // the files list ajax call - Files.updateStorageStatistics(true); + return fileEl; + }, + /** + * Finds the index of the row before which the given + * fileData should be inserted, considering the current + * sorting + */ + _findInsertionIndex: function(fileData) { + var index = 0; + while (index < this.files.length && this._sortComparator(fileData, this.files[index]) > 0) { + index++; + } + return index; + }, + /** + * Moves a file to a given target folder. + * + * @param fileNames array of file names to move + * @param targetPath absolute target path + */ + move: function(fileNames, targetPath) { + var self = this; + var dir = this.getCurrentDirectory(); + var target = OC.basename(targetPath); + if (!_.isArray(fileNames)) { + fileNames = [fileNames]; + } + _.each(fileNames, function(fileName) { + var $tr = self.findFileEl(fileName); + var $td = $tr.children('td.filename'); + var oldBackgroundImage = $td.css('background-image'); + $td.css('background-image', 'url('+ OC.imagePath('core', 'loading.gif') + ')'); + // TODO: improve performance by sending all file names in a single call + $.post( + OC.filePath('files', 'ajax', 'move.php'), + { + dir: dir, + file: fileName, + target: targetPath + }, + function(result) { + if (result) { + if (result.status === 'success') { + // if still viewing the same directory + if (self.getCurrentDirectory() === dir) { + // recalculate folder size + var oldFile = self.findFileEl(target); + var newFile = self.findFileEl(fileName); + var oldSize = oldFile.data('size'); + var newSize = oldSize + newFile.data('size'); + oldFile.data('size', newSize); + oldFile.find('td.filesize').text(OC.Util.humanFileSize(newSize)); + + // TODO: also update entry in FileList.files + + self.remove(fileName); + } + } else { + OC.Notification.hide(); + if (result.status === 'error' && result.data.message) { + OC.Notification.show(result.data.message); + } + else { + OC.Notification.show(t('files', 'Error moving file.')); + } + // hide notification after 10 sec + setTimeout(function() { + OC.Notification.hide(); + }, 10000); + } + } else { + OC.dialogs.alert(t('files', 'Error moving file'), t('files', 'Error')); + } + $td.css('background-image', oldBackgroundImage); + } + ); + }); - if (result.data.permissions) { - this.setDirectoryPermissions(result.data.permissions); - } + }, + + /** + * Triggers file rename input field for the given file name. + * If the user enters a new name, the file will be renamed. + * + * @param oldname file name of the file to rename + */ + rename: function(oldname) { + var self = this; + var tr, td, input, form; + tr = this.findFileEl(oldname); + var oldFileInfo = this.files[tr.index()]; + tr.data('renaming',true); + td = tr.children('td.filename'); + input = $('').val(oldname); + form = $('
'); + form.append(input); + td.children('a.name').hide(); + td.append(form); + input.focus(); + //preselect input + var len = input.val().lastIndexOf('.'); + if ( len === -1 || + tr.data('type') === 'dir' ) { + len = input.val().length; + } + input.selectRange(0, len); + var checkInput = function () { + var filename = input.val(); + if (filename !== oldname) { + // Files.isFileNameValid(filename) throws an exception itself + OCA.Files.Files.isFileNameValid(filename); + if (self.inList(filename)) { + throw t('files', '{new_name} already exists', {new_name: filename}); + } + } + return true; + }; - this.setFiles(result.data.files); - }, - setDirectoryPermissions: function(permissions) { - var isCreatable = (permissions & OC.PERMISSION_CREATE) !== 0; - $('#permissions').val(permissions); - $('.creatable').toggleClass('hidden', !isCreatable); - $('.notCreatable').toggleClass('hidden', isCreatable); - }, - /** - * Shows/hides action buttons - * - * @param show true for enabling, false for disabling - */ - showActions: function(show){ - $('.actions,#file_action_panel').toggleClass('hidden', !show); - if (show){ - // make sure to display according to permissions - var permissions = this.getDirectoryPermissions(); - var isCreatable = (permissions & OC.PERMISSION_CREATE) !== 0; - $('.creatable').toggleClass('hidden', !isCreatable); - $('.notCreatable').toggleClass('hidden', isCreatable); - // remove old style breadcrumbs (some apps might create them) - $('#controls .crumb').remove(); - // refresh breadcrumbs in case it was replaced by an app - this.breadcrumb.render(); - } - else{ - $('.creatable, .notCreatable').addClass('hidden'); - } - }, - /** - * Enables/disables viewer mode. - * In viewer mode, apps can embed themselves under the controls bar. - * In viewer mode, the actions of the file list will be hidden. - * @param show true for enabling, false for disabling - */ - setViewerMode: function(show){ - this.showActions(!show); - $('#filestable').toggleClass('hidden', show); - }, - /** - * Removes a file entry from the list - * @param name name of the file to remove - * @param options optional options as map: - * "updateSummary": true to update the summary (default), false otherwise - * @return deleted element - */ - remove: function(name, options){ - options = options || {}; - var fileEl = FileList.findFileEl(name); - var index = fileEl.index(); - if (!fileEl.length) { - return null; - } - if (this._selectedFiles[fileEl.data('id')]) { - // remove from selection first - this._selectFileEl(fileEl, false); - this.updateSelectionSummary(); - } - if (fileEl.data('permissions') & OC.PERMISSION_DELETE) { - // file is only draggable when delete permissions are set - fileEl.find('td.filename').draggable('destroy'); - } - this.files.splice(index, 1); - fileEl.remove(); - // TODO: improve performance on batch update - FileList.isEmpty = !this.files.length; - if (typeof(options.updateSummary) === 'undefined' || !!options.updateSummary) { - FileList.updateEmptyContent(); - this.fileSummary.remove({type: fileEl.attr('data-type'), size: fileEl.attr('data-size')}, true); - } + form.submit(function(event) { + event.stopPropagation(); + event.preventDefault(); + try { + var newName = input.val(); + if (newName !== oldname) { + checkInput(); + // mark as loading + td.css('background-image', 'url('+ OC.imagePath('core', 'loading.gif') + ')'); + $.ajax({ + url: OC.filePath('files','ajax','rename.php'), + data: { + dir : self.getCurrentDirectory(), + newname: newName, + file: oldname + }, + success: function(result) { + var fileInfo; + if (!result || result.status === 'error') { + OC.dialogs.alert(result.data.message, t('core', 'Could not rename file')); + fileInfo = oldFileInfo; + } + else { + fileInfo = result.data; + } + // reinsert row + self.files.splice(tr.index(), 1); + tr.remove(); + self.add(fileInfo); + } + }); + } + input.tipsy('hide'); + tr.data('renaming',false); + tr.attr('data-file', newName); + var path = td.children('a.name').attr('href'); + // FIXME this will fail if the path contains the filename. + td.children('a.name').attr('href', path.replace(encodeURIComponent(oldname), encodeURIComponent(newName))); + var basename = newName; + if (newName.indexOf('.') > 0 && tr.data('type') !== 'dir') { + basename = newName.substr(0, newName.lastIndexOf('.')); + } + td.find('a.name span.nametext').text(basename); + if (newName.indexOf('.') > 0 && tr.data('type') !== 'dir') { + if ( ! td.find('a.name span.extension').exists() ) { + td.find('a.name span.nametext').append(''); + } + td.find('a.name span.extension').text(newName.substr(newName.lastIndexOf('.'))); + } + form.remove(); + self.fileActions.display( tr.find('td.filename'), true); + td.children('a.name').show(); + } catch (error) { + input.attr('title', error); + input.tipsy({gravity: 'w', trigger: 'manual'}); + input.tipsy('show'); + input.addClass('error'); + } + return false; + }); + input.keyup(function(event) { + // verify filename on typing + try { + checkInput(); + input.tipsy('hide'); + input.removeClass('error'); + } catch (error) { + input.attr('title', error); + input.tipsy({gravity: 'w', trigger: 'manual'}); + input.tipsy('show'); + input.addClass('error'); + } + if (event.keyCode === 27) { + input.tipsy('hide'); + tr.data('renaming',false); + form.remove(); + td.children('a.name').show(); + } + }); + input.click(function(event) { + event.stopPropagation(); + event.preventDefault(); + }); + input.blur(function() { + form.trigger('submit'); + }); + }, + inList:function(file) { + return this.findFileEl(file).length; + }, + /** + * Delete the given files from the given dir + * @param files file names list (without path) + * @param dir directory in which to delete the files, defaults to the current + * directory + */ + do_delete:function(files, dir) { + var self = this; + var params; + if (files && files.substr) { + files=[files]; + } + if (files) { + for (var i=0; itd.date .action.delete').removeClass('delete-icon').addClass('progress-icon'); + } - return fileEl; - }, - /** - * Finds the index of the row before which the given - * fileData should be inserted, considering the current - * sorting - */ - _findInsertionIndex: function(fileData) { - var index = 0; - while (index < this.files.length && this._fileInfoCompare(fileData, this.files[index]) > 0) { - index++; - } - return index; - }, - /** - * Moves a file to a given target folder. - * - * @param fileNames array of file names to move - * @param targetPath absolute target path - */ - move: function(fileNames, targetPath) { - var self = this; - var dir = this.getCurrentDirectory(); - var target = OC.basename(targetPath); - if (!_.isArray(fileNames)) { - fileNames = [fileNames]; - } - _.each(fileNames, function(fileName) { - var $tr = self.findFileEl(fileName); - var $td = $tr.children('td.filename'); - var oldBackgroundImage = $td.css('background-image'); - $td.css('background-image', 'url('+ OC.imagePath('core', 'loading.gif') + ')'); - // TODO: improve performance by sending all file names in a single call - $.post( - OC.filePath('files', 'ajax', 'move.php'), - { - dir: dir, - file: fileName, - target: targetPath - }, - function(result) { - if (result) { + $.post(OC.filePath('files', 'ajax', 'delete.php'), + params, + function(result) { if (result.status === 'success') { - // if still viewing the same directory - if (self.getCurrentDirectory() === dir) { - // recalculate folder size - var oldFile = self.findFileEl(target); - var newFile = self.findFileEl(fileName); - var oldSize = oldFile.data('size'); - var newSize = oldSize + newFile.data('size'); - oldFile.data('size', newSize); - oldFile.find('td.filesize').text(OC.Util.humanFileSize(newSize)); - - // TODO: also update entry in FileList.files - - self.remove(fileName); + if (params.allfiles) { + self.setFiles([]); + } + else { + $.each(files,function(index,file) { + var fileEl = self.remove(file, {updateSummary: false}); + // FIXME: not sure why we need this after the + // element isn't even in the DOM any more + fileEl.find('input[type="checkbox"]').prop('checked', false); + fileEl.removeClass('selected'); + self.fileSummary.remove({type: fileEl.attr('data-type'), size: fileEl.attr('data-size')}); + }); } + // TODO: this info should be returned by the ajax call! + self.updateEmptyContent(); + self.fileSummary.update(); + self.updateSelectionSummary(); + self.updateStorageStatistics(); } else { - OC.Notification.hide(); if (result.status === 'error' && result.data.message) { OC.Notification.show(result.data.message); } else { - OC.Notification.show(t('files', 'Error moving file.')); + OC.Notification.show(t('files', 'Error deleting file.')); } // hide notification after 10 sec setTimeout(function() { OC.Notification.hide(); }, 10000); - } - } else { - OC.dialogs.alert(t('files', 'Error moving file'), t('files', 'Error')); - } - $td.css('background-image', oldBackgroundImage); - }); - }); - - }, - - /** - * Triggers file rename input field for the given file name. - * If the user enters a new name, the file will be renamed. - * - * @param oldname file name of the file to rename - */ - rename: function(oldname) { - var tr, td, input, form; - tr = FileList.findFileEl(oldname); - var oldFileInfo = this.files[tr.index()]; - tr.data('renaming',true); - td = tr.children('td.filename'); - input = $('').val(oldname); - form = $('
'); - form.append(input); - td.children('a.name').hide(); - td.append(form); - input.focus(); - //preselect input - var len = input.val().lastIndexOf('.'); - if ( len === -1 || - tr.data('type') === 'dir' ) { - len = input.val().length; - } - input.selectRange(0, len); - var checkInput = function () { - var filename = input.val(); - if (filename !== oldname) { - // Files.isFileNameValid(filename) throws an exception itself - Files.isFileNameValid(filename); - if (FileList.inList(filename)) { - throw t('files', '{new_name} already exists', {new_name: filename}); - } - } - return true; - }; - - form.submit(function(event) { - event.stopPropagation(); - event.preventDefault(); - try { - var newName = input.val(); - if (newName !== oldname) { - checkInput(); - // mark as loading - td.css('background-image', 'url('+ OC.imagePath('core', 'loading.gif') + ')'); - $.ajax({ - url: OC.filePath('files','ajax','rename.php'), - data: { - dir : $('#dir').val(), - newname: newName, - file: oldname - }, - success: function(result) { - var fileInfo; - if (!result || result.status === 'error') { - OC.dialogs.alert(result.data.message, t('core', 'Could not rename file')); - fileInfo = oldFileInfo; + if (params.allfiles) { + // reload the page as we don't know what files were deleted + // and which ones remain + self.reload(); } else { - fileInfo = result.data; + $.each(files,function(index,file) { + var deleteAction = self.findFileEl(file).find('.action.delete'); + deleteAction.removeClass('progress-icon').addClass('delete-icon'); + }); } - // reinsert row - FileList.files.splice(tr.index(), 1); - tr.remove(); - FileList.add(fileInfo); } }); - } - input.tipsy('hide'); - tr.data('renaming',false); - tr.attr('data-file', newName); - var path = td.children('a.name').attr('href'); - // FIXME this will fail if the path contains the filename. - td.children('a.name').attr('href', path.replace(encodeURIComponent(oldname), encodeURIComponent(newName))); - var basename = newName; - if (newName.indexOf('.') > 0 && tr.data('type') !== 'dir') { - basename = newName.substr(0, newName.lastIndexOf('.')); - } - td.find('a.name span.nametext').text(basename); - if (newName.indexOf('.') > 0 && tr.data('type') !== 'dir') { - if ( ! td.find('a.name span.extension').exists() ) { - td.find('a.name span.nametext').append(''); - } - td.find('a.name span.extension').text(newName.substr(newName.lastIndexOf('.'))); - } - form.remove(); - FileActions.display( tr.find('td.filename'), true); - td.children('a.name').show(); - } catch (error) { - input.attr('title', error); - input.tipsy({gravity: 'w', trigger: 'manual'}); - input.tipsy('show'); - input.addClass('error'); - } - return false; - }); - input.keyup(function(event) { - // verify filename on typing - try { - checkInput(); - input.tipsy('hide'); - input.removeClass('error'); - } catch (error) { - input.attr('title', error); - input.tipsy({gravity: 'w', trigger: 'manual'}); - input.tipsy('show'); - input.addClass('error'); - } - if (event.keyCode === 27) { - input.tipsy('hide'); - tr.data('renaming',false); - form.remove(); - td.children('a.name').show(); - } - }); - input.click(function(event) { - event.stopPropagation(); - event.preventDefault(); - }); - input.blur(function() { - form.trigger('submit'); - }); - }, - inList:function(file) { - return FileList.findFileEl(file).length; - }, - /** - * Delete the given files from the given dir - * @param files file names list (without path) - * @param dir directory in which to delete the files, defaults to the current - * directory - */ - do_delete:function(files, dir) { - var params; - if (files && files.substr) { - files=[files]; - } - if (files) { - for (var i=0; i'); + this.$el.find('tfoot').append($tr); + + return new OCA.Files.FileSummary($tr); + }, + updateEmptyContent: function() { + var permissions = this.getDirectoryPermissions(); + var isCreatable = (permissions & OC.PERMISSION_CREATE) !== 0; + this.$el.find('#emptycontent').toggleClass('hidden', !isCreatable || !this.isEmpty); + this.$el.find('#filestable thead th').toggleClass('hidden', this.isEmpty); + }, + /** + * Shows the loading mask. + * + * @see #hideMask + */ + showMask: function() { + // in case one was shown before + var $mask = this.$el.find('.mask'); + if ($mask.exists()) { + return; } - } - // Finish any existing actions - if (FileList.lastAction) { - FileList.lastAction(); - } - params = { - dir: dir || FileList.getCurrentDirectory() - }; - if (files) { - params.files = JSON.stringify(files); - } - else { - // no files passed, delete all in current dir - params.allfiles = true; - // show spinner for all files - this.$fileList.find('tr>td.date .action.delete').removeClass('delete-icon').addClass('progress-icon'); - } - - $.post(OC.filePath('files', 'ajax', 'delete.php'), - params, - function(result) { - if (result.status === 'success') { - if (params.allfiles) { - FileList.setFiles([]); - } - else { - $.each(files,function(index,file) { - var fileEl = FileList.remove(file, {updateSummary: false}); - // FIXME: not sure why we need this after the - // element isn't even in the DOM any more - fileEl.find('input[type="checkbox"]').prop('checked', false); - fileEl.removeClass('selected'); - FileList.fileSummary.remove({type: fileEl.attr('data-type'), size: fileEl.attr('data-size')}); - }); - } - // TODO: this info should be returned by the ajax call! - checkTrashStatus(); - FileList.updateEmptyContent(); - FileList.fileSummary.update(); - FileList.updateSelectionSummary(); - Files.updateStorageStatistics(); - } else { - if (result.status === 'error' && result.data.message) { - OC.Notification.show(result.data.message); - } - else { - OC.Notification.show(t('files', 'Error deleting file.')); - } - // hide notification after 10 sec - setTimeout(function() { - OC.Notification.hide(); - }, 10000); - if (params.allfiles) { - // reload the page as we don't know what files were deleted - // and which ones remain - FileList.reload(); - } - else { - $.each(files,function(index,file) { - var deleteAction = FileList.findFileEl(file).find('.action.delete'); - deleteAction.removeClass('progress-icon').addClass('delete-icon'); - }); - } - } + this.$table.addClass('hidden'); + + $mask = $('
'); + + $mask.css('background-image', 'url('+ OC.imagePath('core', 'loading.gif') + ')'); + $mask.css('background-repeat', 'no-repeat'); + this.$el.append($mask); + + $mask.removeClass('transparent'); + }, + /** + * Hide the loading mask. + * @see #showMask + */ + hideMask: function() { + this.$el.find('.mask').remove(); + this.$table.removeClass('hidden'); + }, + scrollTo:function(file) { + //scroll to and highlight preselected file + var $scrollToRow = this.findFileEl(file); + if ($scrollToRow.exists()) { + $scrollToRow.addClass('searchresult'); + $(window).scrollTop($scrollToRow.position().top); + //remove highlight when hovered over + $scrollToRow.one('hover', function() { + $scrollToRow.removeClass('searchresult'); }); - }, - /** - * Creates the file summary section - */ - _createSummary: function() { - var $tr = $(''); - this.$el.find('tfoot').append($tr); - - return new FileSummary($tr); - }, - updateEmptyContent: function() { - var permissions = $('#permissions').val(); - var isCreatable = (permissions & OC.PERMISSION_CREATE) !== 0; - $('#emptycontent').toggleClass('hidden', !isCreatable || !FileList.isEmpty); - $('#filestable thead th').toggleClass('hidden', FileList.isEmpty); - }, - /** - * Shows the loading mask. - * - * @see #hideMask - */ - showMask: function() { - // in case one was shown before - var $mask = $('#content .mask'); - if ($mask.exists()) { - return; - } - - this.$el.addClass('hidden'); - - $mask = $('
'); - - $mask.css('background-image', 'url('+ OC.imagePath('core', 'loading.gif') + ')'); - $mask.css('background-repeat', 'no-repeat'); - $('#content').append($mask); - - $mask.removeClass('transparent'); - }, - /** - * Hide the loading mask. - * @see #showMask - */ - hideMask: function() { - $('#content .mask').remove(); - this.$el.removeClass('hidden'); - }, - scrollTo:function(file) { - //scroll to and highlight preselected file - var $scrollToRow = FileList.findFileEl(file); - if ($scrollToRow.exists()) { - $scrollToRow.addClass('searchresult'); - $(window).scrollTop($scrollToRow.position().top); - //remove highlight when hovered over - $scrollToRow.one('hover', function() { - $scrollToRow.removeClass('searchresult'); + } + }, + filter:function(query) { + this.$fileList.find('tr').each(function(i,e) { + if ($(e).data('file').toString().toLowerCase().indexOf(query.toLowerCase()) !== -1) { + $(e).addClass("searchresult"); + } else { + $(e).removeClass("searchresult"); + } }); - } - }, - filter:function(query) { - $('#fileList tr').each(function(i,e) { - if ($(e).data('file').toString().toLowerCase().indexOf(query.toLowerCase()) !== -1) { - $(e).addClass("searchresult"); - } else { + //do not use scrollto to prevent removing searchresult css class + var first = this.$fileList.find('tr.searchresult').first(); + if (first.exists()) { + $(window).scrollTop(first.position().top); + } + }, + unfilter:function() { + this.$fileList.find('tr.searchresult').each(function(i,e) { $(e).removeClass("searchresult"); + }); + }, + /** + * Update UI based on the current selection + */ + updateSelectionSummary: function() { + var summary = this._selectionSummary.summary; + var canDelete; + if (summary.totalFiles === 0 && summary.totalDirs === 0) { + this.$el.find('#headerName a.name>span:first').text(t('files','Name')); + this.$el.find('#headerSize a>span:first').text(t('files','Size')); + this.$el.find('#modified a>span:first').text(t('files','Modified')); + this.$el.find('table').removeClass('multiselect'); + this.$el.find('.selectedActions').addClass('hidden'); } - }); - //do not use scrollto to prevent removing searchresult css class - var first = $('#fileList tr.searchresult').first(); - if (first.exists()) { - $(window).scrollTop(first.position().top); - } - }, - unfilter:function() { - $('#fileList tr.searchresult').each(function(i,e) { - $(e).removeClass("searchresult"); - }); - }, - /** - * Update UI based on the current selection - */ - updateSelectionSummary: function() { - var summary = this._selectionSummary.summary; - if (summary.totalFiles === 0 && summary.totalDirs === 0) { - $('#headerName span.name').text(t('files','Name')); - $('#headerSize').text(t('files','Size')); - $('#modified').text(t('files','Modified')); - $('table').removeClass('multiselect'); - $('.selectedActions').addClass('hidden'); - } - else { - $('.selectedActions').removeClass('hidden'); - $('#headerSize').text(OC.Util.humanFileSize(summary.totalSize)); - var selection = ''; - if (summary.totalDirs > 0) { - selection += n('files', '%n folder', '%n folders', summary.totalDirs); + else { + canDelete = (this.getDirectoryPermissions() & OC.PERMISSION_DELETE); + this.$el.find('.selectedActions').removeClass('hidden'); + this.$el.find('#headerSize a>span:first').text(OC.Util.humanFileSize(summary.totalSize)); + var selection = ''; + if (summary.totalDirs > 0) { + selection += n('files', '%n folder', '%n folders', summary.totalDirs); + if (summary.totalFiles > 0) { + selection += ' & '; + } + } if (summary.totalFiles > 0) { - selection += ' & '; + selection += n('files', '%n file', '%n files', summary.totalFiles); } + this.$el.find('#headerName a.name>span:first').text(selection); + this.$el.find('#modified a>span:first').text(''); + this.$el.find('table').addClass('multiselect'); + this.$el.find('.delete-selected').toggleClass('hidden', !canDelete); } - if (summary.totalFiles > 0) { - selection += n('files', '%n file', '%n files', summary.totalFiles); + }, + + /** + * Returns whether all files are selected + * @return true if all files are selected, false otherwise + */ + isAllSelected: function() { + return this.$el.find('.select-all').prop('checked'); + }, + + /** + * Returns the file info of the selected files + * + * @return array of file names + */ + getSelectedFiles: function() { + return _.values(this._selectedFiles); + }, + + getUniqueName: function(name) { + if (this.findFileEl(name).exists()) { + var numMatch; + var parts=name.split('.'); + var extension = ""; + if (parts.length > 1) { + extension=parts.pop(); + } + var base=parts.join('.'); + numMatch=base.match(/\((\d+)\)/); + var num=2; + if (numMatch && numMatch.length>0) { + num=parseInt(numMatch[numMatch.length-1])+1; + base=base.split('('); + base.pop(); + base=$.trim(base.join('(')); + } + name=base+' ('+num+')'; + if (extension) { + name = name+'.'+extension; + } + // FIXME: ugly recursion + return this.getUniqueName(name); } - $('#headerName span.name').text(selection); - $('#modified').text(''); - $('table').addClass('multiselect'); - } - }, + return name; + }, - /** - * Returns whether all files are selected - * @return true if all files are selected, false otherwise - */ - isAllSelected: function() { - return this.$el.find('#select_all').prop('checked'); - }, + /** + * Setup file upload events related to the file-upload plugin + */ + setupUploadEvents: function() { + var self = this; - /** - * Returns the file info of the selected files - * - * @return array of file names - */ - getSelectedFiles: function() { - return _.values(this._selectedFiles); - } -}; + // handle upload events + var fileUploadStart = this.$el.find('#file_upload_start'); -$(document).ready(function() { - FileList.initialize(); + fileUploadStart.on('fileuploaddrop', function(e, data) { + OC.Upload.log('filelist handle fileuploaddrop', e, data); - // handle upload events - var fileUploadStart = $('#file_upload_start'); + var dropTarget = $(e.originalEvent.target).closest('tr, .crumb'); + // check if dropped inside this list at all + if (dropTarget && !self.$el.has(dropTarget).length) { + return false; + } - fileUploadStart.on('fileuploaddrop', function(e, data) { - OC.Upload.log('filelist handle fileuploaddrop', e, data); + if (dropTarget && (dropTarget.data('type') === 'dir' || dropTarget.hasClass('crumb'))) { // drag&drop upload to folder - var dropTarget = $(e.originalEvent.target).closest('tr, .crumb'); - if (dropTarget && (dropTarget.data('type') === 'dir' || dropTarget.hasClass('crumb'))) { // drag&drop upload to folder + // remember as context + data.context = dropTarget; - // remember as context - data.context = dropTarget; + var dir = dropTarget.data('file'); + // if from file list, need to prepend parent dir + if (dir) { + var parentDir = self.getCurrentDirectory(); + if (parentDir[parentDir.length - 1] !== '/') { + parentDir += '/'; + } + dir = parentDir + dir; + } + else{ + // read full path from crumb + dir = dropTarget.data('dir') || '/'; + } - var dir = dropTarget.data('file'); - // if from file list, need to prepend parent dir - if (dir) { - var parentDir = $('#dir').val() || '/'; - if (parentDir[parentDir.length - 1] !== '/') { - parentDir += '/'; + // update folder in form + data.formData = function(form) { + return [ + {name: 'dir', value: dir}, + {name: 'requesttoken', value: oc_requesttoken}, + {name: 'file_directory', value: data.files[0].relativePath} + ]; + }; + } else { + // cancel uploads to current dir if no permission + var isCreatable = (self.getDirectoryPermissions() & OC.PERMISSION_CREATE) !== 0; + if (!isCreatable) { + return false; + } } - dir = parentDir + dir; - } - else{ - // read full path from crumb - dir = dropTarget.data('dir') || '/'; - } - - // update folder in form - data.formData = function(form) { - return [ - {name: 'dir', value: dir}, - {name: 'requesttoken', value: oc_requesttoken}, - {name: 'file_directory', value: data.files[0].relativePath} - ]; - }; - } else { - // cancel uploads to current dir if no permission - var isCreatable = (FileList.getDirectoryPermissions() & OC.PERMISSION_CREATE) !== 0; - if (!isCreatable) { - return false; - } - } - }); - fileUploadStart.on('fileuploadadd', function(e, data) { - OC.Upload.log('filelist handle fileuploadadd', e, data); + }); + fileUploadStart.on('fileuploadadd', function(e, data) { + OC.Upload.log('filelist handle fileuploadadd', e, data); - //finish delete if we are uploading a deleted file - if (FileList.deleteFiles && FileList.deleteFiles.indexOf(data.files[0].name)!==-1) { - FileList.finishDelete(null, true); //delete file before continuing - } + //finish delete if we are uploading a deleted file + if (self.deleteFiles && self.deleteFiles.indexOf(data.files[0].name)!==-1) { + self.finishDelete(null, true); //delete file before continuing + } - // add ui visualization to existing folder - if (data.context && data.context.data('type') === 'dir') { - // add to existing folder - - // update upload counter ui - var uploadText = data.context.find('.uploadtext'); - var currentUploads = parseInt(uploadText.attr('currentUploads'), 10); - currentUploads += 1; - uploadText.attr('currentUploads', currentUploads); - - var translatedText = n('files', 'Uploading %n file', 'Uploading %n files', currentUploads); - if (currentUploads === 1) { - var img = OC.imagePath('core', 'loading.gif'); - data.context.find('td.filename').attr('style','background-image:url('+img+')'); - uploadText.text(translatedText); - uploadText.show(); - } else { - uploadText.text(translatedText); - } - } + // add ui visualization to existing folder + if (data.context && data.context.data('type') === 'dir') { + // add to existing folder + + // update upload counter ui + var uploadText = data.context.find('.uploadtext'); + var currentUploads = parseInt(uploadText.attr('currentUploads'), 10); + currentUploads += 1; + uploadText.attr('currentUploads', currentUploads); + + var translatedText = n('files', 'Uploading %n file', 'Uploading %n files', currentUploads); + if (currentUploads === 1) { + var img = OC.imagePath('core', 'loading.gif'); + data.context.find('td.filename').attr('style','background-image:url('+img+')'); + uploadText.text(translatedText); + uploadText.show(); + } else { + uploadText.text(translatedText); + } + } - }); - /* - * when file upload done successfully add row to filelist - * update counter when uploading to sub folder - */ - fileUploadStart.on('fileuploaddone', function(e, data) { - OC.Upload.log('filelist handle fileuploaddone', e, data); - - var response; - if (typeof data.result === 'string') { - response = data.result; - } else { - // fetch response from iframe - response = data.result[0].body.innerText; - } - var result=$.parseJSON(response); + }); + /* + * when file upload done successfully add row to filelist + * update counter when uploading to sub folder + */ + fileUploadStart.on('fileuploaddone', function(e, data) { + OC.Upload.log('filelist handle fileuploaddone', e, data); + + var response; + if (typeof data.result === 'string') { + response = data.result; + } else { + // fetch response from iframe + response = data.result[0].body.innerText; + } + var result=$.parseJSON(response); + + if (typeof result[0] !== 'undefined' && result[0].status === 'success') { + var file = result[0]; + var size = 0; + + if (data.context && data.context.data('type') === 'dir') { + + // update upload counter ui + var uploadText = data.context.find('.uploadtext'); + var currentUploads = parseInt(uploadText.attr('currentUploads'), 10); + currentUploads -= 1; + uploadText.attr('currentUploads', currentUploads); + var translatedText = n('files', 'Uploading %n file', 'Uploading %n files', currentUploads); + if (currentUploads === 0) { + var img = OC.imagePath('core', 'filetypes/folder'); + data.context.find('td.filename').attr('style','background-image:url('+img+')'); + uploadText.text(translatedText); + uploadText.hide(); + } else { + uploadText.text(translatedText); + } - if (typeof result[0] !== 'undefined' && result[0].status === 'success') { - var file = result[0]; - var size = 0; + // update folder size + size = parseInt(data.context.data('size'), 10); + size += parseInt(file.size, 10); + data.context.attr('data-size', size); + data.context.find('td.filesize').text(humanFileSize(size)); + } else { + // only append new file if uploaded into the current folder + if (file.directory !== '/' && file.directory !== self.getCurrentDirectory()) { + + var fileDirectory = file.directory.replace('/','').replace(/\/$/, "").split('/'); + + if (fileDirectory.length === 1) { + fileDirectory = fileDirectory[0]; + + // Get the directory + var fd = self.findFileEl(fileDirectory); + if (fd.length === 0) { + var dir = { + name: fileDirectory, + type: 'dir', + mimetype: 'httpd/unix-directory', + permissions: file.permissions, + size: 0, + id: file.parentId + }; + self.add(dir, {insert: true}); + } + } else { + fileDirectory = fileDirectory[0]; + } + + fileDirectory = self.findFileEl(fileDirectory); - if (data.context && data.context.data('type') === 'dir') { + // update folder size + size = parseInt(fileDirectory.attr('data-size'), 10); + size += parseInt(file.size, 10); + fileDirectory.attr('data-size', size); + fileDirectory.find('td.filesize').text(humanFileSize(size)); - // update upload counter ui - var uploadText = data.context.find('.uploadtext'); - var currentUploads = parseInt(uploadText.attr('currentUploads'), 10); - currentUploads -= 1; - uploadText.attr('currentUploads', currentUploads); - var translatedText = n('files', 'Uploading %n file', 'Uploading %n files', currentUploads); - if (currentUploads === 0) { - var img = OC.imagePath('core', 'filetypes/folder'); - data.context.find('td.filename').attr('style','background-image:url('+img+')'); - uploadText.text(translatedText); - uploadText.hide(); - } else { - uploadText.text(translatedText); - } + return; + } - // update folder size - size = parseInt(data.context.data('size'), 10); - size += parseInt(file.size, 10); - data.context.attr('data-size', size); - data.context.find('td.filesize').text(humanFileSize(size)); - } else { - // only append new file if uploaded into the current folder - if (file.directory !== '/' && file.directory !== FileList.getCurrentDirectory()) { - - var fileDirectory = file.directory.replace('/','').replace(/\/$/, "").split('/'); - - if (fileDirectory.length === 1) { - fileDirectory = fileDirectory[0]; - - // Get the directory - var fd = FileList.findFileEl(fileDirectory); - if (fd.length === 0) { - var dir = { - name: fileDirectory, - type: 'dir', - mimetype: 'httpd/unix-directory', - permissions: file.permissions, - size: 0, - id: file.parentId - }; - FileList.add(dir, {insert: true}); + // add as stand-alone row to filelist + size = t('files', 'Pending'); + if (data.files[0].size>=0) { + size=data.files[0].size; } - } else { - fileDirectory = fileDirectory[0]; - } - - fileDirectory = FileList.findFileEl(fileDirectory); + //should the file exist in the list remove it + self.remove(file.name); - // update folder size - size = parseInt(fileDirectory.attr('data-size'), 10); - size += parseInt(file.size, 10); - fileDirectory.attr('data-size', size); - fileDirectory.find('td.filesize').text(humanFileSize(size)); + // create new file context + data.context = self.add(file, {animate: true}); + } + } + }); + fileUploadStart.on('fileuploadstop', function(e, data) { + OC.Upload.log('filelist handle fileuploadstop', e, data); - return; + //if user pressed cancel hide upload chrome + if (data.errorThrown === 'abort') { + //cleanup uploading to a dir + var uploadText = $('tr .uploadtext'); + var img = OC.imagePath('core', 'filetypes/folder'); + uploadText.parents('td.filename').attr('style','background-image:url('+img+')'); + uploadText.fadeOut(); + uploadText.attr('currentUploads', 0); } + self.updateStorageStatistics(); + }); + fileUploadStart.on('fileuploadfail', function(e, data) { + OC.Upload.log('filelist handle fileuploadfail', e, data); - // add as stand-alone row to filelist - size = t('files', 'Pending'); - if (data.files[0].size>=0) { - size=data.files[0].size; + //if user pressed cancel hide upload chrome + if (data.errorThrown === 'abort') { + //cleanup uploading to a dir + var uploadText = $('tr .uploadtext'); + var img = OC.imagePath('core', 'filetypes/folder'); + uploadText.parents('td.filename').attr('style','background-image:url('+img+')'); + uploadText.fadeOut(); + uploadText.attr('currentUploads', 0); } - //should the file exist in the list remove it - FileList.remove(file.name); + self.updateStorageStatistics(); + }); - // create new file context - data.context = FileList.add(file, {animate: true}); - } } - }); - fileUploadStart.on('fileuploadstop', function(e, data) { - OC.Upload.log('filelist handle fileuploadstop', e, data); - - //if user pressed cancel hide upload chrome - if (data.errorThrown === 'abort') { - //cleanup uploading to a dir - var uploadText = $('tr .uploadtext'); - var img = OC.imagePath('core', 'filetypes/folder'); - uploadText.parents('td.filename').attr('style','background-image:url('+img+')'); - uploadText.fadeOut(); - uploadText.attr('currentUploads', 0); - } - }); - fileUploadStart.on('fileuploadfail', function(e, data) { - OC.Upload.log('filelist handle fileuploadfail', e, data); - - //if user pressed cancel hide upload chrome - if (data.errorThrown === 'abort') { - //cleanup uploading to a dir - var uploadText = $('tr .uploadtext'); - var img = OC.imagePath('core', 'filetypes/folder'); - uploadText.parents('td.filename').attr('style','background-image:url('+img+')'); - uploadText.fadeOut(); - uploadText.attr('currentUploads', 0); - } - }); + }; - $('#notification').hide(); - $('#notification:first-child').on('click', '.replace', function() { - OC.Notification.hide(function() { - FileList.replace( - $('#notification > span').attr('data-oldName'), - $('#notification > span').attr('data-newName'), - $('#notification > span').attr('data-isNewFile')); - }); - }); - $('#notification:first-child').on('click', '.suggest', function() { - var file = $('#notification > span').attr('data-oldName'); - FileList.findFileEl(file).removeClass('hidden'); - OC.Notification.hide(); - }); - $('#notification:first-child').on('click', '.cancel', function() { - if ($('#notification > span').attr('data-isNewFile')) { - FileList.deleteCanceled = false; - FileList.deleteFiles = [$('#notification > span').attr('data-oldName')]; + /** + * Sort comparators. + */ + FileList.Comparators = { + /** + * Compares two file infos by name, making directories appear + * first. + * + * @param fileInfo1 file info + * @param fileInfo2 file info + * @return -1 if the first file must appear before the second one, + * 0 if they are identify, 1 otherwise. + */ + name: function(fileInfo1, fileInfo2) { + if (fileInfo1.type === 'dir' && fileInfo2.type !== 'dir') { + return -1; + } + if (fileInfo1.type !== 'dir' && fileInfo2.type === 'dir') { + return 1; + } + return fileInfo1.name.localeCompare(fileInfo2.name); + }, + /** + * Compares two file infos by size. + * + * @param fileInfo1 file info + * @param fileInfo2 file info + * @return -1 if the first file must appear before the second one, + * 0 if they are identify, 1 otherwise. + */ + size: function(fileInfo1, fileInfo2) { + return fileInfo1.size - fileInfo2.size; + }, + /** + * Compares two file infos by timestamp. + * + * @param fileInfo1 file info + * @param fileInfo2 file info + * @return -1 if the first file must appear before the second one, + * 0 if they are identify, 1 otherwise. + */ + mtime: function(fileInfo1, fileInfo2) { + return fileInfo1.mtime - fileInfo2.mtime; } - }); - FileList.useUndo=(window.onbeforeunload)?true:false; + }; + + OCA.Files.FileList = FileList; +})(); + +$(document).ready(function() { + // FIXME: unused ? + OCA.Files.FileList.useUndo = (window.onbeforeunload)?true:false; $(window).bind('beforeunload', function () { - if (FileList.lastAction) { - FileList.lastAction(); + if (OCA.Files.FileList.lastAction) { + OCA.Files.FileList.lastAction(); } }); $(window).unload(function () { $(window).trigger('beforeunload'); }); - function decodeQuery(query) { - return query.replace(/\+/g, ' '); - } - - function parseHashQuery() { - var hash = window.location.hash, - pos = hash.indexOf('?'); - if (pos >= 0) { - return hash.substr(pos + 1); - } - return ''; - } - - function parseCurrentDirFromUrl() { - var query = parseHashQuery(), - params; - // try and parse from URL hash first - if (query) { - params = OC.parseQueryString(decodeQuery(query)); - } - // else read from query attributes - if (!params) { - params = OC.parseQueryString(decodeQuery(location.search)); - } - return (params && params.dir) || '/'; - } - - // disable ajax/history API for public app (TODO: until it gets ported) - // fallback to hashchange when no history support - if (!window.history.pushState) { - $(window).on('hashchange', function() { - FileList.changeDirectory(parseCurrentDirFromUrl(), false); - }); - } - window.onpopstate = function(e) { - var targetDir; - if (e.state && e.state.dir) { - targetDir = e.state.dir; - } - else{ - // read from URL - targetDir = parseCurrentDirFromUrl(); - } - if (targetDir) { - FileList.changeDirectory(targetDir, false); - } - }; - - $(window).scroll(function(e) {FileList._onScroll(e);}); - - var dir = parseCurrentDirFromUrl(); - // trigger ajax load, deferred to let sub-apps do their overrides first - setTimeout(function() { - FileList.changeDirectory(dir, false, true); - }, 0); }); - diff --git a/apps/files/js/files.js b/apps/files/js/files.js index 6d167851e64465249f0a3e23a1299e3da22c1cb4..92f97f5d3c055fd724b4d25e954ab3f3772fa17f 100644 --- a/apps/files/js/files.js +++ b/apps/files/js/files.js @@ -8,257 +8,296 @@ * */ -/* global OC, t, FileList */ /* global getURLParameter */ -var Files = { - // file space size sync - _updateStorageStatistics: function() { - Files._updateStorageStatisticsTimeout = null; - var currentDir = FileList.getCurrentDirectory(), - state = Files.updateStorageStatistics; - if (state.dir){ - if (state.dir === currentDir) { +/** + * Utility class for file related operations + */ +(function() { + var Files = { + // file space size sync + _updateStorageStatistics: function(currentDir) { + var state = Files.updateStorageStatistics; + if (state.dir){ + if (state.dir === currentDir) { + return; + } + // cancel previous call, as it was for another dir + state.call.abort(); + } + state.dir = currentDir; + state.call = $.getJSON(OC.filePath('files','ajax','getstoragestats.php') + '?dir=' + encodeURIComponent(currentDir),function(response) { + state.dir = null; + state.call = null; + Files.updateMaxUploadFilesize(response); + }); + }, + /** + * Update storage statistics such as free space, max upload, + * etc based on the given directory. + * + * Note this function is debounced to avoid making too + * many ajax calls in a row. + * + * @param dir directory + * @param force whether to force retrieving + */ + updateStorageStatistics: function(dir, force) { + if (!OC.currentUser) { return; } - // cancel previous call, as it was for another dir - state.call.abort(); - } - state.dir = currentDir; - state.call = $.getJSON(OC.filePath('files','ajax','getstoragestats.php') + '?dir=' + encodeURIComponent(currentDir),function(response) { - state.dir = null; - state.call = null; - Files.updateMaxUploadFilesize(response); - }); - }, - updateStorageStatistics: function(force) { - if (!OC.currentUser) { - return; - } - - // debounce to prevent calling too often - if (Files._updateStorageStatisticsTimeout) { - clearTimeout(Files._updateStorageStatisticsTimeout); - } - if (force) { - Files._updateStorageStatistics(); - } - else { - Files._updateStorageStatisticsTimeout = setTimeout(Files._updateStorageStatistics, 250); - } - }, - - updateMaxUploadFilesize:function(response) { - if (response === undefined) { - return; - } - if (response.data !== undefined && response.data.uploadMaxFilesize !== undefined) { - $('#max_upload').val(response.data.uploadMaxFilesize); - $('#free_space').val(response.data.freeSpace); - $('#upload.button').attr('original-title', response.data.maxHumanFilesize); - $('#usedSpacePercent').val(response.data.usedSpacePercent); - Files.displayStorageWarnings(); - } - if (response[0] === undefined) { - return; - } - if (response[0].uploadMaxFilesize !== undefined) { - $('#max_upload').val(response[0].uploadMaxFilesize); - $('#upload.button').attr('original-title', response[0].maxHumanFilesize); - $('#usedSpacePercent').val(response[0].usedSpacePercent); - Files.displayStorageWarnings(); - } - - }, - - /** - * Fix path name by removing double slash at the beginning, if any - */ - fixPath: function(fileName) { - if (fileName.substr(0, 2) == '//') { - return fileName.substr(1); - } - return fileName; - }, - /** - * Checks whether the given file name is valid. - * @param name file name to check - * @return true if the file name is valid. - * Throws a string exception with an error message if - * the file name is not valid - */ - isFileNameValid: function (name) { - var trimmedName = name.trim(); - if (trimmedName === '.' || trimmedName === '..') - { - throw t('files', '"{name}" is an invalid file name.', {name: name}); - } else if (trimmedName.length === 0) { - throw t('files', 'File name cannot be empty.'); - } - // check for invalid characters - var invalidCharacters = - ['\\', '/', '<', '>', ':', '"', '|', '?', '*', '\n']; - for (var i = 0; i < invalidCharacters.length; i++) { - if (trimmedName.indexOf(invalidCharacters[i]) !== -1) { - throw t('files', "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed."); + if (force) { + Files._updateStorageStatistics(dir); } - } - return true; - }, - displayStorageWarnings: function() { - if (!OC.Notification.isHidden()) { - return; - } - - var usedSpacePercent = $('#usedSpacePercent').val(); - if (usedSpacePercent > 98) { - OC.Notification.show(t('files', 'Your storage is full, files can not be updated or synced anymore!')); - return; - } - if (usedSpacePercent > 90) { - OC.Notification.show(t('files', 'Your storage is almost full ({usedSpacePercent}%)', - {usedSpacePercent: usedSpacePercent})); - } - }, - - displayEncryptionWarning: function() { - - if (!OC.Notification.isHidden()) { - return; - } + else { + Files._updateStorageStatisticsDebounced(dir); + } + }, - var encryptedFiles = $('#encryptedFiles').val(); - var initStatus = $('#encryptionInitStatus').val(); - if (initStatus === '0') { // enc not initialized, but should be - OC.Notification.show(t('files', 'Encryption App is enabled but your keys are not initialized, please log-out and log-in again')); - return; - } - if (initStatus === '1') { // encryption tried to init but failed - OC.Notification.show(t('files', 'Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files.')); - return; - } - if (encryptedFiles === '1') { - OC.Notification.show(t('files', 'Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files.')); - return; - } - }, + updateMaxUploadFilesize:function(response) { + if (response === undefined) { + return; + } + if (response.data !== undefined && response.data.uploadMaxFilesize !== undefined) { + $('#max_upload').val(response.data.uploadMaxFilesize); + $('#free_space').val(response.data.freeSpace); + $('#upload.button').attr('original-title', response.data.maxHumanFilesize); + $('#usedSpacePercent').val(response.data.usedSpacePercent); + Files.displayStorageWarnings(); + } + if (response[0] === undefined) { + return; + } + if (response[0].uploadMaxFilesize !== undefined) { + $('#max_upload').val(response[0].uploadMaxFilesize); + $('#upload.button').attr('original-title', response[0].maxHumanFilesize); + $('#usedSpacePercent').val(response[0].usedSpacePercent); + Files.displayStorageWarnings(); + } - // TODO: move to FileList class - setupDragAndDrop: function() { - var $fileList = $('#fileList'); + }, - //drag/drop of files - $fileList.find('tr td.filename').each(function(i,e) { - if ($(e).parent().data('permissions') & OC.PERMISSION_DELETE) { - $(e).draggable(dragOptions); + /** + * Fix path name by removing double slash at the beginning, if any + */ + fixPath: function(fileName) { + if (fileName.substr(0, 2) == '//') { + return fileName.substr(1); } - }); - - $fileList.find('tr[data-type="dir"] td.filename').each(function(i,e) { - if ($(e).parent().data('permissions') & OC.PERMISSION_CREATE) { - $(e).droppable(folderDropOptions); + return fileName; + }, + + /** + * Checks whether the given file name is valid. + * @param name file name to check + * @return true if the file name is valid. + * Throws a string exception with an error message if + * the file name is not valid + */ + isFileNameValid: function (name) { + var trimmedName = name.trim(); + if (trimmedName === '.' || trimmedName === '..') + { + throw t('files', '"{name}" is an invalid file name.', {name: name}); + } else if (trimmedName.length === 0) { + throw t('files', 'File name cannot be empty.'); + } + // check for invalid characters + var invalidCharacters = + ['\\', '/', '<', '>', ':', '"', '|', '?', '*', '\n']; + for (var i = 0; i < invalidCharacters.length; i++) { + if (trimmedName.indexOf(invalidCharacters[i]) !== -1) { + throw t('files', "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed."); + } + } + return true; + }, + displayStorageWarnings: function() { + if (!OC.Notification.isHidden()) { + return; } - }); - }, - - /** - * Returns the download URL of the given file(s) - * @param filename string or array of file names to download - * @param dir optional directory in which the file name is, defaults to the current directory - */ - getDownloadUrl: function(filename, dir) { - if ($.isArray(filename)) { - filename = JSON.stringify(filename); - } - var params = { - dir: dir || FileList.getCurrentDirectory(), - files: filename - }; - return this.getAjaxUrl('download', params); - }, - /** - * Returns the ajax URL for a given action - * @param action action string - * @param params optional params map - */ - getAjaxUrl: function(action, params) { - var q = ''; - if (params) { - q = '?' + OC.buildQueryString(params); - } - return OC.filePath('files', 'ajax', action + '.php') + q; - } -}; -$(document).ready(function() { - // FIXME: workaround for trashbin app - if (window.trashBinApp) { - return; - } - Files.displayEncryptionWarning(); - Files.bindKeyboardShortcuts(document, jQuery); + var usedSpacePercent = $('#usedSpacePercent').val(); + if (usedSpacePercent > 98) { + OC.Notification.show(t('files', 'Your storage is full, files can not be updated or synced anymore!')); + return; + } + if (usedSpacePercent > 90) { + OC.Notification.show(t('files', 'Your storage is almost full ({usedSpacePercent}%)', + {usedSpacePercent: usedSpacePercent})); + } + }, - Files.setupDragAndDrop(); + displayEncryptionWarning: function() { - $('#file_action_panel').attr('activeAction', false); + if (!OC.Notification.isHidden()) { + return; + } - // Triggers invisible file input - $('#upload a').on('click', function() { - $(this).parent().children('#file_upload_start').trigger('click'); - return false; - }); + var encryptedFiles = $('#encryptedFiles').val(); + var initStatus = $('#encryptionInitStatus').val(); + if (initStatus === '0') { // enc not initialized, but should be + OC.Notification.show(t('files', 'Encryption App is enabled but your keys are not initialized, please log-out and log-in again')); + return; + } + if (initStatus === '1') { // encryption tried to init but failed + OC.Notification.show(t('files', 'Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files.')); + return; + } + if (encryptedFiles === '1') { + OC.Notification.show(t('files', 'Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files.')); + return; + } + }, + + /** + * Returns the download URL of the given file(s) + * @param filename string or array of file names to download + * @param dir optional directory in which the file name is, defaults to the current directory + */ + getDownloadUrl: function(filename, dir) { + if ($.isArray(filename)) { + filename = JSON.stringify(filename); + } + var params = { + dir: dir, + files: filename + }; + return this.getAjaxUrl('download', params); + }, + + /** + * Returns the ajax URL for a given action + * @param action action string + * @param params optional params map + */ + getAjaxUrl: function(action, params) { + var q = ''; + if (params) { + q = '?' + OC.buildQueryString(params); + } + return OC.filePath('files', 'ajax', action + '.php') + q; + }, + + getMimeIcon: function(mime, ready) { + if (Files.getMimeIcon.cache[mime]) { + ready(Files.getMimeIcon.cache[mime]); + } else { + $.get( OC.filePath('files','ajax','mimeicon.php'), {mime: mime}, function(path) { + if(OC.Util.hasSVGSupport()){ + path = path.substr(0, path.length-4) + '.svg'; + } + Files.getMimeIcon.cache[mime]=path; + ready(Files.getMimeIcon.cache[mime]); + }); + } + }, + + /** + * Generates a preview URL based on the URL space. + * @param urlSpec map with {x: width, y: height, file: file path} + * @return preview URL + * @deprecated used OCA.Files.FileList.generatePreviewUrl instead + */ + generatePreviewUrl: function(urlSpec) { + console.warn('DEPRECATED: please use generatePreviewUrl() from an OCA.Files.FileList instance'); + return OCA.Files.App.fileList.generatePreviewUrl(urlSpec); + }, + + /** + * Lazy load preview + * @deprecated used OCA.Files.FileList.lazyLoadPreview instead + */ + lazyLoadPreview : function(path, mime, ready, width, height, etag) { + console.warn('DEPRECATED: please use lazyLoadPreview() from an OCA.Files.FileList instance'); + return OCA.Files.App.fileList.lazyLoadPreview({ + path: path, + mime: mime, + callback: ready, + width: width, + height: height, + etag: etag + }); + }, + + /** + * Initialize the files view + */ + initialize: function() { + Files.getMimeIcon.cache = {}; + Files.displayEncryptionWarning(); + Files.bindKeyboardShortcuts(document, $); + + // TODO: move file list related code (upload) to OCA.Files.FileList + $('#file_action_panel').attr('activeAction', false); + + // Triggers invisible file input + $('#upload a').on('click', function() { + $(this).parent().children('#file_upload_start').trigger('click'); + return false; + }); - // Trigger cancelling of file upload - $('#uploadprogresswrapper .stop').on('click', function() { - OC.Upload.cancelUploads(); - FileList.updateSelectionSummary(); - }); + // Trigger cancelling of file upload + $('#uploadprogresswrapper .stop').on('click', function() { + OC.Upload.cancelUploads(); + }); - // Show trash bin - $('#trash').on('click', function() { - window.location=OC.filePath('files_trashbin', '', 'index.php'); - }); + // drag&drop support using jquery.fileupload + // TODO use OC.dialogs + $(document).bind('drop dragover', function (e) { + e.preventDefault(); // prevent browser from doing anything, if file isn't dropped in dropZone + }); + + //do a background scan if needed + scanFiles(); + + // display storage warnings + setTimeout(Files.displayStorageWarnings, 100); + OC.Notification.setDefault(Files.displayStorageWarnings); + + // only possible at the moment if user is logged in or the files app is loaded + if (OC.currentUser && OCA.Files.App) { + // start on load - we ask the server every 5 minutes + var updateStorageStatisticsInterval = 5*60*1000; + var updateStorageStatisticsIntervalId = setInterval(OCA.Files.App.fileList.updateStorageStatistics, updateStorageStatisticsInterval); + + // TODO: this should also stop when switching to another view + // Use jquery-visibility to de-/re-activate file stats sync + if ($.support.pageVisibility) { + $(document).on({ + 'show.visibility': function() { + if (!updateStorageStatisticsIntervalId) { + updateStorageStatisticsIntervalId = setInterval(OCA.Files.App.fileList.updateStorageStatistics, updateStorageStatisticsInterval); + } + }, + 'hide.visibility': function() { + clearInterval(updateStorageStatisticsIntervalId); + updateStorageStatisticsIntervalId = 0; + } + }); + } + } - // drag&drop support using jquery.fileupload - // TODO use OC.dialogs - $(document).bind('drop dragover', function (e) { - e.preventDefault(); // prevent browser from doing anything, if file isn't dropped in dropZone - }); - - //do a background scan if needed - scanFiles(); - - // display storage warnings - setTimeout(Files.displayStorageWarnings, 100); - OC.Notification.setDefault(Files.displayStorageWarnings); - - // only possible at the moment if user is logged in - if (OC.currentUser) { - // start on load - we ask the server every 5 minutes - var updateStorageStatisticsInterval = 5*60*1000; - var updateStorageStatisticsIntervalId = setInterval(Files.updateStorageStatistics, updateStorageStatisticsInterval); - - // Use jquery-visibility to de-/re-activate file stats sync - if ($.support.pageVisibility) { - $(document).on({ - 'show.visibility': function() { - if (!updateStorageStatisticsIntervalId) { - updateStorageStatisticsIntervalId = setInterval(Files.updateStorageStatistics, updateStorageStatisticsInterval); - } - }, - 'hide.visibility': function() { - clearInterval(updateStorageStatisticsIntervalId); - updateStorageStatisticsIntervalId = 0; + $('#app-settings-header').on('click', function() { + var $settings = $('#app-settings'); + $settings.toggleClass('opened'); + if ($settings.hasClass('opened')) { + $settings.find('input').focus(); } }); + + //scroll to and highlight preselected file + /* + if (getURLParameter('scrollto')) { + FileList.scrollTo(getURLParameter('scrollto')); + } + */ } } - //scroll to and highlight preselected file - if (getURLParameter('scrollto')) { - FileList.scrollTo(getURLParameter('scrollto')); - } -}); + Files._updateStorageStatisticsDebounced = _.debounce(Files._updateStorageStatistics, 250); + OCA.Files.Files = Files; +})(); function scanFiles(force, dir, users) { if (!OC.currentUser) { @@ -292,7 +331,9 @@ function scanFiles(force, dir, users) { scannerEventSource.listen('done',function(count) { scanFiles.scanning=false; console.log('done after ' + count + ' files'); - Files.updateStorageStatistics(); + if (OCA.Files.App) { + OCA.Files.App.fileList.updateStorageStatistics(true); + } }); scannerEventSource.listen('user',function(user) { console.log('scanning files for ' + user); @@ -303,6 +344,7 @@ scanFiles.scanning=false; // TODO: move to FileList var createDragShadow = function(event) { //select dragged file + var FileList = OCA.Files.App.fileList; var isDragSelected = $(event.target).parents('tr').find('td input:first').prop('checked'); if (!isDragSelected) { //select dragged file @@ -311,7 +353,7 @@ var createDragShadow = function(event) { // do not show drag shadow for too many files var selectedFiles = _.first(FileList.getSelectedFiles(), FileList.pageSize); - selectedFiles.sort(FileList._fileInfoCompare); + selectedFiles = _.sortBy(selectedFiles, FileList._fileInfoCompare); if (!isDragSelected && selectedFiles.length === 1) { //revert the selection @@ -323,7 +365,7 @@ var createDragShadow = function(event) { var tbody = $(''); dragshadow.append(tbody); - var dir=$('#dir').val(); + var dir = FileList.getCurrentDirectory(); $(selectedFiles).each(function(i,elem) { var newtr = $('') @@ -336,8 +378,8 @@ var createDragShadow = function(event) { if (elem.type === 'dir') { newtr.find('td.filename').attr('style','background-image:url('+OC.imagePath('core', 'filetypes/folder.png')+')'); } else { - var path = getPathForPreview(elem.name); - Files.lazyLoadPreview(path, elem.mime, function(previewpath) { + var path = dir + '/' + elem.name; + OCA.Files.App.files.lazyLoadPreview(path, elem.mime, function(previewpath) { newtr.find('td.filename').attr('style','background-image:url('+previewpath+')'); }, null, null, elem.etag); } @@ -350,9 +392,14 @@ var createDragShadow = function(event) { //start&stop handlers needs some cleaning up // TODO: move to FileList class var dragOptions={ - revert: 'invalid', revertDuration: 300, - opacity: 0.7, zIndex: 100, appendTo: 'body', cursorAt: { left: 24, top: 18 }, - helper: createDragShadow, cursor: 'move', + revert: 'invalid', + revertDuration: 300, + opacity: 0.7, + zIndex: 100, + appendTo: 'body', + cursorAt: { left: 24, top: 18 }, + helper: createDragShadow, + cursor: 'move', start: function(event, ui){ var $selectedFiles = $('td.filename input:checkbox:checked'); if($selectedFiles.length > 1){ @@ -383,6 +430,7 @@ var folderDropOptions = { hoverClass: "canDrop", drop: function( event, ui ) { // don't allow moving a file into a selected folder + var FileList = OCA.Files.App.fileList; if ($(event.target).parents('tr').find('td input:first').prop('checked') === true) { return false; } @@ -400,115 +448,11 @@ var folderDropOptions = { tolerance: 'pointer' }; -Files.getMimeIcon = function(mime, ready) { - if (Files.getMimeIcon.cache[mime]) { - ready(Files.getMimeIcon.cache[mime]); - } else { - $.get( OC.filePath('files','ajax','mimeicon.php'), {mime: mime}, function(path) { - if(OC.Util.hasSVGSupport()){ - path = path.substr(0, path.length-4) + '.svg'; - } - Files.getMimeIcon.cache[mime]=path; - ready(Files.getMimeIcon.cache[mime]); - }); - } -} -Files.getMimeIcon.cache={}; - -function getPathForPreview(name) { - var path = $('#dir').val() + '/' + name; - return path; -} - -/** - * Generates a preview URL based on the URL space. - * @param urlSpec map with {x: width, y: height, file: file path} - * @return preview URL - */ -Files.generatePreviewUrl = function(urlSpec) { - urlSpec = urlSpec || {}; - if (!urlSpec.x) { - urlSpec.x = $('#filestable').data('preview-x'); - } - if (!urlSpec.y) { - urlSpec.y = $('#filestable').data('preview-y'); - } - urlSpec.y *= window.devicePixelRatio; - urlSpec.x *= window.devicePixelRatio; - urlSpec.forceIcon = 0; - return OC.generateUrl('/core/preview.png?') + $.param(urlSpec); -}; - -Files.lazyLoadPreview = function(path, mime, ready, width, height, etag) { - // get mime icon url - Files.getMimeIcon(mime, function(iconURL) { - var previewURL, - urlSpec = {}; - ready(iconURL); // set mimeicon URL - - urlSpec.file = Files.fixPath(path); - - if (etag){ - // use etag as cache buster - urlSpec.c = etag; - } - else { - console.warn('Files.lazyLoadPreview(): missing etag argument'); - } - - previewURL = Files.generatePreviewUrl(urlSpec); - previewURL = previewURL.replace('(', '%28'); - previewURL = previewURL.replace(')', '%29'); - - // preload image to prevent delay - // this will make the browser cache the image - var img = new Image(); - img.onload = function(){ - // if loading the preview image failed (no preview for the mimetype) then img.width will < 5 - if (img.width > 5) { - ready(previewURL); - } - }; - img.src = previewURL; - }); -}; - -function getUniqueName(name) { - if (FileList.findFileEl(name).exists()) { - var numMatch; - var parts=name.split('.'); - var extension = ""; - if (parts.length > 1) { - extension=parts.pop(); - } - var base=parts.join('.'); - numMatch=base.match(/\((\d+)\)/); - var num=2; - if (numMatch && numMatch.length>0) { - num=parseInt(numMatch[numMatch.length-1])+1; - base=base.split('('); - base.pop(); - base=$.trim(base.join('(')); - } - name=base+' ('+num+')'; - if (extension) { - name = name+'.'+extension; - } - return getUniqueName(name); - } - return name; -} - -function checkTrashStatus() { - $.post(OC.filePath('files_trashbin', 'ajax', 'isEmpty.php'), function(result) { - if (result.data.isEmpty === false) { - $("input[type=button][id=trash]").removeAttr("disabled"); - } - }); -} - // override core's fileDownloadPath (legacy) function fileDownloadPath(dir, file) { - return Files.getDownloadUrl(file, dir); + return OCA.Files.Files.getDownloadUrl(file, dir); } +// for backward compatibility +window.Files = OCA.Files.Files; + diff --git a/apps/files/js/filesummary.js b/apps/files/js/filesummary.js index b5130247cc99911f068fe1a952b7f72fd738b29a..104dabf1b04ec5e533ee08b30e8a7884a54f8387 100644 --- a/apps/files/js/filesummary.js +++ b/apps/files/js/filesummary.js @@ -190,6 +190,6 @@ this.$el.append($summary); } }; - window.FileSummary = FileSummary; + OCA.Files.FileSummary = FileSummary; })(); diff --git a/apps/files/js/keyboardshortcuts.js b/apps/files/js/keyboardshortcuts.js index 9d6c3ae8c3308ddeeb7774ca000aaf95f8886ef3..b2f2cd0e5828ad9b6ea861c0ebd6eaf7d317eaf2 100644 --- a/apps/files/js/keyboardshortcuts.js +++ b/apps/files/js/keyboardshortcuts.js @@ -12,7 +12,6 @@ * enter: open file/folder * delete/backspace: delete file/folder *****************************/ -var Files = Files || {}; (function(Files) { var keys = []; var keyCodes = { @@ -167,4 +166,4 @@ var Files = Files || {}; removeA(keys, event.keyCode); }); }; -})(Files); +})((OCA.Files && OCA.Files.Files) || {}); diff --git a/apps/files/js/navigation.js b/apps/files/js/navigation.js new file mode 100644 index 0000000000000000000000000000000000000000..c58a284e83fe01eb36ff1fcea06427e6788df1e5 --- /dev/null +++ b/apps/files/js/navigation.js @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2014 + * + * @author Vincent Petry + * @copyright 2014 Vincent Petry + * + * This file is licensed under the Affero General Public License version 3 + * or later. + * + * See the COPYING-README file. + * + */ + +(function() { + + var Navigation = function($el) { + this.initialize($el); + }; + + Navigation.prototype = { + + /** + * Currently selected item in the list + */ + _activeItem: null, + + /** + * Currently selected container + */ + $currentContent: null, + + /** + * Initializes the navigation from the given container + * @param $el element containing the navigation + */ + initialize: function($el) { + this.$el = $el; + this._activeItem = null; + this.$currentContent = null; + this._setupEvents(); + }, + + /** + * Setup UI events + */ + _setupEvents: function() { + this.$el.on('click', 'li a', _.bind(this._onClickItem, this)); + }, + + /** + * Returns the container of the currently active app. + * + * @return app container + */ + getActiveContainer: function() { + return this.$currentContent; + }, + + /** + * Returns the currently active item + * + * @return item ID + */ + getActiveItem: function() { + return this._activeItem; + }, + + /** + * Switch the currently selected item, mark it as selected and + * make the content container visible, if any. + * + * @param string itemId id of the navigation item to select + * @param array options "silent" to not trigger event + */ + setActiveItem: function(itemId, options) { + var oldItemId = this._activeItem; + if (itemId === this._activeItem) { + if (!options || !options.silent) { + this.$el.trigger( + new $.Event('itemChanged', {itemId: itemId, previousItemId: oldItemId}) + ); + } + return; + } + this.$el.find('li').removeClass('selected'); + if (this.$currentContent) { + this.$currentContent.addClass('hidden'); + this.$currentContent.trigger(jQuery.Event('hide')); + } + this._activeItem = itemId; + this.$el.find('li[data-id=' + itemId + ']').addClass('selected'); + this.$currentContent = $('#app-content-' + itemId); + this.$currentContent.removeClass('hidden'); + if (!options || !options.silent) { + this.$currentContent.trigger(jQuery.Event('show')); + this.$el.trigger( + new $.Event('itemChanged', {itemId: itemId, previousItemId: oldItemId}) + ); + } + }, + + /** + * Returns whether a given item exists + */ + itemExists: function(itemId) { + return this.$el.find('li[data-id=' + itemId + ']').length; + }, + + /** + * Event handler for when clicking on an item. + */ + _onClickItem: function(ev) { + var $target = $(ev.target); + var itemId = $target.closest('li').attr('data-id'); + this.setActiveItem(itemId); + return false; + } + }; + + OCA.Files.Navigation = Navigation; + +})(); diff --git a/apps/files/l10n/ar.php b/apps/files/l10n/ar.php index 6779141c5eece747e39125b5bf96c651d057d87b..ea715c38882ad1c2c6ab0411e8c7625a158a828d 100644 --- a/apps/files/l10n/ar.php +++ b/apps/files/l10n/ar.php @@ -52,12 +52,13 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 = غير محدود", "Maximum input size for ZIP files" => "الحد الأقصى المسموح به لملفات ZIP", "Save" => "حفظ", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "استخدم هذا العنوان لـ الدخول الى ملفاتك عن طريق WebDAV", "New" => "جديد", "Text file" => "ملف", "New folder" => "مجلد جديد", "Folder" => "مجلد", "From link" => "من رابط", -"Deleted files" => "حذف الملفات", "Cancel upload" => "إلغاء رفع الملفات", "Nothing in here. Upload something!" => "لا يوجد شيء هنا. إرفع بعض الملفات!", "Download" => "تحميل", diff --git a/apps/files/l10n/ast.php b/apps/files/l10n/ast.php index a2568ae7631ebef0ba5771b51b749fe025431ad4..b0ba541778dfed0c6009d976db8e0ff8f038f82f 100644 --- a/apps/files/l10n/ast.php +++ b/apps/files/l10n/ast.php @@ -1,29 +1,67 @@ "Nun pudo movese %s - Yá existe un ficheru con esi nome.", +"Could not move %s" => "Nun pudo movese %s", "File name cannot be empty." => "El nome de ficheru nun pue quedar baleru.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nome inválidu, los caráuteres \"\\\", \"/\", \"<\", \">\", \":\", \"\", \"|\" \"?\" y \"*\" nun tán permitíos.", +"Unable to set upload directory." => "Nun se puede afitar la carpeta de xubida.", +"Invalid Token" => "Token inválidu", "No file was uploaded. Unknown error" => "Nun se xubió dengún ficheru. Fallu desconocíu", "There is no error, the file uploaded with success" => "Nun hai dengún fallu, el ficheru xubióse ensin problemes", +"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "El ficheru xubíu perpasa la direutiva \"upload_max_filesize\" del ficheru php.ini", "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "El ficheru xubíu perpasa la direutiva \"MAX_FILE_SIZE\" especificada nel formulariu HTML", "The uploaded file was only partially uploaded" => "El ficheru xubióse de mou parcial", "No file was uploaded" => "Nun se xubió dengún ficheru", "Missing a temporary folder" => "Falta una carpeta temporal", "Failed to write to disk" => "Fallu al escribir al discu", "Not enough storage available" => "Nun hai abondu espaciu disponible", +"Upload failed. Could not find uploaded file" => "Xubida fallía. Nun se pudo atopar el ficheru xubíu.", +"Upload failed. Could not get file info." => "Falló la xubida. Nun se pudo obtener la información del ficheru.", +"Invalid directory." => "Carpeta non válida.", "Files" => "Ficheros", +"Unable to upload {filename} as it is a directory or has 0 bytes" => "Nun se pudo xubir {filename}, paez que ye un directoriu o tien 0 bytes", +"Upload cancelled." => "Xubida encaboxada.", +"Could not get result from server." => "Nun se pudo obtener el resultáu del servidor.", +"File upload is in progress. Leaving the page now will cancel the upload." => "La xubida del ficheru ta en progresu. Si dexes esta páxina encaboxarase la xubida.", +"{new_name} already exists" => "{new_name} yá existe", "Share" => "Compartir", +"Delete permanently" => "Desaniciar dafechu", "Rename" => "Renomar", +"Your download is being prepared. This might take some time if the files are big." => "Ta preparándose la descarga. Esto podría llevar dalgún tiempu si los ficheros son grandes.", +"Error moving file" => "Fallu moviendo'l ficheru", "Error" => "Fallu", "Name" => "Nome", "Size" => "Tamañu", +"Modified" => "Modificáu", "_%n folder_::_%n folders_" => array("",""), "_%n file_::_%n files_" => array("",""), "_Uploading %n file_::_Uploading %n files_" => array("",""), +"Your storage is full, files can not be updated or synced anymore!" => "L'almacenamientu ta completu, ¡yá nun se pueden anovar o sincronizar ficheros!", +"Your storage is almost full ({usedSpacePercent}%)" => "L'almacenamientu ta casi completu ({usedSpacePercent}%)", +"Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Deshabilitose'l cifráu pero los tos ficheros tovía tan cifraos. Por favor, vete a los axustes personales pa descrifrar los tos ficheros.", +"%s could not be renamed" => "Nun se puede renomar %s ", +"File handling" => "Alministración de ficheros", +"Maximum upload size" => "Tamañu máximu de xubida", +"max. possible: " => "máx. posible:", +"Needed for multi-file and folder downloads." => "Ye necesariu pa descargues multificheru y de carpetes", +"Enable ZIP-download" => "Activar descarga ZIP", +"0 is unlimited" => "0 ye illimitao", +"Maximum input size for ZIP files" => "Tamañu máximu d'entrada pa ficheros ZIP", "Save" => "Guardar", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Usa esta direición pa acceder a los ficheros a traviés de WebDAV", +"New" => "Nuevu", +"Text file" => "Ficheru de testu", "New folder" => "Nueva carpeta", "Folder" => "Carpeta", +"From link" => "Dende enllaz", "Cancel upload" => "Encaboxar xuba", +"Nothing in here. Upload something!" => "Nun hai nada equí. ¡Xubi daqué!", "Download" => "Descargar", -"Delete" => "Desaniciar" +"Delete" => "Desaniciar", +"Upload too large" => "La xubida ye demasiao grande", +"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Los ficheros que tas intentando xubir perpasen el tamañu máximu pa les xubíes de ficheros nesti servidor.", +"Files are being scanned, please wait." => "Tan escaniándose los ficheros, espera por favor.", +"Current scanning" => "Escanéu actual" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files/l10n/bg_BG.php b/apps/files/l10n/bg_BG.php index f9ef3750b5ce8c46b75aec0ce6250fc4bbd9720f..7b5bac636d793089cf2f4586d39cb5d7deaa2e37 100644 --- a/apps/files/l10n/bg_BG.php +++ b/apps/files/l10n/bg_BG.php @@ -23,6 +23,7 @@ $TRANSLATIONS = array( "Maximum upload size" => "Максимален размер за качване", "0 is unlimited" => "Ползвайте 0 за без ограничения", "Save" => "Запис", +"WebDAV" => "WebDAV", "New" => "Ново", "Text file" => "Текстов файл", "New folder" => "Нова папка", diff --git a/apps/files/l10n/bn_BD.php b/apps/files/l10n/bn_BD.php index b96d2515f1c7439186420e872a57179915ab2efb..dd639b4955c294891314bbcc763e3ff7e2bd95d6 100644 --- a/apps/files/l10n/bn_BD.php +++ b/apps/files/l10n/bn_BD.php @@ -35,6 +35,7 @@ $TRANSLATIONS = array( "0 is unlimited" => "০ এর অর্থ অসীম", "Maximum input size for ZIP files" => "ZIP ফাইলের ইনপুটের সর্বোচ্চ আকার", "Save" => "সংরক্ষণ", +"WebDAV" => "WebDAV", "New" => "নতুন", "Text file" => "টেক্সট ফাইল", "Folder" => "ফোল্ডার", diff --git a/apps/files/l10n/ca.php b/apps/files/l10n/ca.php index 6226168175a895e491ca1b8700eff75430d0537c..240e61bfd961d52b2588c9c92c15d81dca739dae 100644 --- a/apps/files/l10n/ca.php +++ b/apps/files/l10n/ca.php @@ -44,6 +44,7 @@ $TRANSLATIONS = array( "Rename" => "Reanomena", "Your download is being prepared. This might take some time if the files are big." => "S'està preparant la baixada. Pot trigar una estona si els fitxers són grans.", "Pending" => "Pendent", +"Error moving file." => "Error en moure el fitxer.", "Error moving file" => "Error en moure el fitxer", "Error" => "Error", "Could not rename file" => "No es pot canviar el nom de fitxer", @@ -70,13 +71,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 és sense límit", "Maximum input size for ZIP files" => "Mida màxima d'entrada per fitxers ZIP", "Save" => "Desa", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Useu aquesta adreça per accedir als fitxers via WebDAV", "New" => "Nou", "New text file" => "Nou fitxer de text", "Text file" => "Fitxer de text", "New folder" => "Carpeta nova", "Folder" => "Carpeta", "From link" => "Des d'enllaç", -"Deleted files" => "Fitxers esborrats", "Cancel upload" => "Cancel·la la pujada", "You don’t have permission to upload or create files here" => "No teniu permisos per a pujar o crear els fitxers aquí", "Nothing in here. Upload something!" => "Res per aquí. Pugeu alguna cosa!", diff --git a/apps/files/l10n/cs_CZ.php b/apps/files/l10n/cs_CZ.php index 8fa0bb21370d0e6b81d4a620ce61840014d6ee63..1af95dc7fed4e1c595b23e42762df910ec2f3cfd 100644 --- a/apps/files/l10n/cs_CZ.php +++ b/apps/files/l10n/cs_CZ.php @@ -72,13 +72,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 znamená bez omezení", "Maximum input size for ZIP files" => "Maximální velikost vstupu pro ZIP soubory", "Save" => "Uložit", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Použijte tuto adresu pro přístup k vašim souborům přes WebDAV", "New" => "Nový", "New text file" => "Nový textový soubor", "Text file" => "Textový soubor", "New folder" => "Nová složka", "Folder" => "Složka", "From link" => "Z odkazu", -"Deleted files" => "Odstraněné soubory", "Cancel upload" => "Zrušit odesílání", "You don’t have permission to upload or create files here" => "Nemáte oprávnění zde nahrávat či vytvářet soubory", "Nothing in here. Upload something!" => "Žádný obsah. Nahrajte něco.", diff --git a/apps/files/l10n/cy_GB.php b/apps/files/l10n/cy_GB.php index 6ed94e5c77c79dad87a5d83b87229e0b27bf52ab..6b4796c3e9a30e334fe9a6670fd0e84a8ebdfdfc 100644 --- a/apps/files/l10n/cy_GB.php +++ b/apps/files/l10n/cy_GB.php @@ -44,7 +44,6 @@ $TRANSLATIONS = array( "Text file" => "Ffeil destun", "Folder" => "Plygell", "From link" => "Dolen o", -"Deleted files" => "Ffeiliau ddilewyd", "Cancel upload" => "Diddymu llwytho i fyny", "Nothing in here. Upload something!" => "Does dim byd fan hyn. Llwythwch rhywbeth i fyny!", "Download" => "Llwytho i lawr", diff --git a/apps/files/l10n/da.php b/apps/files/l10n/da.php index 076fa46b4c38f6f13638f37d9d9b5fc0585781e2..1f73fb89f4101bc6a219eefc09e00464ac9b69aa 100644 --- a/apps/files/l10n/da.php +++ b/apps/files/l10n/da.php @@ -72,13 +72,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 er ubegrænset", "Maximum input size for ZIP files" => "Maksimal størrelse på ZIP filer", "Save" => "Gem", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Brug denne adresse for at tilgå dine filer via WebDAV", "New" => "Ny", "New text file" => "Ny tekstfil", "Text file" => "Tekstfil", "New folder" => "Ny Mappe", "Folder" => "Mappe", "From link" => "Fra link", -"Deleted files" => "Slettede filer", "Cancel upload" => "Fortryd upload", "You don’t have permission to upload or create files here" => "Du har ikke tilladelse til at uploade eller oprette filer her", "Nothing in here. Upload something!" => "Her er tomt. Upload noget!", diff --git a/apps/files/l10n/de.php b/apps/files/l10n/de.php index 8ad0f8909f194e2c84b1edb1f62fd0aec7fa9690..a1472b6e09bda67e67110299c1787b259d2e9a08 100644 --- a/apps/files/l10n/de.php +++ b/apps/files/l10n/de.php @@ -28,6 +28,7 @@ $TRANSLATIONS = array( "Upload failed. Could not get file info." => "Hochladen fehlgeschlagen. Dateiinformationen konnten nicht abgerufen werden.", "Invalid directory." => "Ungültiges Verzeichnis.", "Files" => "Dateien", +"All files" => "Alle Dateien", "Unable to upload {filename} as it is a directory or has 0 bytes" => "Die Datei {filename} kann nicht hochgeladen werden, da sie entweder ein Verzeichnis oder 0 Bytes groß ist", "Total file size {size1} exceeds upload limit {size2}" => "Die Gesamt-Größe {size1} überschreitet die Upload-Begrenzung {size2}", "Not enough free space, you are uploading {size1} but only {size2} is left" => "Nicht genügend freier Speicherplatz, du möchtest {size1} hochladen, es sind jedoch nur noch {size2} verfügbar.", @@ -72,13 +73,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 bedeutet unbegrenzt", "Maximum input size for ZIP files" => "Maximale Größe für ZIP-Dateien", "Save" => "Speichern", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Verwenden Sie diese Adresse, um via WebDAV auf Ihre Dateien zuzugreifen", "New" => "Neu", "New text file" => "Neue Textdatei", "Text file" => "Textdatei", "New folder" => "Neuer Ordner", "Folder" => "Ordner", "From link" => "Von einem Link", -"Deleted files" => "Gelöschte Dateien", "Cancel upload" => "Upload abbrechen", "You don’t have permission to upload or create files here" => "Du besitzt hier keine Berechtigung, um Dateien hochzuladen oder zu erstellen", "Nothing in here. Upload something!" => "Alles leer. Lade etwas hoch!", diff --git a/apps/files/l10n/de_CH.php b/apps/files/l10n/de_CH.php index 625b9387b0ab630144cf74ed14dcebb2763ac5a5..fc80bfdc7d11615d8852c997741e7eeb36cdccb3 100644 --- a/apps/files/l10n/de_CH.php +++ b/apps/files/l10n/de_CH.php @@ -44,12 +44,12 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 bedeutet unbegrenzt", "Maximum input size for ZIP files" => "Maximale Grösse für ZIP-Dateien", "Save" => "Speichern", +"WebDAV" => "WebDAV", "New" => "Neu", "Text file" => "Textdatei", "New folder" => "Neues Verzeichnis", "Folder" => "Ordner", "From link" => "Von einem Link", -"Deleted files" => "Gelöschte Dateien", "Cancel upload" => "Upload abbrechen", "Nothing in here. Upload something!" => "Alles leer. Laden Sie etwas hoch!", "Download" => "Herunterladen", diff --git a/apps/files/l10n/de_DE.php b/apps/files/l10n/de_DE.php index 9a834f1cc31733d5c4a3014a5a060a0678142ea8..d94361a676d9c3087a5e131c18db52a18ddbdc05 100644 --- a/apps/files/l10n/de_DE.php +++ b/apps/files/l10n/de_DE.php @@ -28,6 +28,7 @@ $TRANSLATIONS = array( "Upload failed. Could not get file info." => "Hochladen fehlgeschlagen. Die Dateiinformationen konnten nicht abgerufen werden.", "Invalid directory." => "Ungültiges Verzeichnis.", "Files" => "Dateien", +"All files" => "Alle Dateien", "Unable to upload {filename} as it is a directory or has 0 bytes" => "Die Datei {filename} kann nicht hochgeladen werden, da sie entweder ein Verzeichnis oder 0 Bytes groß ist", "Total file size {size1} exceeds upload limit {size2}" => "Die Gesamt-Größe {size1} überschreitet die Upload-Begrenzung {size2}", "Not enough free space, you are uploading {size1} but only {size2} is left" => "Nicht genügend freier Speicherplatz, Sie möchten {size1} hochladen, es sind jedoch nur noch {size2} verfügbar.", @@ -72,13 +73,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 bedeutet unbegrenzt", "Maximum input size for ZIP files" => "Maximale Größe für ZIP-Dateien", "Save" => "Speichern", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Verwenden Sie diese Adresse, um via WebDAV auf Ihre Dateien zuzugreifen", "New" => "Neu", "New text file" => "Neue Textdatei", "Text file" => "Textdatei", "New folder" => "Neuer Ordner", "Folder" => "Ordner", "From link" => "Von einem Link", -"Deleted files" => "Gelöschte Dateien", "Cancel upload" => "Upload abbrechen", "You don’t have permission to upload or create files here" => "Sie besitzen hier keine Berechtigung Dateien hochzuladen oder zu erstellen", "Nothing in here. Upload something!" => "Alles leer. Laden Sie etwas hoch!", diff --git a/apps/files/l10n/el.php b/apps/files/l10n/el.php index 5ba92033d13360b780be3d1f0cac1d11e43f47be..892926368100a9920010f3c3d397df24250d3271 100644 --- a/apps/files/l10n/el.php +++ b/apps/files/l10n/el.php @@ -44,6 +44,7 @@ $TRANSLATIONS = array( "Rename" => "Μετονομασία", "Your download is being prepared. This might take some time if the files are big." => "Η λήψη προετοιμάζεται. Αυτό μπορεί να πάρει ώρα εάν τα αρχεία έχουν μεγάλο μέγεθος.", "Pending" => "Εκκρεμεί", +"Error moving file." => "Σφάλμα κατά τη μετακίνηση του αρχείου.", "Error moving file" => "Σφάλμα κατά τη μετακίνηση του αρχείου", "Error" => "Σφάλμα", "Could not rename file" => "Αδυναμία μετονομασίας αρχείου", @@ -71,13 +72,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 για απεριόριστο", "Maximum input size for ZIP files" => "Μέγιστο μέγεθος για αρχεία ZIP", "Save" => "Αποθήκευση", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Χρησιμοποιήστε αυτήν την διεύθυνση για να αποκτήσετε πρόσβαση στα αρχεία σας μέσω WebDAV", "New" => "Νέο", "New text file" => "Νέο αρχείο κειμένου", "Text file" => "Αρχείο κειμένου", "New folder" => "Νέος κατάλογος", "Folder" => "Φάκελος", "From link" => "Από σύνδεσμο", -"Deleted files" => "Διαγραμμένα αρχεία", "Cancel upload" => "Ακύρωση αποστολής", "You don’t have permission to upload or create files here" => "Δεν έχετε δικαιώματα φόρτωσης ή δημιουργίας αρχείων εδώ", "Nothing in here. Upload something!" => "Δεν υπάρχει τίποτα εδώ. Ανεβάστε κάτι!", diff --git a/apps/files/l10n/en_GB.php b/apps/files/l10n/en_GB.php index 5ebc141b80e74b175f4be917cbf0be3c8e3305dc..e64b7f4cc95e5016e2725f7ed6d5c67650f40b72 100644 --- a/apps/files/l10n/en_GB.php +++ b/apps/files/l10n/en_GB.php @@ -72,13 +72,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 is unlimited", "Maximum input size for ZIP files" => "Maximum input size for ZIP files", "Save" => "Save", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Use this address to access your Files via WebDAV", "New" => "New", "New text file" => "New text file", "Text file" => "Text file", "New folder" => "New folder", "Folder" => "Folder", "From link" => "From link", -"Deleted files" => "Deleted files", "Cancel upload" => "Cancel upload", "You don’t have permission to upload or create files here" => "You don’t have permission to upload or create files here", "Nothing in here. Upload something!" => "Nothing in here. Upload something!", diff --git a/apps/files/l10n/eo.php b/apps/files/l10n/eo.php index eebd94abc33263042a211434e3cdfde4f2a54bc0..9aaf72d98ad39bde2820458dcd4f5097979270ae 100644 --- a/apps/files/l10n/eo.php +++ b/apps/files/l10n/eo.php @@ -58,12 +58,12 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 signifas senlime", "Maximum input size for ZIP files" => "Maksimuma enirgrando por ZIP-dosieroj", "Save" => "Konservi", +"WebDAV" => "WebDAV", "New" => "Nova", "Text file" => "Tekstodosiero", "New folder" => "Nova dosierujo", "Folder" => "Dosierujo", "From link" => "El ligilo", -"Deleted files" => "Forigitaj dosieroj", "Cancel upload" => "Nuligi alŝuton", "You don’t have permission to upload or create files here" => "Vi ne havas permeson alŝuti aŭ krei dosierojn ĉi tie", "Nothing in here. Upload something!" => "Nenio estas ĉi tie. Alŝutu ion!", diff --git a/apps/files/l10n/es.php b/apps/files/l10n/es.php index ba115e6af7883183e91ce9957be1afd16d66b6bb..0a56a324a236c8834dba87910d84df0117878bba 100644 --- a/apps/files/l10n/es.php +++ b/apps/files/l10n/es.php @@ -28,6 +28,7 @@ $TRANSLATIONS = array( "Upload failed. Could not get file info." => "Actualización fallida. No se pudo obtener información del archivo.", "Invalid directory." => "Directorio inválido.", "Files" => "Archivos", +"All files" => "Todos los archivos", "Unable to upload {filename} as it is a directory or has 0 bytes" => "No ha sido posible subir {filename} porque es un directorio o tiene 0 bytes", "Total file size {size1} exceeds upload limit {size2}" => "El tamaño total del archivo {size1} excede el límite {size2}", "Not enough free space, you are uploading {size1} but only {size2} is left" => "No hay suficiente espacio libre. Quiere subir {size1} pero solo quedan {size2}", @@ -72,13 +73,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 significa ilimitado", "Maximum input size for ZIP files" => "Tamaño máximo para archivos ZIP de entrada", "Save" => "Guardar", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Use esta URL para acceder via WebDAV", "New" => "Nuevo", "New text file" => "Nuevo archivo de texto", "Text file" => "Archivo de texto", "New folder" => "Nueva carpeta", "Folder" => "Carpeta", "From link" => "Desde enlace", -"Deleted files" => "Archivos eliminados", "Cancel upload" => "Cancelar subida", "You don’t have permission to upload or create files here" => "No tienes permisos para subir o crear archivos aquí.", "Nothing in here. Upload something!" => "No hay nada aquí. ¡Suba algo!", diff --git a/apps/files/l10n/es_AR.php b/apps/files/l10n/es_AR.php index 7d1eb0fb4aaa0f7b20ed60e832804fcab626f54d..9edbe50206ecd7a476335ddc394785da06e750b7 100644 --- a/apps/files/l10n/es_AR.php +++ b/apps/files/l10n/es_AR.php @@ -65,13 +65,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 significa ilimitado", "Maximum input size for ZIP files" => "Tamaño máximo para archivos ZIP de entrada", "Save" => "Guardar", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Usar esta dirección para acceder a tus archivos vía WebDAV", "New" => "Nuevo", "New text file" => "Nuevo archivo de texto", "Text file" => "Archivo de texto", "New folder" => "Nueva Carpeta", "Folder" => "Carpeta", "From link" => "Desde enlace", -"Deleted files" => "Archivos borrados", "Cancel upload" => "Cancelar subida", "You don’t have permission to upload or create files here" => "No tienes permisos para subir o crear archivos aquí", "Nothing in here. Upload something!" => "No hay nada. ¡Subí contenido!", diff --git a/apps/files/l10n/es_BO.php b/apps/files/l10n/es_BO.php new file mode 100644 index 0000000000000000000000000000000000000000..0157af093e92200cc7790497227e92e62d80165f --- /dev/null +++ b/apps/files/l10n/es_BO.php @@ -0,0 +1,7 @@ + array("",""), +"_%n file_::_%n files_" => array("",""), +"_Uploading %n file_::_Uploading %n files_" => array("","") +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files/l10n/es_CO.php b/apps/files/l10n/es_CO.php new file mode 100644 index 0000000000000000000000000000000000000000..0157af093e92200cc7790497227e92e62d80165f --- /dev/null +++ b/apps/files/l10n/es_CO.php @@ -0,0 +1,7 @@ + array("",""), +"_%n file_::_%n files_" => array("",""), +"_Uploading %n file_::_Uploading %n files_" => array("","") +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files/l10n/es_EC.php b/apps/files/l10n/es_EC.php new file mode 100644 index 0000000000000000000000000000000000000000..0157af093e92200cc7790497227e92e62d80165f --- /dev/null +++ b/apps/files/l10n/es_EC.php @@ -0,0 +1,7 @@ + array("",""), +"_%n file_::_%n files_" => array("",""), +"_Uploading %n file_::_Uploading %n files_" => array("","") +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files/l10n/es_MX.php b/apps/files/l10n/es_MX.php index b6d06d941363d443f68d95ceb1577b74e5fcac01..5b88655631818cf3fb9c23e2dd49c42ca9b48d02 100644 --- a/apps/files/l10n/es_MX.php +++ b/apps/files/l10n/es_MX.php @@ -65,13 +65,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 significa ilimitado", "Maximum input size for ZIP files" => "Tamaño máximo para archivos ZIP de entrada", "Save" => "Guardar", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Utilice esta dirección para acceder a sus archivos vía WebDAV", "New" => "Nuevo", "New text file" => "Nuevo archivo de texto", "Text file" => "Archivo de texto", "New folder" => "Nueva carpeta", "Folder" => "Carpeta", "From link" => "Desde enlace", -"Deleted files" => "Archivos eliminados", "Cancel upload" => "Cancelar subida", "You don’t have permission to upload or create files here" => "No tienes permisos para subir o crear archivos aquí.", "Nothing in here. Upload something!" => "No hay nada aquí. ¡Suba algo!", diff --git a/apps/files/l10n/es_PE.php b/apps/files/l10n/es_PE.php new file mode 100644 index 0000000000000000000000000000000000000000..0157af093e92200cc7790497227e92e62d80165f --- /dev/null +++ b/apps/files/l10n/es_PE.php @@ -0,0 +1,7 @@ + array("",""), +"_%n file_::_%n files_" => array("",""), +"_Uploading %n file_::_Uploading %n files_" => array("","") +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files/l10n/es_UY.php b/apps/files/l10n/es_UY.php new file mode 100644 index 0000000000000000000000000000000000000000..0157af093e92200cc7790497227e92e62d80165f --- /dev/null +++ b/apps/files/l10n/es_UY.php @@ -0,0 +1,7 @@ + array("",""), +"_%n file_::_%n files_" => array("",""), +"_Uploading %n file_::_Uploading %n files_" => array("","") +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files/l10n/et_EE.php b/apps/files/l10n/et_EE.php index 4956e3fb45b72d440b74271ce243d72d3aa032ad..783152aa5812a46935b2f42e1057af8e96d2528b 100644 --- a/apps/files/l10n/et_EE.php +++ b/apps/files/l10n/et_EE.php @@ -71,13 +71,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 tähendab piiramatut", "Maximum input size for ZIP files" => "Maksimaalne ZIP-faili sisestatava faili suurus", "Save" => "Salvesta", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Kasuta seda aadressi oma failidele ligipääsuks WebDAV kaudu", "New" => "Uus", "New text file" => "Uus tekstifail", "Text file" => "Tekstifail", "New folder" => "Uus kaust", "Folder" => "Kaust", "From link" => "Allikast", -"Deleted files" => "Kustutatud failid", "Cancel upload" => "Tühista üleslaadimine", "You don’t have permission to upload or create files here" => "Sul puuduvad õigused siia failide üleslaadimiseks või tekitamiseks", "Nothing in here. Upload something!" => "Siin pole midagi. Lae midagi üles!", diff --git a/apps/files/l10n/eu.php b/apps/files/l10n/eu.php index 3ad25d2fe4e5982f75ed9f473be57cc096b1c49d..c3909ac5dac1769064b606745a3d2b504ec1a8d6 100644 --- a/apps/files/l10n/eu.php +++ b/apps/files/l10n/eu.php @@ -72,13 +72,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 mugarik gabe esan nahi du", "Maximum input size for ZIP files" => "ZIP fitxategien gehienezko tamaina", "Save" => "Gorde", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "helbidea erabili zure fitxategiak WebDAV bidez eskuratzeko", "New" => "Berria", "New text file" => "Testu fitxategi berria", "Text file" => "Testu fitxategia", "New folder" => "Karpeta berria", "Folder" => "Karpeta", "From link" => "Estekatik", -"Deleted files" => "Ezabatutako fitxategiak", "Cancel upload" => "Ezeztatu igoera", "You don’t have permission to upload or create files here" => "Ez duzu fitxategiak hona igotzeko edo hemen sortzeko baimenik", "Nothing in here. Upload something!" => "Ez dago ezer. Igo zerbait!", diff --git a/apps/files/l10n/fa.php b/apps/files/l10n/fa.php index ce4efe00e2ccb19900a8f8a31f6ace5c31f21b20..01f2905366b6566e241522e3c51a3ae5f3af6c26 100644 --- a/apps/files/l10n/fa.php +++ b/apps/files/l10n/fa.php @@ -43,12 +43,13 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 نامحدود است", "Maximum input size for ZIP files" => "حداکثرمقدار برای بار گزاری پرونده های فشرده", "Save" => "ذخیره", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "از این آدرس استفاده کنید تا بتوانید به فایل‌های خود توسط WebDAV دسترسی پیدا کنید", "New" => "جدید", "Text file" => "فایل متنی", "New folder" => "پوشه جدید", "Folder" => "پوشه", "From link" => "از پیوند", -"Deleted files" => "فایل های حذف شده", "Cancel upload" => "متوقف کردن بار گذاری", "Nothing in here. Upload something!" => "اینجا هیچ چیز نیست.", "Download" => "دانلود", diff --git a/apps/files/l10n/fi_FI.php b/apps/files/l10n/fi_FI.php index 2a5c02277f683fba20511db1c3af8f6dae213861..c25fe7e1e2e094065fd97215577cf7ccf38fec5b 100644 --- a/apps/files/l10n/fi_FI.php +++ b/apps/files/l10n/fi_FI.php @@ -27,6 +27,7 @@ $TRANSLATIONS = array( "Upload failed. Could not get file info." => "Lähetys epäonnistui. Lähettävää tiedostoa ei löydetty.", "Invalid directory." => "Virheellinen kansio.", "Files" => "Tiedostot", +"All files" => "Kaikki tiedostot", "Unable to upload {filename} as it is a directory or has 0 bytes" => "Kohdetta {filename} ei voi lähettää, koska se on joko kansio tai sen koko on 0 tavua", "Total file size {size1} exceeds upload limit {size2}" => "Yhteiskoko {size1} ylittää lähetysrajan {size2}", "Not enough free space, you are uploading {size1} but only {size2} is left" => "Ei riittävästi vapaata tilaa. Lähetyksesi koko on {size1}, mutta vain {size2} on jäljellä", @@ -71,13 +72,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 on rajoittamaton", "Maximum input size for ZIP files" => "ZIP-tiedostojen enimmäiskoko", "Save" => "Tallenna", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Käytä tätä osoitetta käyttääksesi tiedostojasi WebDAVin kautta", "New" => "Uusi", "New text file" => "Uusi tekstitiedosto", "Text file" => "Tekstitiedosto", "New folder" => "Uusi kansio", "Folder" => "Kansio", "From link" => "Linkistä", -"Deleted files" => "Poistetut tiedostot", "Cancel upload" => "Peru lähetys", "You don’t have permission to upload or create files here" => "Käyttöoikeutesi eivät riitä tiedostojen lähettämiseen tai kansioiden luomiseen tähän sijaintiin", "Nothing in here. Upload something!" => "Täällä ei ole mitään. Lähetä tänne jotakin!", diff --git a/apps/files/l10n/fr.php b/apps/files/l10n/fr.php index 3e61c782a5631bded7d7ee1bdb72d9e998619ef1..1ddb94d083930482ba94be48c3f2f69b4e8d054a 100644 --- a/apps/files/l10n/fr.php +++ b/apps/files/l10n/fr.php @@ -72,13 +72,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 est illimité", "Maximum input size for ZIP files" => "Taille maximale pour les fichiers ZIP", "Save" => "Sauvegarder", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Utiliser cette adresse pour accéder à vos fichiers par WebDAV", "New" => "Nouveau", "New text file" => "Nouveau fichier texte", "Text file" => "Fichier texte", "New folder" => "Nouveau dossier", "Folder" => "Dossier", "From link" => "Depuis le lien", -"Deleted files" => "Fichiers supprimés", "Cancel upload" => "Annuler l'envoi", "You don’t have permission to upload or create files here" => "Vous n'avez pas la permission de téléverser ou de créer des fichiers ici", "Nothing in here. Upload something!" => "Il n'y a rien ici ! Envoyez donc quelque chose :)", diff --git a/apps/files/l10n/gl.php b/apps/files/l10n/gl.php index 66d981c45430ad376fcdc9bcf09450511c76865b..98a3a73b296a605053d0ae432cb6f5b13b26c447 100644 --- a/apps/files/l10n/gl.php +++ b/apps/files/l10n/gl.php @@ -28,6 +28,7 @@ $TRANSLATIONS = array( "Upload failed. Could not get file info." => "O envío fracasou. Non foi posíbel obter información do ficheiro.", "Invalid directory." => "O directorio é incorrecto.", "Files" => "Ficheiros", +"All files" => "Todos os ficheiros", "Unable to upload {filename} as it is a directory or has 0 bytes" => "Non é posíbel enviar {filename}, xa que ou é un directorio ou ten 0 bytes", "Total file size {size1} exceeds upload limit {size2}" => "O tamaño total do ficheiro {size1} excede do límite de envío {size2}", "Not enough free space, you are uploading {size1} but only {size2} is left" => "Non hai espazo libre abondo, o seu envío é de {size1} mais só dispón de {size2}", @@ -72,13 +73,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 significa ilimitado", "Maximum input size for ZIP files" => "Tamaño máximo de descarga para os ficheiros ZIP", "Save" => "Gardar", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Empregue esta ligazón para acceder aos seus ficheiros mediante WebDAV", "New" => "Novo", "New text file" => "Ficheiro novo de texto", "Text file" => "Ficheiro de texto", "New folder" => "Novo cartafol", "Folder" => "Cartafol", "From link" => "Desde a ligazón", -"Deleted files" => "Ficheiros eliminados", "Cancel upload" => "Cancelar o envío", "You don’t have permission to upload or create files here" => "Non ten permisos para enviar ou crear ficheiros aquí.", "Nothing in here. Upload something!" => "Aquí non hai nada. Envíe algo.", diff --git a/apps/files/l10n/he.php b/apps/files/l10n/he.php index 7f155176546295843a074f1f8d861680af5055fe..e69599694ebd598a68977750de9499205a514071 100644 --- a/apps/files/l10n/he.php +++ b/apps/files/l10n/he.php @@ -40,11 +40,11 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 - ללא הגבלה", "Maximum input size for ZIP files" => "גודל הקלט המרבי לקובצי ZIP", "Save" => "שמירה", +"WebDAV" => "WebDAV", "New" => "חדש", "Text file" => "קובץ טקסט", "Folder" => "תיקייה", "From link" => "מקישור", -"Deleted files" => "קבצים שנמחקו", "Cancel upload" => "ביטול ההעלאה", "Nothing in here. Upload something!" => "אין כאן שום דבר. אולי ברצונך להעלות משהו?", "Download" => "הורדה", diff --git a/apps/files/l10n/hu_HU.php b/apps/files/l10n/hu_HU.php index 3cfb54726147845c03b6baf534ee82bae554ac17..89264c0c525a08c94b07a43684916bc8abca0cf5 100644 --- a/apps/files/l10n/hu_HU.php +++ b/apps/files/l10n/hu_HU.php @@ -65,13 +65,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 = korlátlan", "Maximum input size for ZIP files" => "ZIP-fájlok maximális kiindulási mérete", "Save" => "Mentés", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Ezt a címet használd, hogy hozzáférj a fileokhoz WebDAV-on keresztül", "New" => "Új", "New text file" => "Új szöveges file", "Text file" => "Szövegfájl", "New folder" => "Új mappa", "Folder" => "Mappa", "From link" => "Feltöltés linkről", -"Deleted files" => "Törölt fájlok", "Cancel upload" => "A feltöltés megszakítása", "You don’t have permission to upload or create files here" => "Önnek nincs jogosultsága ahhoz, hogy ide állományokat töltsön föl, vagy itt újakat hozzon létre", "Nothing in here. Upload something!" => "Itt nincs semmi. Töltsön fel valamit!", diff --git a/apps/files/l10n/id.php b/apps/files/l10n/id.php index e4a2529e5ed629fbe917a5b30b21d9f84c3ca24c..4e9852cd18e04364930ba2ad2c06109a6e834015 100644 --- a/apps/files/l10n/id.php +++ b/apps/files/l10n/id.php @@ -63,13 +63,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 berarti tidak terbatas", "Maximum input size for ZIP files" => "Ukuran masukan maksimum untuk berkas ZIP", "Save" => "Simpan", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Gunakan alamat ini untuk mengakses Berkas via WebDAV", "New" => "Baru", "New text file" => "Berkas teks baru", "Text file" => "Berkas teks", "New folder" => "Map baru", "Folder" => "Folder", "From link" => "Dari tautan", -"Deleted files" => "Berkas yang dihapus", "Cancel upload" => "Batal pengunggahan", "You don’t have permission to upload or create files here" => "Anda tidak memiliki akses untuk mengunggah atau membuat berkas disini", "Nothing in here. Upload something!" => "Tidak ada apa-apa di sini. Unggah sesuatu!", diff --git a/apps/files/l10n/is.php b/apps/files/l10n/is.php index 82b3db81d651f4859b5781ce62fa33d3be0861be..982c6f3742d24c3125e6843714f0de493ad29f53 100644 --- a/apps/files/l10n/is.php +++ b/apps/files/l10n/is.php @@ -35,6 +35,7 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 er ótakmarkað", "Maximum input size for ZIP files" => "Hámarks inntaksstærð fyrir ZIP skrár", "Save" => "Vista", +"WebDAV" => "WebDAV", "New" => "Nýtt", "Text file" => "Texta skrá", "Folder" => "Mappa", diff --git a/apps/files/l10n/it.php b/apps/files/l10n/it.php index d55c80091602ff8815f3d4aaf7dec6eba06896e2..e4fed8fd2f97da23535d2076f00a7cc452112863 100644 --- a/apps/files/l10n/it.php +++ b/apps/files/l10n/it.php @@ -28,6 +28,7 @@ $TRANSLATIONS = array( "Upload failed. Could not get file info." => "Caricamento non riuscito. Impossibile ottenere informazioni sul file.", "Invalid directory." => "Cartella non valida.", "Files" => "File", +"All files" => "Tutti i file", "Unable to upload {filename} as it is a directory or has 0 bytes" => "Impossibile caricare {filename} poiché è una cartella oppure ha una dimensione di 0 byte.", "Total file size {size1} exceeds upload limit {size2}" => "La dimensione totale del file {size1} supera il limite di caricamento {size2}", "Not enough free space, you are uploading {size1} but only {size2} is left" => "Spazio insufficiente, stai caricando {size1}, ma è rimasto solo {size2}", @@ -72,13 +73,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 è illimitato", "Maximum input size for ZIP files" => "Dimensione massima per i file ZIP", "Save" => "Salva", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Utilizza questo indirizzo per accedere ai tuoi file con WebDAV", "New" => "Nuovo", "New text file" => "Nuovo file di testo", "Text file" => "File di testo", "New folder" => "Nuova cartella", "Folder" => "Cartella", "From link" => "Da collegamento", -"Deleted files" => "File eliminati", "Cancel upload" => "Annulla invio", "You don’t have permission to upload or create files here" => "Qui non hai i permessi di caricare o creare file", "Nothing in here. Upload something!" => "Non c'è niente qui. Carica qualcosa!", diff --git a/apps/files/l10n/ja.php b/apps/files/l10n/ja.php index 0b00594d71c4406316ae8f08e153f75c7b62e56e..dfbc590d0afb337405ceff5d68077d47f315a49a 100644 --- a/apps/files/l10n/ja.php +++ b/apps/files/l10n/ja.php @@ -72,13 +72,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0を指定した場合は無制限", "Maximum input size for ZIP files" => "ZIPファイルでの最大入力サイズ", "Save" => "保存", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "WebDAV 経由でファイルにアクセス するにはこのアドレスを利用してください", "New" => "新規作成", "New text file" => "新規のテキストファイル作成", "Text file" => "テキストファイル", "New folder" => "新しいフォルダー", "Folder" => "フォルダー", "From link" => "リンク", -"Deleted files" => "ゴミ箱", "Cancel upload" => "アップロードをキャンセル", "You don’t have permission to upload or create files here" => "ここにファイルをアップロードもしくは作成する権限がありません", "Nothing in here. Upload something!" => "ここには何もありません。何かアップロードしてください。", diff --git a/apps/files/l10n/ka_GE.php b/apps/files/l10n/ka_GE.php index d9f5244fa736df165fcb5aacfae014612ae9323e..b13a6ac23ce37b784b25df5d3c48e63a486e48ed 100644 --- a/apps/files/l10n/ka_GE.php +++ b/apps/files/l10n/ka_GE.php @@ -40,12 +40,12 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 is unlimited", "Maximum input size for ZIP files" => "ZIP ფაილების მაქსიმუმ დასაშვები ზომა", "Save" => "შენახვა", +"WebDAV" => "WebDAV", "New" => "ახალი", "Text file" => "ტექსტური ფაილი", "New folder" => "ახალი ფოლდერი", "Folder" => "საქაღალდე", "From link" => "მისამართიდან", -"Deleted files" => "წაშლილი ფაილები", "Cancel upload" => "ატვირთვის გაუქმება", "Nothing in here. Upload something!" => "აქ არაფერი არ არის. ატვირთე რამე!", "Download" => "ჩამოტვირთვა", diff --git a/apps/files/l10n/km.php b/apps/files/l10n/km.php index 08b29304c1b402225e12ea1a6188b81da25739de..3cfb33854bc9c2b54c21726a5ef3a488b129e8f4 100644 --- a/apps/files/l10n/km.php +++ b/apps/files/l10n/km.php @@ -1,17 +1,37 @@ "ឈ្មោះ​ឯកសារ​មិន​អាច​នៅ​ទទេ​បាន​ឡើយ។", +"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "ឈ្មោះ​មិន​ត្រឹម​ត្រូវ, មិន​អនុញ្ញាត '\\', '/', '<', '>', ':', '\"', '|', '?' និង '*' ទេ។", "Files" => "ឯកសារ", +"Upload cancelled." => "បាន​បោះបង់​ការ​ផ្ទុក​ឡើង។", +"{new_name} already exists" => "មាន​ឈ្មោះ {new_name} រួច​ហើយ", "Share" => "ចែក​រំលែក", +"Delete permanently" => "លុប​ជា​អចិន្ត្រៃយ៍", +"Rename" => "ប្ដូរ​ឈ្មោះ", +"Your download is being prepared. This might take some time if the files are big." => "ការ​ទាញយក​របស់​អ្នក​កំពុង​ត្រូវ​បាន​រៀបចំ​ហើយ។ នេះ​អាច​ចំណាយ​ពេល​មួយ​សំទុះ ប្រសិន​បើ​ឯកសារ​ធំ។", +"Pending" => "កំពុង​រង់ចាំ", "Error" => "កំហុស", "Name" => "ឈ្មោះ", "Size" => "ទំហំ", +"Modified" => "បាន​កែ​ប្រែ", "_%n folder_::_%n folders_" => array(""), "_%n file_::_%n files_" => array(""), "_Uploading %n file_::_Uploading %n files_" => array(""), +"Maximum upload size" => "ទំហំ​ផ្ទុកឡើង​ជា​អតិបរមា", +"Enable ZIP-download" => "បើក​ការ​ទាញយក​ជា ZIP", +"0 is unlimited" => "0 គឺ​មិន​កំណត់", +"Maximum input size for ZIP files" => "ទំហំ​ចូល​ជា​អតិបរមា​សម្រាប់​ឯកសារ ZIP", "Save" => "រក្សាទុក", +"WebDAV" => "WebDAV", +"New" => "ថ្មី", +"Text file" => "ឯកសារ​អក្សរ", "New folder" => "ថត​ថ្មី", "Folder" => "ថត", +"From link" => "ពី​តំណ", +"Cancel upload" => "បោះបង់​ការ​ផ្ទុកឡើង", +"Nothing in here. Upload something!" => "គ្មាន​អ្វី​នៅ​ទីនេះ​ទេ។ ផ្ទុក​ឡើង​អ្វី​មួយ!", "Download" => "ទាញយក", -"Delete" => "លុប" +"Delete" => "លុប", +"Upload too large" => "ផ្ទុក​ឡើង​ធំ​ពេក" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files/l10n/ko.php b/apps/files/l10n/ko.php index bfb69bb4445a85b4fa4777889449e4712aa2e42c..ae885bb7a3f5c2c3edeb2abdaf2e66890f8a4d7b 100644 --- a/apps/files/l10n/ko.php +++ b/apps/files/l10n/ko.php @@ -65,13 +65,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0은 무제한입니다", "Maximum input size for ZIP files" => "ZIP 파일 최대 크기", "Save" => "저장", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "WebDAV로 파일에 접근하려면 이 주소를 사용하십시오", "New" => "새로 만들기", "New text file" => "새 텍스트 파일", "Text file" => "텍스트 파일", "New folder" => "새 폴더", "Folder" => "폴더", "From link" => "링크에서", -"Deleted files" => "삭제된 파일", "Cancel upload" => "업로드 취소", "You don’t have permission to upload or create files here" => "여기에 파일을 업로드하거나 만들 권한이 없습니다", "Nothing in here. Upload something!" => "내용이 없습니다. 업로드할 수 있습니다!", diff --git a/apps/files/l10n/lt_LT.php b/apps/files/l10n/lt_LT.php index b2055162d98458046420c40839056aaefca5c5b2..f6fa6514c5c7e23f2a9e7d2ca75e269eab213dc7 100644 --- a/apps/files/l10n/lt_LT.php +++ b/apps/files/l10n/lt_LT.php @@ -65,13 +65,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 yra neribotas", "Maximum input size for ZIP files" => "Maksimalus ZIP archyvo failo dydis", "Save" => "Išsaugoti", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Naudokite šį adresą, kad pasiektumėte savo failus per WebDAV", "New" => "Naujas", "New text file" => "Naujas tekstinis failas", "Text file" => "Teksto failas", "New folder" => "Naujas aplankas", "Folder" => "Katalogas", "From link" => "Iš nuorodos", -"Deleted files" => "Ištrinti failai", "Cancel upload" => "Atšaukti siuntimą", "You don’t have permission to upload or create files here" => "Jūs neturite leidimo čia įkelti arba kurti failus", "Nothing in here. Upload something!" => "Čia tuščia. Įkelkite ką nors!", diff --git a/apps/files/l10n/lv.php b/apps/files/l10n/lv.php index c5a9b9338a7494b606a715888b67f8227f26f1de..970e960384606613120cf3c6a9d6fc162392d372 100644 --- a/apps/files/l10n/lv.php +++ b/apps/files/l10n/lv.php @@ -44,12 +44,12 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 ir neierobežots", "Maximum input size for ZIP files" => "Maksimālais ievades izmērs ZIP datnēm", "Save" => "Saglabāt", +"WebDAV" => "WebDAV", "New" => "Jauna", "Text file" => "Teksta datne", "New folder" => "Jauna mape", "Folder" => "Mape", "From link" => "No saites", -"Deleted files" => "Dzēstās datnes", "Cancel upload" => "Atcelt augšupielādi", "Nothing in here. Upload something!" => "Te vēl nekas nav. Rīkojies, sāc augšupielādēt!", "Download" => "Lejupielādēt", diff --git a/apps/files/l10n/mk.php b/apps/files/l10n/mk.php index 4a1f16c7921af3a3c5c2485c6799cab65ec4391b..293756282c44fa36eb03b1fb3db7c23b44a3888d 100644 --- a/apps/files/l10n/mk.php +++ b/apps/files/l10n/mk.php @@ -56,11 +56,11 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 е неограничено", "Maximum input size for ZIP files" => "Максимална големина за внес на ZIP датотеки", "Save" => "Сними", +"WebDAV" => "WebDAV", "New" => "Ново", "Text file" => "Текстуална датотека", "Folder" => "Папка", "From link" => "Од врска", -"Deleted files" => "Избришани датотеки", "Cancel upload" => "Откажи прикачување", "Nothing in here. Upload something!" => "Тука нема ништо. Снимете нешто!", "Download" => "Преземи", diff --git a/apps/files/l10n/nb_NO.php b/apps/files/l10n/nb_NO.php index 80b706dd5368d28c9516428d1ceaefd165069b73..81f96a81c48b41559973a2678b2439578492b64a 100644 --- a/apps/files/l10n/nb_NO.php +++ b/apps/files/l10n/nb_NO.php @@ -65,13 +65,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 er ubegrenset", "Maximum input size for ZIP files" => "Maksimal størrelse på ZIP-filer", "Save" => "Lagre", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Bruk denne adressen for å aksessere filene dine via WebDAV", "New" => "Ny", "New text file" => "Ny tekstfil", "Text file" => "Tekstfil", "New folder" => "Ny mappe", "Folder" => "Mappe", "From link" => "Fra link", -"Deleted files" => "Slettede filer", "Cancel upload" => "Avbryt opplasting", "You don’t have permission to upload or create files here" => "Du har ikke tillatelse til å laste opp eller opprette filer her", "Nothing in here. Upload something!" => "Ingenting her. Last opp noe!", diff --git a/apps/files/l10n/nl.php b/apps/files/l10n/nl.php index 6bde1e612d0a738450cc7e21063a9c0477599d07..b4b6be87304a2f8fcfadb410c0e6852a4d46704b 100644 --- a/apps/files/l10n/nl.php +++ b/apps/files/l10n/nl.php @@ -72,13 +72,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 is ongelimiteerd", "Maximum input size for ZIP files" => "Maximale grootte voor ZIP bestanden", "Save" => "Bewaren", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Gebruik deze link om uw bestanden via WebDAV te benaderen", "New" => "Nieuw", "New text file" => "Nieuw tekstbestand", "Text file" => "Tekstbestand", "New folder" => "Nieuwe map", "Folder" => "Map", "From link" => "Vanaf link", -"Deleted files" => "Verwijderde bestanden", "Cancel upload" => "Upload afbreken", "You don’t have permission to upload or create files here" => "U hebt geen toestemming om hier te uploaden of bestanden te maken", "Nothing in here. Upload something!" => "Er bevindt zich hier niets. Upload een bestand!", diff --git a/apps/files/l10n/nn_NO.php b/apps/files/l10n/nn_NO.php index 238d1459b1adfe00b40595caa94e9144004faba4..2c6c0479ebcf3b41521e60201abf89975c851e7b 100644 --- a/apps/files/l10n/nn_NO.php +++ b/apps/files/l10n/nn_NO.php @@ -50,12 +50,12 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 er ubegrensa", "Maximum input size for ZIP files" => "Maksimal storleik for ZIP-filer", "Save" => "Lagre", +"WebDAV" => "WebDAV", "New" => "Ny", "Text file" => "Tekst fil", "New folder" => "Ny mappe", "Folder" => "Mappe", "From link" => "Frå lenkje", -"Deleted files" => "Sletta filer", "Cancel upload" => "Avbryt opplasting", "Nothing in here. Upload something!" => "Ingenting her. Last noko opp!", "Download" => "Last ned", diff --git a/apps/files/l10n/pl.php b/apps/files/l10n/pl.php index fa9c7911443bfad08cb8bd341dbea25624845b22..177ae51391caecb47872926e2cef451d5a40468a 100644 --- a/apps/files/l10n/pl.php +++ b/apps/files/l10n/pl.php @@ -72,13 +72,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 - bez limitów", "Maximum input size for ZIP files" => "Maksymalna wielkość pliku wejściowego ZIP ", "Save" => "Zapisz", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Użyj tego adresu do dostępu do twoich plików przez WebDAV", "New" => "Nowy", "New text file" => "Nowy plik tekstowy", "Text file" => "Plik tekstowy", "New folder" => "Nowy folder", "Folder" => "Folder", "From link" => "Z odnośnika", -"Deleted files" => "Pliki usunięte", "Cancel upload" => "Anuluj wysyłanie", "You don’t have permission to upload or create files here" => "Nie masz uprawnień do wczytywania lub tworzenia plików w tym miejscu", "Nothing in here. Upload something!" => "Pusto. Wyślij coś!", diff --git a/apps/files/l10n/pt_BR.php b/apps/files/l10n/pt_BR.php index 5e0399bc4e2c3c35977570549aaf919f065816b4..e65504ea474d897cdeac1c050460313d90a697df 100644 --- a/apps/files/l10n/pt_BR.php +++ b/apps/files/l10n/pt_BR.php @@ -28,6 +28,7 @@ $TRANSLATIONS = array( "Upload failed. Could not get file info." => "Falha no envio. Não foi possível obter informações do arquivo.", "Invalid directory." => "Diretório inválido.", "Files" => "Arquivos", +"All files" => "Todos os arquivos", "Unable to upload {filename} as it is a directory or has 0 bytes" => "Incapaz de fazer o envio de {filename}, pois é um diretório ou tem 0 bytes", "Total file size {size1} exceeds upload limit {size2}" => "Tamanho total do arquivo {size1} excede limite de envio {size2}", "Not enough free space, you are uploading {size1} but only {size2} is left" => "Não há espaço suficiente, você está enviando {size1} mas resta apenas {size2}", @@ -72,13 +73,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 para ilimitado", "Maximum input size for ZIP files" => "Tamanho máximo para arquivo ZIP", "Save" => "Guardar", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Use este endereço para ter acesso a seus Arquivos via WebDAV", "New" => "Novo", "New text file" => "Novo arquivo texto", "Text file" => "Arquivo texto", "New folder" => "Nova pasta", "Folder" => "Pasta", "From link" => "Do link", -"Deleted files" => "Arquivos apagados", "Cancel upload" => "Cancelar upload", "You don’t have permission to upload or create files here" => "Você não tem permissão para carregar ou criar arquivos aqui", "Nothing in here. Upload something!" => "Nada aqui.Carrege alguma coisa!", diff --git a/apps/files/l10n/pt_PT.php b/apps/files/l10n/pt_PT.php index c6d2767fb81f9ec5d20a39e6ca4e1b5f07fced17..189cdebf791c2626d0210ae94e874c16d3f06148 100644 --- a/apps/files/l10n/pt_PT.php +++ b/apps/files/l10n/pt_PT.php @@ -3,7 +3,9 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Não pôde mover o ficheiro %s - Já existe um ficheiro com esse nome", "Could not move %s" => "Não foi possível move o ficheiro %s", "File name cannot be empty." => "O nome do ficheiro não pode estar vazio.", +"\"%s\" is an invalid file name." => "\"%s\" é um nome de ficheiro inválido.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nome Inválido, os caracteres '\\', '/', '<', '>', ':', '\"', '|', '?' e '*' não são permitidos.", +"The target folder has been moved or deleted." => "A pasta de destino foi movida ou eliminada.", "The name %s is already used in the folder %s. Please choose a different name." => "O nome %s já está em uso na pasta %s. Por favor escolha um nome diferente.", "Not a valid source" => "Não é uma fonte válida", "Server is not allowed to open URLs, please check the server configuration" => "O servidor não consegue abrir URLs, por favor verifique a configuração do servidor", @@ -27,6 +29,8 @@ $TRANSLATIONS = array( "Invalid directory." => "Directório Inválido", "Files" => "Ficheiros", "Unable to upload {filename} as it is a directory or has 0 bytes" => "Incapaz de enviar {filename}, dado que é uma pasta, ou tem 0 bytes", +"Total file size {size1} exceeds upload limit {size2}" => "O tamanho total do ficheiro {size1} excede o limite de carregamento {size2}", +"Not enough free space, you are uploading {size1} but only {size2} is left" => "Não existe espaço suficiente. Está a enviar {size1} mas apenas existe {size2} disponível", "Upload cancelled." => "Envio cancelado.", "Could not get result from server." => "Não foi possível obter o resultado do servidor.", "File upload is in progress. Leaving the page now will cancel the upload." => "Envio de ficheiro em progresso. Irá cancelar o envio se sair da página agora.", @@ -40,6 +44,7 @@ $TRANSLATIONS = array( "Rename" => "Renomear", "Your download is being prepared. This might take some time if the files are big." => "O seu download está a ser preparado. Este processo pode demorar algum tempo se os ficheiros forem grandes.", "Pending" => "Pendente", +"Error moving file." => "Erro a mover o ficheiro.", "Error moving file" => "Erro ao mover o ficheiro", "Error" => "Erro", "Could not rename file" => "Não pôde renomear o ficheiro", @@ -50,6 +55,7 @@ $TRANSLATIONS = array( "_%n folder_::_%n folders_" => array("%n pasta","%n pastas"), "_%n file_::_%n files_" => array("%n ficheiro","%n ficheiros"), "_Uploading %n file_::_Uploading %n files_" => array("A carregar %n ficheiro","A carregar %n ficheiros"), +"\"{name}\" is an invalid file name." => "\"{name}\" é um nome de ficheiro inválido.", "Your storage is full, files can not be updated or synced anymore!" => "O seu armazenamento está cheio, os ficheiros não podem ser sincronizados.", "Your storage is almost full ({usedSpacePercent}%)" => "O seu espaço de armazenamento está quase cheiro ({usedSpacePercent}%)", "Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "A Aplicação de Encriptação está ativada, mas as suas chaves não inicializaram. Por favor termine e inicie a sessão novamente", @@ -57,6 +63,7 @@ $TRANSLATIONS = array( "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "A encriptação foi desactivada mas os seus ficheiros continuam encriptados. Por favor consulte as suas definições pessoais para desencriptar os ficheiros.", "{dirs} and {files}" => "{dirs} e {files}", "%s could not be renamed" => "%s não pode ser renomeada", +"Upload (max. %s)" => "Enviar (max. %s)", "File handling" => "Manuseamento de ficheiros", "Maximum upload size" => "Tamanho máximo de envio", "max. possible: " => "max. possivel: ", @@ -65,13 +72,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 é ilimitado", "Maximum input size for ZIP files" => "Tamanho máximo para ficheiros ZIP", "Save" => "Guardar", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Utilize esta ligação para aceder aos seus ficheiros via WebDAV", "New" => "Novo", "New text file" => "Novo ficheiro de texto", "Text file" => "Ficheiro de texto", "New folder" => "Nova Pasta", "Folder" => "Pasta", "From link" => "Da ligação", -"Deleted files" => "Ficheiros eliminados", "Cancel upload" => "Cancelar envio", "You don’t have permission to upload or create files here" => "Você não tem permissão para enviar ou criar ficheiros aqui", "Nothing in here. Upload something!" => "Vazio. Envie alguma coisa!", diff --git a/apps/files/l10n/ro.php b/apps/files/l10n/ro.php index c36ba11fc0c5f6a01294c8de934b9baa085649a4..befb4bad3ac6237448d2eaaebb7a028e47b730f5 100644 --- a/apps/files/l10n/ro.php +++ b/apps/files/l10n/ro.php @@ -72,13 +72,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 este nelimitat", "Maximum input size for ZIP files" => "Dimensiunea maximă de intrare pentru fișierele ZIP", "Save" => "Salvează", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Folosește această adresă pentru acces la fișierele tale folosind WebDAV", "New" => "Nou", "New text file" => "Un nou fișier text", "Text file" => "Fișier text", "New folder" => "Un nou dosar", "Folder" => "Dosar", "From link" => "De la adresa", -"Deleted files" => "Fișiere șterse", "Cancel upload" => "Anulează încărcarea", "You don’t have permission to upload or create files here" => "Nu aveti permisiunea de a incarca sau crea fisiere aici", "Nothing in here. Upload something!" => "Nimic aici. Încarcă ceva!", diff --git a/apps/files/l10n/ru.php b/apps/files/l10n/ru.php index 181e063e6067d110efef1cb0f840a01100e6f31b..9ebd626eac65bc4f6b63199cf8f5a781164a8371 100644 --- a/apps/files/l10n/ru.php +++ b/apps/files/l10n/ru.php @@ -71,13 +71,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 - без ограничений", "Maximum input size for ZIP files" => "Максимальный исходный размер для ZIP файлов", "Save" => "Сохранить", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Используйте этот адресс для доступа к вашим файлам через WebDAV", "New" => "Новый", "New text file" => "Новый текстовый файл", "Text file" => "Текстовый файл", "New folder" => "Новый каталог", "Folder" => "Каталог", "From link" => "Объект по ссылке", -"Deleted files" => "Удалённые файлы", "Cancel upload" => "Отменить загрузку", "You don’t have permission to upload or create files here" => "У вас нет прав для загрузки или создания файлов здесь.", "Nothing in here. Upload something!" => "Здесь ничего нет. Загрузите что-нибудь!", diff --git a/apps/files/l10n/sk_SK.php b/apps/files/l10n/sk_SK.php index 66f1c616e4f2a5329b835c75ef8fc9750567335c..2372a34aa304baeec70c80868f4c621593cfe31d 100644 --- a/apps/files/l10n/sk_SK.php +++ b/apps/files/l10n/sk_SK.php @@ -71,13 +71,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 znamená neobmedzené", "Maximum input size for ZIP files" => "Najväčšia veľkosť ZIP súborov", "Save" => "Uložiť", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Použite túto linku pre prístup k vašim súborom cez WebDAV", "New" => "Nový", "New text file" => "Nový textový súbor", "Text file" => "Textový súbor", "New folder" => "Nový priečinok", "Folder" => "Priečinok", "From link" => "Z odkazu", -"Deleted files" => "Zmazané súbory", "Cancel upload" => "Zrušiť odosielanie", "You don’t have permission to upload or create files here" => "Nemáte oprávnenie sem nahrávať alebo vytvoriť súbory", "Nothing in here. Upload something!" => "Žiadny súbor. Nahrajte niečo!", diff --git a/apps/files/l10n/sl.php b/apps/files/l10n/sl.php index 90b18f632c3f5bac89dabaf952a9812cafe234ec..48f455cc87c72b9ae9afe6edb54f6d2e562947e6 100644 --- a/apps/files/l10n/sl.php +++ b/apps/files/l10n/sl.php @@ -72,13 +72,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 predstavlja neomejeno vrednost", "Maximum input size for ZIP files" => "Največja vhodna velikost za datoteke ZIP", "Save" => "Shrani", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Uporabite naslov za dostop do datotek rpeko sistema WebDAV.", "New" => "Novo", "New text file" => "Nova besedilna datoteka", "Text file" => "Besedilna datoteka", "New folder" => "Nova mapa", "Folder" => "Mapa", "From link" => "Iz povezave", -"Deleted files" => "Izbrisane datoteke", "Cancel upload" => "Prekliči pošiljanje", "You don’t have permission to upload or create files here" => "Ni ustreznih dovoljenj za pošiljanje ali ustvarjanje datotek na tem mestu.", "Nothing in here. Upload something!" => "Tukaj še ni ničesar. Najprej je treba kakšno datoteko poslati v oblak!", diff --git a/apps/files/l10n/sq.php b/apps/files/l10n/sq.php index d246fdd6d64b997db3f368f26a09b81ef466d85e..5a125683b0ef3064de5a3ed4621c02ab0dc86e8e 100644 --- a/apps/files/l10n/sq.php +++ b/apps/files/l10n/sq.php @@ -48,12 +48,12 @@ $TRANSLATIONS = array( "0 is unlimited" => "o është pa limit", "Maximum input size for ZIP files" => "Maksimumi hyrës i skedarëve ZIP", "Save" => "Ruaj", +"WebDAV" => "WebDAV", "New" => "E re", "Text file" => "Skedar tekst", "New folder" => "Dosje e're", "Folder" => "Dosje", "From link" => "Nga lidhja", -"Deleted files" => "Skedarë të fshirë ", "Cancel upload" => "Anullo ngarkimin", "Nothing in here. Upload something!" => "Këtu nuk ka asgje. Ngarko dicka", "Download" => "Shkarko", diff --git a/apps/files/l10n/sr.php b/apps/files/l10n/sr.php index 4cb50b318c2e5b8d8318a1f9a32968045376e171..1f0aaab8cf3e53cf8a4e27efcd609dee6c35ee83 100644 --- a/apps/files/l10n/sr.php +++ b/apps/files/l10n/sr.php @@ -40,11 +40,11 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 је неограничено", "Maximum input size for ZIP files" => "Највећа величина ZIP датотека", "Save" => "Сачувај", +"WebDAV" => "WebDAV", "New" => "Нова", "Text file" => "текстуална датотека", "Folder" => "фасцикла", "From link" => "Са везе", -"Deleted files" => "Обрисане датотеке", "Cancel upload" => "Прекини отпремање", "Nothing in here. Upload something!" => "Овде нема ничег. Отпремите нешто!", "Download" => "Преузми", diff --git a/apps/files/l10n/sv.php b/apps/files/l10n/sv.php index 8908be66d3e45dd9baaf013c2bc8601096132944..657eef47567e4e7e6acc60433c164d510150c526 100644 --- a/apps/files/l10n/sv.php +++ b/apps/files/l10n/sv.php @@ -28,6 +28,7 @@ $TRANSLATIONS = array( "Upload failed. Could not get file info." => "Uppladdning misslyckades. Gick inte att hämta filinformation.", "Invalid directory." => "Felaktig mapp.", "Files" => "Filer", +"All files" => "Alla filer", "Unable to upload {filename} as it is a directory or has 0 bytes" => "Kan inte ladda upp {filename} eftersom den antingen är en mapp eller har 0 bytes.", "Total file size {size1} exceeds upload limit {size2}" => "Totala filstorleken {size1} överskrider uppladdningsgränsen {size2}", "Not enough free space, you are uploading {size1} but only {size2} is left" => "Inte tillräckligt med ledigt utrymme, du laddar upp {size1} men endast {size2} finns kvar.", @@ -44,6 +45,7 @@ $TRANSLATIONS = array( "Rename" => "Byt namn", "Your download is being prepared. This might take some time if the files are big." => "Din nedladdning förbereds. Det kan ta tid om det är stora filer.", "Pending" => "Väntar", +"Error moving file." => "Fel vid flytt av fil.", "Error moving file" => "Fel uppstod vid flyttning av fil", "Error" => "Fel", "Could not rename file" => "Kan ej byta filnamn", @@ -71,13 +73,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 är oändligt", "Maximum input size for ZIP files" => "Största tillåtna storlek för ZIP-filer", "Save" => "Spara", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Använd denna adress till nå dina Filer via WebDAV", "New" => "Ny", "New text file" => "Ny textfil", "Text file" => "Textfil", "New folder" => "Ny mapp", "Folder" => "Mapp", "From link" => "Från länk", -"Deleted files" => "Raderade filer", "Cancel upload" => "Avbryt uppladdning", "You don’t have permission to upload or create files here" => "Du har ej tillåtelse att ladda upp eller skapa filer här", "Nothing in here. Upload something!" => "Ingenting här. Ladda upp något!", diff --git a/apps/files/l10n/th_TH.php b/apps/files/l10n/th_TH.php index 63714471104bbc39a64c49dbf8de360b2664a23a..67ebb99f660c6f520d5a6b502803a845bd2e214c 100644 --- a/apps/files/l10n/th_TH.php +++ b/apps/files/l10n/th_TH.php @@ -39,6 +39,7 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 หมายถึงไม่จำกัด", "Maximum input size for ZIP files" => "ขนาดไฟล์ ZIP สูงสุด", "Save" => "บันทึก", +"WebDAV" => "WebDAV", "New" => "อัพโหลดไฟล์ใหม่", "Text file" => "ไฟล์ข้อความ", "New folder" => "โฟลเดอร์ใหม่", diff --git a/apps/files/l10n/tr.php b/apps/files/l10n/tr.php index a62e0f3eb66ed1dc5a5bbe863b8064624dfce779..45e8062ad6809e4b0126d4e8ff838abc99c03ddb 100644 --- a/apps/files/l10n/tr.php +++ b/apps/files/l10n/tr.php @@ -28,6 +28,7 @@ $TRANSLATIONS = array( "Upload failed. Could not get file info." => "Yükleme başarısız. Dosya bilgisi alınamadı.", "Invalid directory." => "Geçersiz dizin.", "Files" => "Dosyalar", +"All files" => "Tüm dosyalar", "Unable to upload {filename} as it is a directory or has 0 bytes" => "Bir dizin veya 0 bayt olduğundan {filename} yüklenemedi", "Total file size {size1} exceeds upload limit {size2}" => "Toplam dosya boyutu {size1}, {size2} gönderme sınırını aşıyor", "Not enough free space, you are uploading {size1} but only {size2} is left" => "Yeterince boş alan yok. Gönderdiğiniz boyut {size1} ancak {size2} alan mevcut", @@ -72,13 +73,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 limitsiz demektir", "Maximum input size for ZIP files" => "ZIP dosyaları için en fazla girdi boyutu", "Save" => "Kaydet", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "Dosyalarınıza WebDAV aracılığıyla erişmek için bu adresi kullanın", "New" => "Yeni", "New text file" => "Yeni metin dosyası", "Text file" => "Metin dosyası", "New folder" => "Yeni klasör", "Folder" => "Klasör", "From link" => "Bağlantıdan", -"Deleted files" => "Silinmiş dosyalar", "Cancel upload" => "Yüklemeyi iptal et", "You don’t have permission to upload or create files here" => "Buraya dosya yükleme veya oluşturma izniniz yok", "Nothing in here. Upload something!" => "Burada hiçbir şey yok. Bir şeyler yükleyin!", diff --git a/apps/files/l10n/ug.php b/apps/files/l10n/ug.php index 446852368f30a76b3f015997151c4d9d903b262c..b104f60794763bede78f124e8aadd67ae0f131e4 100644 --- a/apps/files/l10n/ug.php +++ b/apps/files/l10n/ug.php @@ -22,11 +22,11 @@ $TRANSLATIONS = array( "_%n file_::_%n files_" => array(""), "_Uploading %n file_::_Uploading %n files_" => array(""), "Save" => "ساقلا", +"WebDAV" => "WebDAV", "New" => "يېڭى", "Text file" => "تېكىست ھۆججەت", "New folder" => "يېڭى قىسقۇچ", "Folder" => "قىسقۇچ", -"Deleted files" => "ئۆچۈرۈلگەن ھۆججەتلەر", "Cancel upload" => "يۈكلەشتىن ۋاز كەچ", "Nothing in here. Upload something!" => "بۇ جايدا ھېچنېمە يوق. Upload something!", "Download" => "چۈشۈر", diff --git a/apps/files/l10n/uk.php b/apps/files/l10n/uk.php index 8fb578016c75b8d02aba1206cf0307703b4dbaf1..efdbcc2c4b43d22db8b408a75475408d72df767e 100644 --- a/apps/files/l10n/uk.php +++ b/apps/files/l10n/uk.php @@ -48,12 +48,12 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 є безліміт", "Maximum input size for ZIP files" => "Максимальний розмір завантажуємого ZIP файлу", "Save" => "Зберегти", +"WebDAV" => "WebDAV", "New" => "Створити", "Text file" => "Текстовий файл", "New folder" => "Нова тека", "Folder" => "Тека", "From link" => "З посилання", -"Deleted files" => "Видалено файлів", "Cancel upload" => "Перервати завантаження", "Nothing in here. Upload something!" => "Тут нічого немає. Відвантажте що-небудь!", "Download" => "Завантажити", diff --git a/apps/files/l10n/ur_PK.php b/apps/files/l10n/ur_PK.php index b9548acde92c17a83f69260c7f9bf7f50dc1cba1..203f93b5e80933a2bd6eda103548acf5f5b89120 100644 --- a/apps/files/l10n/ur_PK.php +++ b/apps/files/l10n/ur_PK.php @@ -1,8 +1,12 @@ "تقسیم", "Error" => "ایرر", +"Name" => "اسم", "_%n folder_::_%n folders_" => array("",""), "_%n file_::_%n files_" => array("",""), -"_Uploading %n file_::_Uploading %n files_" => array("","") +"_Uploading %n file_::_Uploading %n files_" => array("",""), +"Save" => "حفظ", +"Delete" => "حذف کریں" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files/l10n/vi.php b/apps/files/l10n/vi.php index c14f1b7ea0984deff368e0441b50343299730d3a..c8b8a6960405bf196d6e37a9f548f6fc10b8bb1b 100644 --- a/apps/files/l10n/vi.php +++ b/apps/files/l10n/vi.php @@ -63,13 +63,13 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 là không giới hạn", "Maximum input size for ZIP files" => "Kích thước tối đa cho các tập tin ZIP", "Save" => "Lưu", +"WebDAV" => "WebDAV", "New" => "Tạo mới", "New text file" => "File text mới", "Text file" => "Tập tin văn bản", "New folder" => "Tạo thư mục", "Folder" => "Thư mục", "From link" => "Từ liên kết", -"Deleted files" => "File đã bị xóa", "Cancel upload" => "Hủy upload", "You don’t have permission to upload or create files here" => "Bạn không có quyền upload hoặc tạo files ở đây", "Nothing in here. Upload something!" => "Không có gì ở đây .Hãy tải lên một cái gì đó !", diff --git a/apps/files/l10n/zh_CN.php b/apps/files/l10n/zh_CN.php index 7f0183e9205a9f797c7f65bf9986ca81feae189c..39c7f86ece3e68af6d43b93d0008e21bdb4de4b0 100644 --- a/apps/files/l10n/zh_CN.php +++ b/apps/files/l10n/zh_CN.php @@ -72,13 +72,14 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 为无限制", "Maximum input size for ZIP files" => "ZIP 文件的最大输入大小", "Save" => "保存", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "使用这个地址 通过 WebDAV 访问您的文件", "New" => "新建", "New text file" => "创建文本文件", "Text file" => "文本文件", "New folder" => "添加文件夹", "Folder" => "文件夹", "From link" => "来自链接", -"Deleted files" => "已删除文件", "Cancel upload" => "取消上传", "You don’t have permission to upload or create files here" => "您没有权限来上传湖州哦和创建文件", "Nothing in here. Upload something!" => "这里还什么都没有。上传些东西吧!", diff --git a/apps/files/l10n/zh_TW.php b/apps/files/l10n/zh_TW.php index 7b4caf592a088f90fe235767eec3284c9479953d..9e56c853ad7aaa9590500cdb2330e51d36bfda44 100644 --- a/apps/files/l10n/zh_TW.php +++ b/apps/files/l10n/zh_TW.php @@ -62,12 +62,13 @@ $TRANSLATIONS = array( "0 is unlimited" => "0代表沒有限制", "Maximum input size for ZIP files" => "ZIP 壓縮前的原始大小限制", "Save" => "儲存", +"WebDAV" => "WebDAV", +"Use this address to access your Files via WebDAV" => "使用這個地址來透過 WebDAV 存取檔案", "New" => "新增", "Text file" => "文字檔", "New folder" => "新資料夾", "Folder" => "資料夾", "From link" => "從連結", -"Deleted files" => "回收桶", "Cancel upload" => "取消上傳", "You don’t have permission to upload or create files here" => "您沒有權限在這裡上傳或建立檔案", "Nothing in here. Upload something!" => "這裡還沒有東西,上傳一些吧!", diff --git a/apps/files/lib/app.php b/apps/files/lib/app.php index ed4aa32c66246bb0058f1a76d94b6c7c392d6c4a..e32225d06805451ae98c85f8d2873182e5942a71 100644 --- a/apps/files/lib/app.php +++ b/apps/files/lib/app.php @@ -30,6 +30,11 @@ class App { */ private $l10n; + /** + * @var \OCP\INavigationManager + */ + private static $navigationManager; + /** * @var \OC\Files\View */ @@ -40,6 +45,18 @@ class App { $this->l10n = $l10n; } + /** + * Returns the app's navigation manager + * + * @return \OCP\INavigationManager + */ + public static function getNavigationManager() { + if (self::$navigationManager === null) { + self::$navigationManager = new \OC\NavigationManager(); + } + return self::$navigationManager; + } + /** * rename a file * diff --git a/apps/files/lib/helper.php b/apps/files/lib/helper.php index 0ae87d12fbfb3974a90b47bd388dcc30ef096a5c..7d8906e22514b9f9383685519839a7a7682c2250 100644 --- a/apps/files/lib/helper.php +++ b/apps/files/lib/helper.php @@ -1,7 +1,16 @@ + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ namespace OCA\Files; +/** + * Helper class for manipulating file information + */ class Helper { public static function buildFileStorageStatistics($dir) { @@ -9,12 +18,12 @@ class Helper $storageInfo = \OC_Helper::getStorageInfo($dir); $l = new \OC_L10N('files'); - $maxUploadFilesize = \OCP\Util::maxUploadFilesize($dir, $storageInfo['free']); - $maxHumanFilesize = \OCP\Util::humanFileSize($maxUploadFilesize); - $maxHumanFilesize = $l->t('Upload (max. %s)', array($maxHumanFilesize)); + $maxUploadFileSize = \OCP\Util::maxUploadFilesize($dir, $storageInfo['free']); + $maxHumanFileSize = \OCP\Util::humanFileSize($maxUploadFileSize); + $maxHumanFileSize = $l->t('Upload (max. %s)', array($maxHumanFileSize)); - return array('uploadMaxFilesize' => $maxUploadFilesize, - 'maxHumanFilesize' => $maxHumanFilesize, + return array('uploadMaxFilesize' => $maxUploadFileSize, + 'maxHumanFilesize' => $maxHumanFileSize, 'freeSpace' => $storageInfo['free'], 'usedSpacePercent' => (int)$storageInfo['relative']); } @@ -27,20 +36,11 @@ class Helper */ public static function determineIcon($file) { if($file['type'] === 'dir') { - $dir = $file['directory']; $icon = \OC_Helper::mimetypeIcon('dir'); - $absPath = $file->getPath(); - $mount = \OC\Files\Filesystem::getMountManager()->find($absPath); - if (!is_null($mount)) { - $sid = $mount->getStorageId(); - if (!is_null($sid)) { - $sid = explode(':', $sid); - if ($sid[0] === 'shared') { - $icon = \OC_Helper::mimetypeIcon('dir-shared'); - } elseif ($sid[0] !== 'local' and $sid[0] !== 'home') { - $icon = \OC_Helper::mimetypeIcon('dir-external'); - } - } + if ($file->isShared()) { + $icon = \OC_Helper::mimetypeIcon('dir-shared'); + } elseif ($file->isMounted()) { + $icon = \OC_Helper::mimetypeIcon('dir-external'); } }else{ $icon = \OC_Helper::mimetypeIcon($file->getMimetype()); @@ -57,7 +57,7 @@ class Helper * @param \OCP\Files\FileInfo $b file * @return int -1 if $a must come before $b, 1 otherwise */ - public static function fileCmp($a, $b) { + public static function compareFileNames($a, $b) { $aType = $a->getType(); $bType = $b->getType(); if ($aType === 'dir' and $bType !== 'dir') { @@ -69,6 +69,32 @@ class Helper } } + /** + * Comparator function to sort files by date + * + * @param \OCP\Files\FileInfo $a file + * @param \OCP\Files\FileInfo $b file + * @return int -1 if $a must come before $b, 1 otherwise + */ + public static function compareTimestamp($a, $b) { + $aTime = $a->getMTime(); + $bTime = $b->getMTime(); + return $aTime - $bTime; + } + + /** + * Comparator function to sort files by size + * + * @param \OCP\Files\FileInfo $a file + * @param \OCP\Files\FileInfo $b file + * @return int -1 if $a must come before $b, 1 otherwise + */ + public static function compareSize($a, $b) { + $aSize = $a->getSize(); + $bSize = $b->getSize(); + return $aSize - $bSize; + } + /** * Formats the file info to be returned as JSON to the client. * @@ -120,12 +146,35 @@ class Helper * returns it as a sorted array of FileInfo. * * @param string $dir path to the directory + * @param string $sortAttribute attribute to sort on + * @param bool $sortDescending true for descending sort, false otherwise * @return \OCP\Files\FileInfo[] files */ - public static function getFiles($dir) { + public static function getFiles($dir, $sortAttribute = 'name', $sortDescending = false) { $content = \OC\Files\Filesystem::getDirectoryContent($dir); - usort($content, array('\OCA\Files\Helper', 'fileCmp')); - return $content; + return self::sortFiles($content, $sortAttribute, $sortDescending); + } + + /** + * Sort the given file info array + * + * @param \OCP\Files\FileInfo[] $files files to sort + * @param string $sortAttribute attribute to sort on + * @param bool $sortDescending true for descending sort, false otherwise + * @return \OCP\Files\FileInfo[] sorted files + */ + public static function sortFiles($files, $sortAttribute = 'name', $sortDescending = false) { + $sortFunc = 'compareFileNames'; + if ($sortAttribute === 'mtime') { + $sortFunc = 'compareTimestamp'; + } else if ($sortAttribute === 'size') { + $sortFunc = 'compareSize'; + } + usort($files, array('\OCA\Files\Helper', $sortFunc)); + if ($sortDescending) { + $files = array_reverse($files); + } + return $files; } } diff --git a/apps/files/list.php b/apps/files/list.php new file mode 100644 index 0000000000000000000000000000000000000000..e583839b2519449f3e1e366ec1b98fd18da8cec7 --- /dev/null +++ b/apps/files/list.php @@ -0,0 +1,38 @@ + + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library 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 along with this library. If not, see . + * + */ + +// Check if we are a user +OCP\User::checkLoggedIn(); + +$config = \OC::$server->getConfig(); +// TODO: move this to the generated config.js +$publicUploadEnabled = $config->getAppValue('core', 'shareapi_allow_public_upload', 'yes'); +$uploadLimit=OCP\Util::uploadLimit(); + +// renders the controls and table headers template +$tmpl = new OCP\Template('files', 'list', ''); +$tmpl->assign('uploadLimit', $uploadLimit); // PHP upload limit +$tmpl->assign('publicUploadEnabled', $publicUploadEnabled); +$tmpl->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true))); +$tmpl->printPage(); + diff --git a/apps/files/templates/appnavigation.php b/apps/files/templates/appnavigation.php new file mode 100644 index 0000000000000000000000000000000000000000..86436bbe8c4733398c0bf809a610a04a941286fe --- /dev/null +++ b/apps/files/templates/appnavigation.php @@ -0,0 +1,17 @@ +
+
    + + + +
+
+
+ +
+
+

t('WebDAV'));?>

+
+ t('Use this address to access your Files via WebDAV', array(link_to_docs('user-webdav'))));?> +
+
+
diff --git a/apps/files/templates/index.php b/apps/files/templates/index.php index 42263c880a7b530ccfa78d12e8a5410dcd81c830..8cab4ce220b864523a5b898fb98383574aa7b306 100644 --- a/apps/files/templates/index.php +++ b/apps/files/templates/index.php @@ -1,117 +1,15 @@ -
- -
- - -
- - - - - - - - - - - - - - - - - -
-
-
-

- t('The files you are trying to upload exceed the maximum size for file uploads on this server.'));?> -

-
-
-

- t('Files are being scanned, please wait.'));?> -

-

- t('Current scanning'));?> -

-
+ +printPage(); ?> +
+ + + +
- diff --git a/apps/files/templates/list.php b/apps/files/templates/list.php new file mode 100644 index 0000000000000000000000000000000000000000..8f11f965b2d960f30f17dc1e1a34d29e54e79cf9 --- /dev/null +++ b/apps/files/templates/list.php @@ -0,0 +1,107 @@ +
+ +
+ + +
+ + + + + + + + + + + + + + + +
+ + +
+
+

+ t('The files you are trying to upload exceed the maximum size for file uploads on this server.'));?> +

+
+
+

+ t('Files are being scanned, please wait.'));?> +

+

+ t('Current scanning'));?> +

+
diff --git a/apps/files/tests/ajax_rename.php b/apps/files/tests/ajax_rename.php index 74ca1e4495da1409742df4fb142ba2eacc54ad5b..9928053e5015ac0861f604e5a84cd76b1c771e97 100644 --- a/apps/files/tests/ajax_rename.php +++ b/apps/files/tests/ajax_rename.php @@ -24,6 +24,16 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase { private static $user; + /** + * @var PHPUnit_Framework_MockObject_MockObject + */ + private $viewMock; + + /** + * @var \OCA\Files\App + */ + private $files; + function setUp() { // mock OC_L10n if (!self::$user) { @@ -56,7 +66,7 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase { } /** - * @brief test rename of file/folder + * test rename of file/folder */ function testRenameFolder() { $dir = '/'; @@ -72,7 +82,7 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase { ->method('getFileInfo') ->will($this->returnValue(new \OC\Files\FileInfo( '/', - null, + new \OC\Files\Storage\Local(array('datadir' => '/')), '/', array( 'fileid' => 123, diff --git a/apps/files/tests/helper.php b/apps/files/tests/helper.php new file mode 100644 index 0000000000000000000000000000000000000000..9b3603cd5633197d272898ac71d0744ddeb2ffcb --- /dev/null +++ b/apps/files/tests/helper.php @@ -0,0 +1,98 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +require_once __DIR__ . '/../lib/helper.php'; + +use OCA\Files; + +/** + * Class Test_Files_Helper + */ +class Test_Files_Helper extends \PHPUnit_Framework_TestCase { + + private function makeFileInfo($name, $size, $mtime, $isDir = false) { + return new \OC\Files\FileInfo( + '/', + null, + '/', + array( + 'name' => $name, + 'size' => $size, + 'mtime' => $mtime, + 'type' => $isDir ? 'dir' : 'file', + 'mimetype' => $isDir ? 'httpd/unix-directory' : 'application/octet-stream' + ) + ); + } + + /** + * Returns a file list for testing + */ + private function getTestFileList() { + return array( + self::makeFileInfo('a.txt', 4, 1000), + self::makeFileInfo('q.txt', 5, 150), + self::makeFileInfo('subdir2', 87, 128, true), + self::makeFileInfo('b.txt', 166, 800), + self::makeFileInfo('o.txt', 12, 100), + self::makeFileInfo('subdir', 88, 125, true), + ); + } + + function sortDataProvider() { + return array( + array( + 'name', + false, + array('subdir', 'subdir2', 'a.txt', 'b.txt', 'o.txt', 'q.txt'), + ), + array( + 'name', + true, + array('q.txt', 'o.txt', 'b.txt', 'a.txt', 'subdir2', 'subdir'), + ), + array( + 'size', + false, + array('a.txt', 'q.txt', 'o.txt', 'subdir2', 'subdir', 'b.txt'), + ), + array( + 'size', + true, + array('b.txt', 'subdir', 'subdir2', 'o.txt', 'q.txt', 'a.txt'), + ), + array( + 'mtime', + false, + array('o.txt', 'subdir', 'subdir2', 'q.txt', 'b.txt', 'a.txt'), + ), + array( + 'mtime', + true, + array('a.txt', 'b.txt', 'q.txt', 'subdir2', 'subdir', 'o.txt'), + ), + ); + } + + /** + * @dataProvider sortDataProvider + */ + public function testSortByName($sort, $sortDescending, $expectedOrder) { + $files = self::getTestFileList(); + $files = \OCA\Files\Helper::sortFiles($files, $sort, $sortDescending); + $fileNames = array(); + foreach ($files as $fileInfo) { + $fileNames[] = $fileInfo->getName(); + } + $this->assertEquals( + $expectedOrder, + $fileNames + ); + } + +} diff --git a/apps/files/tests/js/appSpec.js b/apps/files/tests/js/appSpec.js new file mode 100644 index 0000000000000000000000000000000000000000..0e9abad6989c9c84b04e82a532aaeee309bcd103 --- /dev/null +++ b/apps/files/tests/js/appSpec.js @@ -0,0 +1,220 @@ +/** +* ownCloud +* +* @author Vincent Petry +* @copyright 2014 Vincent Petry +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +* License as published by the Free Software Foundation; either +* version 3 of the License, or any later version. +* +* This library 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 along with this library. If not, see . +* +*/ + +describe('OCA.Files.App tests', function() { + var App = OCA.Files.App; + var pushStateStub; + var parseUrlQueryStub; + + beforeEach(function() { + $('#testArea').append( + '
' + + '
' + + '
' + + '
' + + '' + + '' + + '
' + + '
' + + '' + ); + + pushStateStub = sinon.stub(OC.Util.History, 'pushState'); + parseUrlQueryStub = sinon.stub(OC.Util.History, 'parseUrlQuery'); + parseUrlQueryStub.returns({}); + + App.initialize(); + }); + afterEach(function() { + App.navigation = null; + App.fileList = null; + App.files = null; + App.fileActions.clear(); + App.fileActions = null; + + pushStateStub.restore(); + parseUrlQueryStub.restore(); + }); + + describe('initialization', function() { + it('initializes the default file list with the default file actions', function() { + expect(App.fileList).toBeDefined(); + expect(App.fileList.fileActions.actions.all).toBeDefined(); + expect(App.fileList.$el.is('#app-content-files')).toEqual(true); + }); + }); + + describe('URL handling', function() { + it('pushes the state to the URL when current app changed directory', function() { + $('#app-content-files').trigger(new $.Event('changeDirectory', {dir: 'subdir'})); + expect(pushStateStub.calledOnce).toEqual(true); + expect(pushStateStub.getCall(0).args[0].dir).toEqual('subdir'); + expect(pushStateStub.getCall(0).args[0].view).not.toBeDefined(); + + $('li[data-id=other]>a').click(); + pushStateStub.reset(); + + $('#app-content-other').trigger(new $.Event('changeDirectory', {dir: 'subdir'})); + expect(pushStateStub.calledOnce).toEqual(true); + expect(pushStateStub.getCall(0).args[0].dir).toEqual('subdir'); + expect(pushStateStub.getCall(0).args[0].view).toEqual('other'); + }); + describe('onpopstate', function() { + it('sends "urlChanged" event to current app', function() { + var handler = sinon.stub(); + $('#app-content-files').on('urlChanged', handler); + App._onPopState({view: 'files', dir: '/somedir'}); + expect(handler.calledOnce).toEqual(true); + expect(handler.getCall(0).args[0].view).toEqual('files'); + expect(handler.getCall(0).args[0].dir).toEqual('/somedir'); + }); + it('sends "show" event to current app and sets navigation', function() { + var showHandlerFiles = sinon.stub(); + var showHandlerOther = sinon.stub(); + var hideHandlerFiles = sinon.stub(); + var hideHandlerOther = sinon.stub(); + $('#app-content-files').on('show', showHandlerFiles); + $('#app-content-files').on('hide', hideHandlerFiles); + $('#app-content-other').on('show', showHandlerOther); + $('#app-content-other').on('hide', hideHandlerOther); + App._onPopState({view: 'other', dir: '/somedir'}); + expect(showHandlerFiles.notCalled).toEqual(true); + expect(hideHandlerFiles.calledOnce).toEqual(true); + expect(showHandlerOther.calledOnce).toEqual(true); + expect(hideHandlerOther.notCalled).toEqual(true); + + showHandlerFiles.reset(); + showHandlerOther.reset(); + hideHandlerFiles.reset(); + hideHandlerOther.reset(); + + App._onPopState({view: 'files', dir: '/somedir'}); + expect(showHandlerFiles.calledOnce).toEqual(true); + expect(hideHandlerFiles.notCalled).toEqual(true); + expect(showHandlerOther.notCalled).toEqual(true); + expect(hideHandlerOther.calledOnce).toEqual(true); + + expect(App.navigation.getActiveItem()).toEqual('files'); + expect($('#app-content-files').hasClass('hidden')).toEqual(false); + expect($('#app-content-other').hasClass('hidden')).toEqual(true); + }); + it('does not send "show" or "hide" event to current app when already visible', function() { + var showHandler = sinon.stub(); + var hideHandler = sinon.stub(); + $('#app-content-files').on('show', showHandler); + $('#app-content-files').on('hide', hideHandler); + App._onPopState({view: 'files', dir: '/somedir'}); + expect(showHandler.notCalled).toEqual(true); + expect(hideHandler.notCalled).toEqual(true); + }); + it('state defaults to files app with root dir', function() { + var handler = sinon.stub(); + parseUrlQueryStub.returns({}); + $('#app-content-files').on('urlChanged', handler); + App._onPopState(); + expect(handler.calledOnce).toEqual(true); + expect(handler.getCall(0).args[0].view).toEqual('files'); + expect(handler.getCall(0).args[0].dir).toEqual('/'); + }); + it('activates files app if invalid view is passed', function() { + App._onPopState({view: 'invalid', dir: '/somedir'}); + + expect(App.navigation.getActiveItem()).toEqual('files'); + expect($('#app-content-files').hasClass('hidden')).toEqual(false); + }); + }); + describe('navigation', function() { + it('switches the navigation item and panel visibility when onpopstate', function() { + App._onPopState({view: 'other', dir: '/somedir'}); + expect(App.navigation.getActiveItem()).toEqual('other'); + expect($('#app-content-files').hasClass('hidden')).toEqual(true); + expect($('#app-content-other').hasClass('hidden')).toEqual(false); + expect($('li[data-id=files]').hasClass('selected')).toEqual(false); + expect($('li[data-id=other]').hasClass('selected')).toEqual(true); + + App._onPopState({view: 'files', dir: '/somedir'}); + + expect(App.navigation.getActiveItem()).toEqual('files'); + expect($('#app-content-files').hasClass('hidden')).toEqual(false); + expect($('#app-content-other').hasClass('hidden')).toEqual(true); + expect($('li[data-id=files]').hasClass('selected')).toEqual(true); + expect($('li[data-id=other]').hasClass('selected')).toEqual(false); + }); + it('clicking on navigation switches the panel visibility', function() { + $('li[data-id=other]>a').click(); + expect(App.navigation.getActiveItem()).toEqual('other'); + expect($('#app-content-files').hasClass('hidden')).toEqual(true); + expect($('#app-content-other').hasClass('hidden')).toEqual(false); + expect($('li[data-id=files]').hasClass('selected')).toEqual(false); + expect($('li[data-id=other]').hasClass('selected')).toEqual(true); + + $('li[data-id=files]>a').click(); + expect(App.navigation.getActiveItem()).toEqual('files'); + expect($('#app-content-files').hasClass('hidden')).toEqual(false); + expect($('#app-content-other').hasClass('hidden')).toEqual(true); + expect($('li[data-id=files]').hasClass('selected')).toEqual(true); + expect($('li[data-id=other]').hasClass('selected')).toEqual(false); + }); + it('clicking on navigation sends "show" and "urlChanged" event', function() { + var handler = sinon.stub(); + var showHandler = sinon.stub(); + $('#app-content-other').on('urlChanged', handler); + $('#app-content-other').on('show', showHandler); + $('li[data-id=other]>a').click(); + expect(handler.calledOnce).toEqual(true); + expect(handler.getCall(0).args[0].view).toEqual('other'); + expect(handler.getCall(0).args[0].dir).toEqual('/'); + expect(showHandler.calledOnce).toEqual(true); + }); + it('clicking on activate navigation only sends "urlChanged" event', function() { + var handler = sinon.stub(); + var showHandler = sinon.stub(); + $('#app-content-files').on('urlChanged', handler); + $('#app-content-files').on('show', showHandler); + $('li[data-id=files]>a').click(); + expect(handler.calledOnce).toEqual(true); + expect(handler.getCall(0).args[0].view).toEqual('files'); + expect(handler.getCall(0).args[0].dir).toEqual('/'); + expect(showHandler.notCalled).toEqual(true); + }); + }); + describe('viewer mode', function() { + it('toggles the sidebar when viewer mode is enabled', function() { + $('#app-content-files').trigger( + new $.Event('changeViewerMode', {viewerModeEnabled: true} + )); + expect($('#app-navigation').hasClass('hidden')).toEqual(true); + expect($('.app-files').hasClass('viewer-mode no-sidebar')).toEqual(true); + + $('#app-content-files').trigger( + new $.Event('changeViewerMode', {viewerModeEnabled: false} + )); + + expect($('#app-navigation').hasClass('hidden')).toEqual(false); + expect($('.app-files').hasClass('viewer-mode no-sidebar')).toEqual(false); + }); + }); + }); +}); diff --git a/apps/files/tests/js/breadcrumbSpec.js b/apps/files/tests/js/breadcrumbSpec.js index 1bfe5308a278c0dcabfcff3a9661ec14c01b47fc..e3d9c757a7c0a1e01031b2ed6b28f56aefd448b4 100644 --- a/apps/files/tests/js/breadcrumbSpec.js +++ b/apps/files/tests/js/breadcrumbSpec.js @@ -20,7 +20,9 @@ */ /* global BreadCrumb */ -describe('BreadCrumb tests', function() { +describe('OCA.Files.BreadCrumb tests', function() { + var BreadCrumb = OCA.Files.BreadCrumb; + describe('Rendering', function() { var bc; beforeEach(function() { diff --git a/apps/files/tests/js/fileactionsSpec.js b/apps/files/tests/js/fileactionsSpec.js index f5eafba509f6d5ed8925aa5831ddc1012367582a..9152dbb58c30a6961f3265698f95d7d70b53827e 100644 --- a/apps/files/tests/js/fileactionsSpec.js +++ b/apps/files/tests/js/fileactionsSpec.js @@ -19,35 +19,45 @@ * */ -/* global OC, FileActions, FileList */ -describe('FileActions tests', function() { - var $filesTable; +describe('OCA.Files.FileActions tests', function() { + var $filesTable, fileList; + var FileActions = OCA.Files.FileActions; beforeEach(function() { // init horrible parameters - var $body = $('body'); + var $body = $('#testArea'); $body.append(''); $body.append(''); // dummy files table $filesTable = $body.append('
'); - FileList.files = []; + fileList = new OCA.Files.FileList($('#testArea')); + FileActions.registerDefaultActions(fileList); }); afterEach(function() { + FileActions.clear(); + fileList = undefined; $('#dir, #permissions, #filestable').remove(); }); + it('calling clear() clears file actions', function() { + FileActions.clear(); + expect(FileActions.actions).toEqual({}); + expect(FileActions.defaults).toEqual({}); + expect(FileActions.icons).toEqual({}); + expect(FileActions.currentFile).toBe(null); + }); it('calling display() sets file actions', function() { var fileData = { id: 18, type: 'file', name: 'testName.txt', - mimetype: 'plain/text', + mimetype: 'text/plain', size: '1234', etag: 'a01234c', mtime: '123456' }; // note: FileActions.display() is called implicitly - var $tr = FileList.add(fileData); + var $tr = fileList.add(fileData); // actions defined after call expect($tr.find('.action.action-download').length).toEqual(1); @@ -61,12 +71,12 @@ describe('FileActions tests', function() { id: 18, type: 'file', name: 'testName.txt', - mimetype: 'plain/text', + mimetype: 'text/plain', size: '1234', etag: 'a01234c', mtime: '123456' }; - var $tr = FileList.add(fileData); + var $tr = fileList.add(fileData); FileActions.display($tr.find('td.filename'), true); FileActions.display($tr.find('td.filename'), true); @@ -82,12 +92,12 @@ describe('FileActions tests', function() { id: 18, type: 'file', name: 'testName.txt', - mimetype: 'plain/text', + mimetype: 'text/plain', size: '1234', etag: 'a01234c', mtime: '123456' }; - var $tr = FileList.add(fileData); + var $tr = fileList.add(fileData); FileActions.display($tr.find('td.filename'), true); $tr.find('.action-download').click(); @@ -97,17 +107,17 @@ describe('FileActions tests', function() { redirectStub.restore(); }); it('deletes file when clicking delete', function() { - var deleteStub = sinon.stub(FileList, 'do_delete'); + var deleteStub = sinon.stub(fileList, 'do_delete'); var fileData = { id: 18, type: 'file', name: 'testName.txt', - mimetype: 'plain/text', + mimetype: 'text/plain', size: '1234', etag: 'a01234c', mtime: '123456' }; - var $tr = FileList.add(fileData); + var $tr = fileList.add(fileData); FileActions.display($tr.find('td.filename'), true); $tr.find('.action.delete').click(); diff --git a/apps/files/tests/js/filelistSpec.js b/apps/files/tests/js/filelistSpec.js index 7a2b56d559a00edcf6b5fdf3e26cd5ce98875287..bfc983c7483bd7140146deb566f42b328b6f93ee 100644 --- a/apps/files/tests/js/filelistSpec.js +++ b/apps/files/tests/js/filelistSpec.js @@ -19,10 +19,9 @@ * */ -/* global OC, FileList */ -describe('FileList tests', function() { - var testFiles, alertStub, notificationStub, - pushStateStub; +describe('OCA.Files.FileList tests', function() { + var testFiles, alertStub, notificationStub, fileList; + var FileActions = OCA.Files.FileActions; /** * Generate test file data @@ -52,21 +51,13 @@ describe('FileList tests', function() { } beforeEach(function() { - // init horrible parameters - var $body = $('body'); - $body.append(''); - $body.append(''); - // dummy files table - $body.append('
'); - - // prevents URL changes during tests - pushStateStub = sinon.stub(window.history, 'pushState'); - alertStub = sinon.stub(OC.dialogs, 'alert'); notificationStub = sinon.stub(OC.Notification, 'show'); // init parameters and test table elements $('#testArea').append( + '
' + + // init horrible parameters '' + '' + // dummy controls @@ -75,19 +66,24 @@ describe('FileList tests', function() { '
' + '
' + // dummy table - // TODO: at some point this will be rendered by the FileList class itself! + // TODO: at some point this will be rendered by the fileList class itself! '' + - '' + + '' + - '' + + '' + + '' + + '' + + '' + + '' + '' + '
' + - '
Empty content message
' + '
Empty content message
' + + '' ); testFiles = [{ @@ -120,27 +116,27 @@ describe('FileList tests', function() { etag: '456' }]; - FileList.initialize(); + fileList = new OCA.Files.FileList($('#app-content-files')); + FileActions.clear(); + FileActions.registerDefaultActions(fileList); + fileList.setFileActions(FileActions); }); afterEach(function() { testFiles = undefined; - FileList.initialized = false; - FileList.isEmpty = true; - delete FileList._reloadCall; + fileList = undefined; - $('#dir, #permissions, #filestable').remove(); + FileActions.clear(); notificationStub.restore(); alertStub.restore(); - pushStateStub.restore(); }); describe('Getters', function() { it('Returns the current directory', function() { $('#dir').val('/one/two/three'); - expect(FileList.getCurrentDirectory()).toEqual('/one/two/three'); + expect(fileList.getCurrentDirectory()).toEqual('/one/two/three'); }); it('Returns the directory permissions as int', function() { $('#permissions').val('23'); - expect(FileList.getDirectoryPermissions()).toEqual(23); + expect(fileList.getDirectoryPermissions()).toEqual(23); }); }); describe('Adding files', function() { @@ -158,12 +154,12 @@ describe('FileList tests', function() { id: 18, type: 'file', name: 'testName.txt', - mimetype: 'plain/text', + mimetype: 'text/plain', size: '1234', etag: 'a01234c', mtime: '123456' }; - var $tr = FileList.add(fileData); + var $tr = fileList.add(fileData); expect($tr).toBeDefined(); expect($tr[0].tagName.toLowerCase()).toEqual('tr'); @@ -173,12 +169,14 @@ describe('FileList tests', function() { expect($tr.attr('data-size')).toEqual('1234'); expect($tr.attr('data-etag')).toEqual('a01234c'); expect($tr.attr('data-permissions')).toEqual('31'); - expect($tr.attr('data-mime')).toEqual('plain/text'); + expect($tr.attr('data-mime')).toEqual('text/plain'); expect($tr.attr('data-mtime')).toEqual('123456'); - expect($tr.find('a.name').attr('href')).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=testName.txt'); + expect($tr.find('a.name').attr('href')) + .toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=testName.txt'); + expect($tr.find('.nametext').text().trim()).toEqual('testName.txt'); expect($tr.find('.filesize').text()).toEqual('1 kB'); - expect(FileList.findFileEl('testName.txt')[0]).toEqual($tr[0]); + expect(fileList.findFileEl('testName.txt')[0]).toEqual($tr[0]); }); it('generates dir element with correct attributes when calling add() with dir data', function() { var fileData = { @@ -190,7 +188,7 @@ describe('FileList tests', function() { etag: 'a01234c', mtime: '123456' }; - var $tr = FileList.add(fileData); + var $tr = fileList.add(fileData); expect($tr).toBeDefined(); expect($tr[0].tagName.toLowerCase()).toEqual('tr'); @@ -205,7 +203,7 @@ describe('FileList tests', function() { expect($tr.find('.filesize').text()).toEqual('1 kB'); - expect(FileList.findFileEl('testFolder')[0]).toEqual($tr[0]); + expect(fileList.findFileEl('testFolder')[0]).toEqual($tr[0]); }); it('generates file element with default attributes when calling add() with minimal data', function() { var fileData = { @@ -213,8 +211,8 @@ describe('FileList tests', function() { name: 'testFile.txt' }; - clock.tick(123456); - var $tr = FileList.add(fileData); + clock.tick(123456); + var $tr = fileList.add(fileData); expect($tr).toBeDefined(); expect($tr[0].tagName.toLowerCase()).toEqual('tr'); @@ -234,8 +232,8 @@ describe('FileList tests', function() { type: 'dir', name: 'testFolder' }; - clock.tick(123456); - var $tr = FileList.add(fileData); + clock.tick(123456); + var $tr = fileList.add(fileData); expect($tr).toBeDefined(); expect($tr[0].tagName.toLowerCase()).toEqual('tr'); @@ -256,7 +254,7 @@ describe('FileList tests', function() { name: 'testFolder', size: '0' }; - var $tr = FileList.add(fileData); + var $tr = fileList.add(fileData); expect($tr.find('.filesize').text()).toEqual('0 B'); }); it('adds new file to the end of the list', function() { @@ -265,19 +263,19 @@ describe('FileList tests', function() { type: 'file', name: 'ZZZ.txt' }; - FileList.setFiles(testFiles); - $tr = FileList.add(fileData); + fileList.setFiles(testFiles); + $tr = fileList.add(fileData); expect($tr.index()).toEqual(4); }); it('inserts files in a sorted manner when insert option is enabled', function() { var $tr; for (var i = 0; i < testFiles.length; i++) { - FileList.add(testFiles[i]); + fileList.add(testFiles[i]); } - expect(FileList.files[0].name).toEqual('somedir'); - expect(FileList.files[1].name).toEqual('One.txt'); - expect(FileList.files[2].name).toEqual('Three.pdf'); - expect(FileList.files[3].name).toEqual('Two.jpg'); + expect(fileList.files[0].name).toEqual('somedir'); + expect(fileList.files[1].name).toEqual('One.txt'); + expect(fileList.files[2].name).toEqual('Three.pdf'); + expect(fileList.files[3].name).toEqual('Two.jpg'); }); it('inserts new file at correct position', function() { var $tr; @@ -286,12 +284,12 @@ describe('FileList tests', function() { name: 'P comes after O.txt' }; for (var i = 0; i < testFiles.length; i++) { - FileList.add(testFiles[i]); + fileList.add(testFiles[i]); } - $tr = FileList.add(fileData); + $tr = fileList.add(fileData); // after "One.txt" expect($tr.index()).toEqual(2); - expect(FileList.files[2]).toEqual(fileData); + expect(fileList.files[2]).toEqual(fileData); }); it('inserts new folder at correct position in insert mode', function() { var $tr; @@ -300,11 +298,11 @@ describe('FileList tests', function() { name: 'somedir2 comes after somedir' }; for (var i = 0; i < testFiles.length; i++) { - FileList.add(testFiles[i]); + fileList.add(testFiles[i]); } - $tr = FileList.add(fileData); + $tr = fileList.add(fileData); expect($tr.index()).toEqual(1); - expect(FileList.files[1]).toEqual(fileData); + expect(fileList.files[1]).toEqual(fileData); }); it('inserts new file at the end correctly', function() { var $tr; @@ -313,21 +311,22 @@ describe('FileList tests', function() { name: 'zzz.txt' }; for (var i = 0; i < testFiles.length; i++) { - FileList.add(testFiles[i]); + fileList.add(testFiles[i]); } - $tr = FileList.add(fileData); + $tr = fileList.add(fileData); expect($tr.index()).toEqual(4); - expect(FileList.files[4]).toEqual(fileData); + expect(fileList.files[4]).toEqual(fileData); }); it('removes empty content message and shows summary when adding first file', function() { + var $summary; var fileData = { type: 'file', name: 'first file.txt', size: 12 }; - FileList.setFiles([]); - expect(FileList.isEmpty).toEqual(true); - FileList.add(fileData); + fileList.setFiles([]); + expect(fileList.isEmpty).toEqual(true); + fileList.add(fileData); $summary = $('#filestable .summary'); expect($summary.hasClass('hidden')).toEqual(false); // yes, ugly... @@ -337,19 +336,20 @@ describe('FileList tests', function() { expect($summary.find('.filesize').text()).toEqual('12 B'); expect($('#filestable thead th').hasClass('hidden')).toEqual(false); expect($('#emptycontent').hasClass('hidden')).toEqual(true); - expect(FileList.isEmpty).toEqual(false); + expect(fileList.isEmpty).toEqual(false); }); }); describe('Removing files from the list', function() { it('Removes file from list when calling remove() and updates summary', function() { + var $summary; var $removedEl; - FileList.setFiles(testFiles); - $removedEl = FileList.remove('One.txt'); + fileList.setFiles(testFiles); + $removedEl = fileList.remove('One.txt'); expect($removedEl).toBeDefined(); expect($removedEl.attr('data-file')).toEqual('One.txt'); expect($('#fileList tr').length).toEqual(3); - expect(FileList.files.length).toEqual(3); - expect(FileList.findFileEl('One.txt').length).toEqual(0); + expect(fileList.files.length).toEqual(3); + expect(fileList.findFileEl('One.txt').length).toEqual(0); $summary = $('#filestable .summary'); expect($summary.hasClass('hidden')).toEqual(false); @@ -357,27 +357,28 @@ describe('FileList tests', function() { expect($summary.find('.dirinfo').hasClass('hidden')).toEqual(false); expect($summary.find('.fileinfo').hasClass('hidden')).toEqual(false); expect($summary.find('.filesize').text()).toEqual('69 kB'); - expect(FileList.isEmpty).toEqual(false); + expect(fileList.isEmpty).toEqual(false); }); it('Shows empty content when removing last file', function() { - FileList.setFiles([testFiles[0]]); - FileList.remove('One.txt'); + var $summary; + fileList.setFiles([testFiles[0]]); + fileList.remove('One.txt'); expect($('#fileList tr').length).toEqual(0); - expect(FileList.files.length).toEqual(0); - expect(FileList.findFileEl('One.txt').length).toEqual(0); + expect(fileList.files.length).toEqual(0); + expect(fileList.findFileEl('One.txt').length).toEqual(0); $summary = $('#filestable .summary'); expect($summary.hasClass('hidden')).toEqual(true); expect($('#filestable thead th').hasClass('hidden')).toEqual(true); expect($('#emptycontent').hasClass('hidden')).toEqual(false); - expect(FileList.isEmpty).toEqual(true); + expect(fileList.isEmpty).toEqual(true); }); }); describe('Deleting files', function() { function doDelete() { var request, query; // note: normally called from FileActions - FileList.do_delete(['One.txt', 'Two.jpg']); + fileList.do_delete(['One.txt', 'Two.jpg']); expect(fakeServer.requests.length).toEqual(1); request = fakeServer.requests[0]; @@ -387,7 +388,8 @@ describe('FileList tests', function() { expect(OC.parseQueryString(query)).toEqual({'dir': '/subdir', files: '["One.txt","Two.jpg"]'}); } it('calls delete.php, removes the deleted entries and updates summary', function() { - FileList.setFiles(testFiles); + var $summary; + fileList.setFiles(testFiles); doDelete(); fakeServer.requests[0].respond( @@ -396,10 +398,10 @@ describe('FileList tests', function() { JSON.stringify({status: 'success'}) ); - expect(FileList.findFileEl('One.txt').length).toEqual(0); - expect(FileList.findFileEl('Two.jpg').length).toEqual(0); - expect(FileList.findFileEl('Three.pdf').length).toEqual(1); - expect(FileList.$fileList.find('tr').length).toEqual(2); + expect(fileList.findFileEl('One.txt').length).toEqual(0); + expect(fileList.findFileEl('Two.jpg').length).toEqual(0); + expect(fileList.findFileEl('Three.pdf').length).toEqual(1); + expect(fileList.$fileList.find('tr').length).toEqual(2); $summary = $('#filestable .summary'); expect($summary.hasClass('hidden')).toEqual(false); @@ -407,28 +409,29 @@ describe('FileList tests', function() { expect($summary.find('.dirinfo').hasClass('hidden')).toEqual(false); expect($summary.find('.fileinfo').hasClass('hidden')).toEqual(false); expect($summary.find('.filesize').text()).toEqual('57 kB'); - expect(FileList.isEmpty).toEqual(false); + expect(fileList.isEmpty).toEqual(false); expect($('#filestable thead th').hasClass('hidden')).toEqual(false); expect($('#emptycontent').hasClass('hidden')).toEqual(true); expect(notificationStub.notCalled).toEqual(true); }); it('shows spinner on files to be deleted', function() { - FileList.setFiles(testFiles); + fileList.setFiles(testFiles); doDelete(); - expect(FileList.findFileEl('One.txt').find('.progress-icon:not(.delete-icon)').length).toEqual(1); - expect(FileList.findFileEl('Three.pdf').find('.delete-icon:not(.progress-icon)').length).toEqual(1); + expect(fileList.findFileEl('One.txt').find('.progress-icon:not(.delete-icon)').length).toEqual(1); + expect(fileList.findFileEl('Three.pdf').find('.delete-icon:not(.progress-icon)').length).toEqual(1); }); it('shows spinner on all files when deleting all', function() { - FileList.setFiles(testFiles); + fileList.setFiles(testFiles); - FileList.do_delete(); + fileList.do_delete(); - expect(FileList.$fileList.find('tr .progress-icon:not(.delete-icon)').length).toEqual(4); + expect(fileList.$fileList.find('tr .progress-icon:not(.delete-icon)').length).toEqual(4); }); it('updates summary when deleting last file', function() { - FileList.setFiles([testFiles[0], testFiles[1]]); + var $summary; + fileList.setFiles([testFiles[0], testFiles[1]]); doDelete(); fakeServer.requests[0].respond( @@ -437,17 +440,17 @@ describe('FileList tests', function() { JSON.stringify({status: 'success'}) ); - expect(FileList.$fileList.find('tr').length).toEqual(0); + expect(fileList.$fileList.find('tr').length).toEqual(0); $summary = $('#filestable .summary'); expect($summary.hasClass('hidden')).toEqual(true); - expect(FileList.isEmpty).toEqual(true); - expect(FileList.files.length).toEqual(0); + expect(fileList.isEmpty).toEqual(true); + expect(fileList.files.length).toEqual(0); expect($('#filestable thead th').hasClass('hidden')).toEqual(true); expect($('#emptycontent').hasClass('hidden')).toEqual(false); }); it('bring back deleted item when delete call failed', function() { - FileList.setFiles(testFiles); + fileList.setFiles(testFiles); doDelete(); fakeServer.requests[0].respond( @@ -457,9 +460,9 @@ describe('FileList tests', function() { ); // files are still in the list - expect(FileList.findFileEl('One.txt').length).toEqual(1); - expect(FileList.findFileEl('Two.jpg').length).toEqual(1); - expect(FileList.$fileList.find('tr').length).toEqual(4); + expect(fileList.findFileEl('One.txt').length).toEqual(1); + expect(fileList.findFileEl('Two.jpg').length).toEqual(1); + expect(fileList.$fileList.find('tr').length).toEqual(4); expect(notificationStub.calledOnce).toEqual(true); }); @@ -469,13 +472,15 @@ describe('FileList tests', function() { var $input, request; for (var i = 0; i < testFiles.length; i++) { - FileList.add(testFiles[i]); + fileList.add(testFiles[i]); } // trigger rename prompt - FileList.rename('One.txt'); - $input = FileList.$fileList.find('input.filename'); - $input.val('Tu_after_three.txt').blur(); + fileList.rename('One.txt'); + $input = fileList.$fileList.find('input.filename'); + $input.val('Tu_after_three.txt'); + // trigger submit because triggering blur doesn't work in all browsers + $input.closest('form').trigger('submit'); expect(fakeServer.requests.length).toEqual(1); request = fakeServer.requests[0]; @@ -483,10 +488,10 @@ describe('FileList tests', function() { expect(OC.parseQueryString(request.url)).toEqual({'dir': '/subdir', newname: 'Tu_after_three.txt', file: 'One.txt'}); // element is renamed before the request finishes - expect(FileList.findFileEl('One.txt').length).toEqual(0); - expect(FileList.findFileEl('Tu_after_three.txt').length).toEqual(1); + expect(fileList.findFileEl('One.txt').length).toEqual(0); + expect(fileList.findFileEl('Tu_after_three.txt').length).toEqual(1); // input is gone - expect(FileList.$fileList.find('input.filename').length).toEqual(0); + expect(fileList.$fileList.find('input.filename').length).toEqual(0); } it('Inserts renamed file entry at correct position if rename ajax call suceeded', function() { doRename(); @@ -500,9 +505,9 @@ describe('FileList tests', function() { })); // element stays renamed - expect(FileList.findFileEl('One.txt').length).toEqual(0); - expect(FileList.findFileEl('Tu_after_three.txt').length).toEqual(1); - expect(FileList.findFileEl('Tu_after_three.txt').index()).toEqual(2); // after Two.txt + expect(fileList.findFileEl('One.txt').length).toEqual(0); + expect(fileList.findFileEl('Tu_after_three.txt').length).toEqual(1); + expect(fileList.findFileEl('Tu_after_three.txt').index()).toEqual(2); // after Two.txt expect(alertStub.notCalled).toEqual(true); }); @@ -517,9 +522,9 @@ describe('FileList tests', function() { })); // element was reverted - expect(FileList.findFileEl('One.txt').length).toEqual(1); - expect(FileList.findFileEl('One.txt').index()).toEqual(1); // after somedir - expect(FileList.findFileEl('Tu_after_three.txt').length).toEqual(0); + expect(fileList.findFileEl('One.txt').length).toEqual(1); + expect(fileList.findFileEl('One.txt').index()).toEqual(1); // after somedir + expect(fileList.findFileEl('Tu_after_three.txt').length).toEqual(0); expect(alertStub.calledOnce).toEqual(true); }); @@ -534,7 +539,7 @@ describe('FileList tests', function() { } })); - $tr = FileList.findFileEl('Tu_after_three.txt'); + $tr = fileList.findFileEl('Tu_after_three.txt'); expect($tr.find('a.name').attr('href')).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=Tu_after_three.txt'); }); // FIXME: fix this in the source code! @@ -551,17 +556,17 @@ describe('FileList tests', function() { } })); - $tr = FileList.findFileEl('Tu_after_three.txt'); + $tr = fileList.findFileEl('Tu_after_three.txt'); expect($tr.find('a.name').attr('href')).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=One.txt'); }); }); describe('Moving files', function() { beforeEach(function() { - FileList.setFiles(testFiles); + fileList.setFiles(testFiles); }); it('Moves single file to target folder', function() { var request; - FileList.move('One.txt', '/somedir'); + fileList.move('One.txt', '/somedir'); expect(fakeServer.requests.length).toEqual(1); request = fakeServer.requests[0]; @@ -576,17 +581,17 @@ describe('FileList tests', function() { } })); - expect(FileList.findFileEl('One.txt').length).toEqual(0); + expect(fileList.findFileEl('One.txt').length).toEqual(0); // folder size has increased - expect(FileList.findFileEl('somedir').data('size')).toEqual(262); - expect(FileList.findFileEl('somedir').find('.filesize').text()).toEqual('262 B'); + expect(fileList.findFileEl('somedir').data('size')).toEqual(262); + expect(fileList.findFileEl('somedir').find('.filesize').text()).toEqual('262 B'); expect(notificationStub.notCalled).toEqual(true); }); it('Moves list of files to target folder', function() { var request; - FileList.move(['One.txt', 'Two.jpg'], '/somedir'); + fileList.move(['One.txt', 'Two.jpg'], '/somedir'); expect(fakeServer.requests.length).toEqual(2); request = fakeServer.requests[0]; @@ -605,11 +610,11 @@ describe('FileList tests', function() { } })); - expect(FileList.findFileEl('One.txt').length).toEqual(0); + expect(fileList.findFileEl('One.txt').length).toEqual(0); // folder size has increased - expect(FileList.findFileEl('somedir').data('size')).toEqual(262); - expect(FileList.findFileEl('somedir').find('.filesize').text()).toEqual('262 B'); + expect(fileList.findFileEl('somedir').data('size')).toEqual(262); + expect(fileList.findFileEl('somedir').find('.filesize').text()).toEqual('262 B'); fakeServer.requests[1].respond(200, {'Content-Type': 'application/json'}, JSON.stringify({ status: 'success', @@ -619,17 +624,17 @@ describe('FileList tests', function() { } })); - expect(FileList.findFileEl('Two.jpg').length).toEqual(0); + expect(fileList.findFileEl('Two.jpg').length).toEqual(0); // folder size has increased - expect(FileList.findFileEl('somedir').data('size')).toEqual(12311); - expect(FileList.findFileEl('somedir').find('.filesize').text()).toEqual('12 kB'); + expect(fileList.findFileEl('somedir').data('size')).toEqual(12311); + expect(fileList.findFileEl('somedir').find('.filesize').text()).toEqual('12 kB'); expect(notificationStub.notCalled).toEqual(true); }); it('Shows notification if a file could not be moved', function() { var request; - FileList.move('One.txt', '/somedir'); + fileList.move('One.txt', '/somedir'); expect(fakeServer.requests.length).toEqual(1); request = fakeServer.requests[0]; @@ -643,7 +648,7 @@ describe('FileList tests', function() { } })); - expect(FileList.findFileEl('One.txt').length).toEqual(1); + expect(fileList.findFileEl('One.txt').length).toEqual(1); expect(notificationStub.calledOnce).toEqual(true); expect(notificationStub.getCall(0).args[0]).toEqual('Error while moving file'); @@ -651,47 +656,47 @@ describe('FileList tests', function() { }); describe('List rendering', function() { it('renders a list of files using add()', function() { - expect(FileList.files.length).toEqual(0); - expect(FileList.files).toEqual([]); - FileList.setFiles(testFiles); + expect(fileList.files.length).toEqual(0); + expect(fileList.files).toEqual([]); + fileList.setFiles(testFiles); expect($('#fileList tr').length).toEqual(4); - expect(FileList.files.length).toEqual(4); - expect(FileList.files).toEqual(testFiles); + expect(fileList.files.length).toEqual(4); + expect(fileList.files).toEqual(testFiles); }); it('updates summary using the file sizes', function() { var $summary; - FileList.setFiles(testFiles); + fileList.setFiles(testFiles); $summary = $('#filestable .summary'); expect($summary.hasClass('hidden')).toEqual(false); expect($summary.find('.info').text()).toEqual('1 folder and 3 files'); expect($summary.find('.filesize').text()).toEqual('69 kB'); }); it('shows headers, summary and hide empty content message after setting files', function(){ - FileList.setFiles(testFiles); + fileList.setFiles(testFiles); expect($('#filestable thead th').hasClass('hidden')).toEqual(false); expect($('#emptycontent').hasClass('hidden')).toEqual(true); - expect(FileList.$el.find('.summary').hasClass('hidden')).toEqual(false); + expect(fileList.$el.find('.summary').hasClass('hidden')).toEqual(false); }); it('hides headers, summary and show empty content message after setting empty file list', function(){ - FileList.setFiles([]); + fileList.setFiles([]); expect($('#filestable thead th').hasClass('hidden')).toEqual(true); expect($('#emptycontent').hasClass('hidden')).toEqual(false); - expect(FileList.$el.find('.summary').hasClass('hidden')).toEqual(true); + expect(fileList.$el.find('.summary').hasClass('hidden')).toEqual(true); }); it('hides headers, empty content message, and summary when list is empty and user has no creation permission', function(){ $('#permissions').val(0); - FileList.setFiles([]); + fileList.setFiles([]); expect($('#filestable thead th').hasClass('hidden')).toEqual(true); expect($('#emptycontent').hasClass('hidden')).toEqual(true); - expect(FileList.$el.find('.summary').hasClass('hidden')).toEqual(true); + expect(fileList.$el.find('.summary').hasClass('hidden')).toEqual(true); }); it('calling findFileEl() can find existing file element', function() { - FileList.setFiles(testFiles); - expect(FileList.findFileEl('Two.jpg').length).toEqual(1); + fileList.setFiles(testFiles); + expect(fileList.findFileEl('Two.jpg').length).toEqual(1); }); it('calling findFileEl() returns empty when file not found in file', function() { - FileList.setFiles(testFiles); - expect(FileList.findFileEl('unexist.dat').length).toEqual(0); + fileList.setFiles(testFiles); + expect(fileList.findFileEl('unexist.dat').length).toEqual(0); }); it('only add file if in same current directory', function() { $('#dir').val('/current dir'); @@ -700,121 +705,122 @@ describe('FileList tests', function() { name: 'testFile.txt', directory: '/current dir' }; - var $tr = FileList.add(fileData); - expect(FileList.findFileEl('testFile.txt').length).toEqual(1); + var $tr = fileList.add(fileData); + expect(fileList.findFileEl('testFile.txt').length).toEqual(1); }); it('triggers "fileActionsReady" event after update', function() { var handler = sinon.stub(); - FileList.$fileList.on('fileActionsReady', handler); - FileList.setFiles(testFiles); + fileList.$fileList.on('fileActionsReady', handler); + fileList.setFiles(testFiles); expect(handler.calledOnce).toEqual(true); }); it('triggers "updated" event after update', function() { var handler = sinon.stub(); - FileList.$fileList.on('updated', handler); - FileList.setFiles(testFiles); + fileList.$fileList.on('updated', handler); + fileList.setFiles(testFiles); expect(handler.calledOnce).toEqual(true); }); it('does not update summary when removing non-existing files', function() { + var $summary; // single file - FileList.setFiles([testFiles[0]]); + fileList.setFiles([testFiles[0]]); $summary = $('#filestable .summary'); expect($summary.hasClass('hidden')).toEqual(false); expect($summary.find('.info').text()).toEqual('0 folders and 1 file'); - FileList.remove('unexist.txt'); + fileList.remove('unexist.txt'); expect($summary.hasClass('hidden')).toEqual(false); expect($summary.find('.info').text()).toEqual('0 folders and 1 file'); }); }); describe('Rendering next page on scroll', function() { beforeEach(function() { - FileList.setFiles(generateFiles(0, 64)); + fileList.setFiles(generateFiles(0, 64)); }); it('renders only the first page', function() { - expect(FileList.files.length).toEqual(65); + expect(fileList.files.length).toEqual(65); expect($('#fileList tr').length).toEqual(20); }); it('renders the second page when scrolling down (trigger nextPage)', function() { // TODO: can't simulate scrolling here, so calling nextPage directly - FileList._nextPage(true); + fileList._nextPage(true); expect($('#fileList tr').length).toEqual(40); - FileList._nextPage(true); + fileList._nextPage(true); expect($('#fileList tr').length).toEqual(60); - FileList._nextPage(true); + fileList._nextPage(true); expect($('#fileList tr').length).toEqual(65); - FileList._nextPage(true); + fileList._nextPage(true); // stays at 65 expect($('#fileList tr').length).toEqual(65); }); it('inserts into the DOM if insertion point is in the visible page ', function() { - FileList.add({ + fileList.add({ id: 2000, type: 'file', name: 'File with index 15b.txt' }); expect($('#fileList tr').length).toEqual(21); - expect(FileList.findFileEl('File with index 15b.txt').index()).toEqual(16); + expect(fileList.findFileEl('File with index 15b.txt').index()).toEqual(16); }); it('does not inserts into the DOM if insertion point is not the visible page ', function() { - FileList.add({ + fileList.add({ id: 2000, type: 'file', name: 'File with index 28b.txt' }); expect($('#fileList tr').length).toEqual(20); - expect(FileList.findFileEl('File with index 28b.txt').length).toEqual(0); - FileList._nextPage(true); + expect(fileList.findFileEl('File with index 28b.txt').length).toEqual(0); + fileList._nextPage(true); expect($('#fileList tr').length).toEqual(40); - expect(FileList.findFileEl('File with index 28b.txt').index()).toEqual(29); + expect(fileList.findFileEl('File with index 28b.txt').index()).toEqual(29); }); it('appends into the DOM when inserting a file after the last visible element', function() { - FileList.add({ + fileList.add({ id: 2000, type: 'file', name: 'File with index 19b.txt' }); expect($('#fileList tr').length).toEqual(21); - FileList._nextPage(true); + fileList._nextPage(true); expect($('#fileList tr').length).toEqual(41); }); it('appends into the DOM when inserting a file on the last page when visible', function() { - FileList._nextPage(true); + fileList._nextPage(true); expect($('#fileList tr').length).toEqual(40); - FileList._nextPage(true); + fileList._nextPage(true); expect($('#fileList tr').length).toEqual(60); - FileList._nextPage(true); + fileList._nextPage(true); expect($('#fileList tr').length).toEqual(65); - FileList._nextPage(true); - FileList.add({ + fileList._nextPage(true); + fileList.add({ id: 2000, type: 'file', name: 'File with index 88.txt' }); expect($('#fileList tr').length).toEqual(66); - FileList._nextPage(true); + fileList._nextPage(true); expect($('#fileList tr').length).toEqual(66); }); it('shows additional page when appending a page of files and scrolling down', function() { var newFiles = generateFiles(66, 81); for (var i = 0; i < newFiles.length; i++) { - FileList.add(newFiles[i]); + fileList.add(newFiles[i]); } expect($('#fileList tr').length).toEqual(20); - FileList._nextPage(true); + fileList._nextPage(true); expect($('#fileList tr').length).toEqual(40); - FileList._nextPage(true); + fileList._nextPage(true); expect($('#fileList tr').length).toEqual(60); - FileList._nextPage(true); + fileList._nextPage(true); expect($('#fileList tr').length).toEqual(80); - FileList._nextPage(true); + fileList._nextPage(true); expect($('#fileList tr').length).toEqual(81); - FileList._nextPage(true); + fileList._nextPage(true); expect($('#fileList tr').length).toEqual(81); }); it('automatically renders next page when there are not enough elements visible', function() { // delete the 15 first elements for (var i = 0; i < 15; i++) { - FileList.remove(FileList.files[0].name); + fileList.remove(fileList.files[0].name); } // still makes sure that there are 20 elements visible, if any expect($('#fileList tr').length).toEqual(25); @@ -834,7 +840,7 @@ describe('FileList tests', function() { } beforeEach(function() { - previewLoadStub = sinon.stub(Files, 'lazyLoadPreview'); + previewLoadStub = sinon.stub(OCA.Files.FileList.prototype, 'lazyLoadPreview'); }); afterEach(function() { previewLoadStub.restore(); @@ -844,7 +850,7 @@ describe('FileList tests', function() { type: 'file', name: 'testFile.txt' }; - var $tr = FileList.add(fileData); + var $tr = fileList.add(fileData); var $td = $tr.find('td.filename'); expect(getImageUrl($td)).toEqual(OC.webroot + '/core/img/filetypes/file.svg'); expect(previewLoadStub.notCalled).toEqual(true); @@ -854,7 +860,7 @@ describe('FileList tests', function() { type: 'dir', name: 'test dir' }; - var $tr = FileList.add(fileData); + var $tr = fileList.add(fileData); var $td = $tr.find('td.filename'); expect(getImageUrl($td)).toEqual(OC.webroot + '/core/img/filetypes/folder.svg'); expect(previewLoadStub.notCalled).toEqual(true); @@ -865,7 +871,7 @@ describe('FileList tests', function() { name: 'test dir', icon: OC.webroot + '/core/img/filetypes/application-pdf.svg' }; - var $tr = FileList.add(fileData); + var $tr = fileList.add(fileData); var $td = $tr.find('td.filename'); expect(getImageUrl($td)).toEqual(OC.webroot + '/core/img/filetypes/application-pdf.svg'); expect(previewLoadStub.notCalled).toEqual(true); @@ -876,12 +882,12 @@ describe('FileList tests', function() { name: 'test dir', isPreviewAvailable: true }; - var $tr = FileList.add(fileData); + var $tr = fileList.add(fileData); var $td = $tr.find('td.filename'); expect(getImageUrl($td)).toEqual(OC.webroot + '/core/img/filetypes/file.svg'); expect(previewLoadStub.calledOnce).toEqual(true); // third argument is callback - previewLoadStub.getCall(0).args[2](OC.webroot + '/somepath.png'); + previewLoadStub.getCall(0).args[0].callback(OC.webroot + '/somepath.png'); expect(getImageUrl($td)).toEqual(OC.webroot + '/somepath.png'); }); it('renders default file type icon when no icon was provided and no preview is available', function() { @@ -890,7 +896,7 @@ describe('FileList tests', function() { name: 'test dir', isPreviewAvailable: false }; - var $tr = FileList.add(fileData); + var $tr = fileList.add(fileData); var $td = $tr.find('td.filename'); expect(getImageUrl($td)).toEqual(OC.webroot + '/core/img/filetypes/file.svg'); expect(previewLoadStub.notCalled).toEqual(true); @@ -898,26 +904,38 @@ describe('FileList tests', function() { }); describe('viewer mode', function() { it('enabling viewer mode hides files table and action buttons', function() { - FileList.setViewerMode(true); + fileList.setViewerMode(true); expect($('#filestable').hasClass('hidden')).toEqual(true); expect($('.actions').hasClass('hidden')).toEqual(true); expect($('.notCreatable').hasClass('hidden')).toEqual(true); }); it('disabling viewer mode restores files table and action buttons', function() { - FileList.setViewerMode(true); - FileList.setViewerMode(false); + fileList.setViewerMode(true); + fileList.setViewerMode(false); expect($('#filestable').hasClass('hidden')).toEqual(false); expect($('.actions').hasClass('hidden')).toEqual(false); expect($('.notCreatable').hasClass('hidden')).toEqual(true); }); it('disabling viewer mode restores files table and action buttons with correct permissions', function() { $('#permissions').val(0); - FileList.setViewerMode(true); - FileList.setViewerMode(false); + fileList.setViewerMode(true); + fileList.setViewerMode(false); expect($('#filestable').hasClass('hidden')).toEqual(false); expect($('.actions').hasClass('hidden')).toEqual(true); expect($('.notCreatable').hasClass('hidden')).toEqual(false); }); + it('toggling viewer mode triggers event', function() { + var handler = sinon.stub(); + fileList.$el.on('changeViewerMode', handler); + fileList.setViewerMode(true); + expect(handler.calledOnce).toEqual(true); + expect(handler.getCall(0).args[0].viewerModeEnabled).toEqual(true); + + handler.reset(); + fileList.setViewerMode(false); + expect(handler.calledOnce).toEqual(true); + expect(handler.getCall(0).args[0].viewerModeEnabled).toEqual(false); + }); }); describe('loading file list', function() { beforeEach(function() { @@ -936,22 +954,22 @@ describe('FileList tests', function() { ]); }); it('fetches file list from server and renders it when reload() is called', function() { - FileList.reload(); + fileList.reload(); expect(fakeServer.requests.length).toEqual(1); var url = fakeServer.requests[0].url; var query = url.substr(url.indexOf('?') + 1); - expect(OC.parseQueryString(query)).toEqual({'dir': '/subdir'}); + expect(OC.parseQueryString(query)).toEqual({'dir': '/subdir', sort: 'name', sortdirection: 'asc'}); fakeServer.respond(); expect($('#fileList tr').length).toEqual(4); - expect(FileList.findFileEl('One.txt').length).toEqual(1); + expect(fileList.findFileEl('One.txt').length).toEqual(1); }); it('switches dir and fetches file list when calling changeDirectory()', function() { - FileList.changeDirectory('/anothersubdir'); - expect(FileList.getCurrentDirectory()).toEqual('/anothersubdir'); + fileList.changeDirectory('/anothersubdir'); + expect(fileList.getCurrentDirectory()).toEqual('/anothersubdir'); expect(fakeServer.requests.length).toEqual(1); var url = fakeServer.requests[0].url; var query = url.substr(url.indexOf('?') + 1); - expect(OC.parseQueryString(query)).toEqual({'dir': '/anothersubdir'}); + expect(OC.parseQueryString(query)).toEqual({'dir': '/anothersubdir', sort: 'name', sortdirection: 'asc'}); fakeServer.respond(); }); it('switches to root dir when current directory does not exist', function() { @@ -961,14 +979,14 @@ describe('FileList tests', function() { }, '' ]); - FileList.changeDirectory('/unexist'); + fileList.changeDirectory('/unexist'); fakeServer.respond(); - expect(FileList.getCurrentDirectory()).toEqual('/'); + expect(fileList.getCurrentDirectory()).toEqual('/'); }); it('shows mask before loading file list then hides it at the end', function() { - var showMaskStub = sinon.stub(FileList, 'showMask'); - var hideMaskStub = sinon.stub(FileList, 'hideMask'); - FileList.changeDirectory('/anothersubdir'); + var showMaskStub = sinon.stub(fileList, 'showMask'); + var hideMaskStub = sinon.stub(fileList, 'hideMask'); + fileList.changeDirectory('/anothersubdir'); expect(showMaskStub.calledOnce).toEqual(true); expect(hideMaskStub.calledOnce).toEqual(false); fakeServer.respond(); @@ -977,18 +995,23 @@ describe('FileList tests', function() { showMaskStub.restore(); hideMaskStub.restore(); }); - it('changes URL to target dir', function() { - FileList.changeDirectory('/somedir'); - expect(pushStateStub.calledOnce).toEqual(true); - expect(pushStateStub.getCall(0).args[0]).toEqual({dir: '/somedir'}); - expect(pushStateStub.getCall(0).args[2]).toEqual(OC.webroot + '/index.php/apps/files?dir=/somedir'); + it('triggers "changeDirectory" event when changing directory', function() { + var handler = sinon.stub(); + $('#app-content-files').on('changeDirectory', handler); + fileList.changeDirectory('/somedir'); + expect(handler.calledOnce).toEqual(true); + expect(handler.getCall(0).args[0].dir).toEqual('/somedir'); + }); + it('changes the directory when receiving "urlChanged" event', function() { + $('#app-content-files').trigger(new $.Event('urlChanged', {view: 'files', dir: '/somedir'})); + expect(fileList.getCurrentDirectory()).toEqual('/somedir'); }); it('refreshes breadcrumb after update', function() { - var setDirSpy = sinon.spy(FileList.breadcrumb, 'setDirectory'); - FileList.changeDirectory('/anothersubdir'); + var setDirSpy = sinon.spy(fileList.breadcrumb, 'setDirectory'); + fileList.changeDirectory('/anothersubdir'); fakeServer.respond(); - expect(FileList.breadcrumb.setDirectory.calledOnce).toEqual(true); - expect(FileList.breadcrumb.setDirectory.calledWith('/anothersubdir')).toEqual(true); + expect(fileList.breadcrumb.setDirectory.calledOnce).toEqual(true); + expect(fileList.breadcrumb.setDirectory.calledWith('/anothersubdir')).toEqual(true); setDirSpy.restore(); }); }); @@ -1009,20 +1032,20 @@ describe('FileList tests', function() { ]); }); it('clicking on root breadcrumb changes directory to root', function() { - FileList.changeDirectory('/subdir/two/three with space/four/five'); + fileList.changeDirectory('/subdir/two/three with space/four/five'); fakeServer.respond(); - var changeDirStub = sinon.stub(FileList, 'changeDirectory'); - FileList.breadcrumb.$el.find('.crumb:eq(0)').click(); + var changeDirStub = sinon.stub(fileList, 'changeDirectory'); + fileList.breadcrumb.$el.find('.crumb:eq(0)').click(); expect(changeDirStub.calledOnce).toEqual(true); expect(changeDirStub.getCall(0).args[0]).toEqual('/'); changeDirStub.restore(); }); it('clicking on breadcrumb changes directory', function() { - FileList.changeDirectory('/subdir/two/three with space/four/five'); + fileList.changeDirectory('/subdir/two/three with space/four/five'); fakeServer.respond(); - var changeDirStub = sinon.stub(FileList, 'changeDirectory'); - FileList.breadcrumb.$el.find('.crumb:eq(3)').click(); + var changeDirStub = sinon.stub(fileList, 'changeDirectory'); + fileList.breadcrumb.$el.find('.crumb:eq(3)').click(); expect(changeDirStub.calledOnce).toEqual(true); expect(changeDirStub.getCall(0).args[0]).toEqual('/subdir/two/three with space'); @@ -1030,9 +1053,9 @@ describe('FileList tests', function() { }); it('dropping files on breadcrumb calls move operation', function() { var request, query, testDir = '/subdir/two/three with space/four/five'; - FileList.changeDirectory(testDir); + fileList.changeDirectory(testDir); fakeServer.respond(); - var $crumb = FileList.breadcrumb.$el.find('.crumb:eq(3)'); + var $crumb = fileList.breadcrumb.$el.find('.crumb:eq(3)'); // no idea what this is but is required by the handler var ui = { helper: { @@ -1045,7 +1068,7 @@ describe('FileList tests', function() { $('') ]); // simulate drop event - FileList._onDropOnBreadCrumb(new $.Event('drop', {target: $crumb}), ui); + fileList._onDropOnBreadCrumb(new $.Event('drop', {target: $crumb}), ui); // will trigger two calls to move.php (first one was previous list.php) expect(fakeServer.requests.length).toEqual(3); @@ -1071,10 +1094,10 @@ describe('FileList tests', function() { }); }); it('dropping files on same dir breadcrumb does nothing', function() { - var request, query, testDir = '/subdir/two/three with space/four/five'; - FileList.changeDirectory(testDir); + var testDir = '/subdir/two/three with space/four/five'; + fileList.changeDirectory(testDir); fakeServer.respond(); - var $crumb = FileList.breadcrumb.$el.find('.crumb:last'); + var $crumb = fileList.breadcrumb.$el.find('.crumb:last'); // no idea what this is but is required by the handler var ui = { helper: { @@ -1087,7 +1110,7 @@ describe('FileList tests', function() { $('') ]); // simulate drop event - FileList._onDropOnBreadCrumb(new $.Event('drop', {target: $crumb}), ui); + fileList._onDropOnBreadCrumb(new $.Event('drop', {target: $crumb}), ui); // no extra server request expect(fakeServer.requests.length).toEqual(1); @@ -1095,32 +1118,32 @@ describe('FileList tests', function() { }); describe('Download Url', function() { it('returns correct download URL for single files', function() { - expect(Files.getDownloadUrl('some file.txt')).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=some%20file.txt'); - expect(Files.getDownloadUrl('some file.txt', '/anotherpath/abc')).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fanotherpath%2Fabc&files=some%20file.txt'); + expect(fileList.getDownloadUrl('some file.txt')).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=some%20file.txt'); + expect(fileList.getDownloadUrl('some file.txt', '/anotherpath/abc')).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fanotherpath%2Fabc&files=some%20file.txt'); $('#dir').val('/'); - expect(Files.getDownloadUrl('some file.txt')).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2F&files=some%20file.txt'); + expect(fileList.getDownloadUrl('some file.txt')).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2F&files=some%20file.txt'); }); it('returns correct download URL for multiple files', function() { - expect(Files.getDownloadUrl(['a b c.txt', 'd e f.txt'])).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=%5B%22a%20b%20c.txt%22%2C%22d%20e%20f.txt%22%5D'); + expect(fileList.getDownloadUrl(['a b c.txt', 'd e f.txt'])).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=%5B%22a%20b%20c.txt%22%2C%22d%20e%20f.txt%22%5D'); }); it('returns the correct ajax URL', function() { - expect(Files.getAjaxUrl('test', {a:1, b:'x y'})).toEqual(OC.webroot + '/index.php/apps/files/ajax/test.php?a=1&b=x%20y'); + expect(fileList.getAjaxUrl('test', {a:1, b:'x y'})).toEqual(OC.webroot + '/index.php/apps/files/ajax/test.php?a=1&b=x%20y'); }); }); describe('File selection', function() { beforeEach(function() { - FileList.setFiles(testFiles); + fileList.setFiles(testFiles); }); it('Selects a file when clicking its checkbox', function() { - var $tr = FileList.findFileEl('One.txt'); + var $tr = fileList.findFileEl('One.txt'); expect($tr.find('input:checkbox').prop('checked')).toEqual(false); $tr.find('td.filename input:checkbox').click(); expect($tr.find('input:checkbox').prop('checked')).toEqual(true); }); it('Selects/deselect a file when clicking on the name while holding Ctrl', function() { - var $tr = FileList.findFileEl('One.txt'); - var $tr2 = FileList.findFileEl('Three.pdf'); + var $tr = fileList.findFileEl('One.txt'); + var $tr2 = fileList.findFileEl('Three.pdf'); var e; expect($tr.find('input:checkbox').prop('checked')).toEqual(false); expect($tr2.find('input:checkbox').prop('checked')).toEqual(false); @@ -1138,7 +1161,7 @@ describe('FileList tests', function() { expect($tr.find('input:checkbox').prop('checked')).toEqual(true); expect($tr2.find('input:checkbox').prop('checked')).toEqual(true); - expect(_.pluck(FileList.getSelectedFiles(), 'name')).toEqual(['One.txt', 'Three.pdf']); + expect(_.pluck(fileList.getSelectedFiles(), 'name')).toEqual(['One.txt', 'Three.pdf']); // deselect now e = new $.Event('click'); @@ -1146,11 +1169,11 @@ describe('FileList tests', function() { $tr2.find('td.filename .name').trigger(e); expect($tr.find('input:checkbox').prop('checked')).toEqual(true); expect($tr2.find('input:checkbox').prop('checked')).toEqual(false); - expect(_.pluck(FileList.getSelectedFiles(), 'name')).toEqual(['One.txt']); + expect(_.pluck(fileList.getSelectedFiles(), 'name')).toEqual(['One.txt']); }); it('Selects a range when clicking on one file then Shift clicking on another one', function() { - var $tr = FileList.findFileEl('One.txt'); - var $tr2 = FileList.findFileEl('Three.pdf'); + var $tr = fileList.findFileEl('One.txt'); + var $tr2 = fileList.findFileEl('Three.pdf'); var e; $tr.find('td.filename input:checkbox').click(); e = new $.Event('click'); @@ -1159,16 +1182,16 @@ describe('FileList tests', function() { expect($tr.find('input:checkbox').prop('checked')).toEqual(true); expect($tr2.find('input:checkbox').prop('checked')).toEqual(true); - expect(FileList.findFileEl('Two.jpg').find('input:checkbox').prop('checked')).toEqual(true); - var selection = _.pluck(FileList.getSelectedFiles(), 'name'); + expect(fileList.findFileEl('Two.jpg').find('input:checkbox').prop('checked')).toEqual(true); + var selection = _.pluck(fileList.getSelectedFiles(), 'name'); expect(selection.length).toEqual(3); expect(selection).toContain('One.txt'); expect(selection).toContain('Two.jpg'); expect(selection).toContain('Three.pdf'); }); it('Selects a range when clicking on one file then Shift clicking on another one that is above the first one', function() { - var $tr = FileList.findFileEl('One.txt'); - var $tr2 = FileList.findFileEl('Three.pdf'); + var $tr = fileList.findFileEl('One.txt'); + var $tr2 = fileList.findFileEl('Three.pdf'); var e; $tr2.find('td.filename input:checkbox').click(); e = new $.Event('click'); @@ -1177,104 +1200,104 @@ describe('FileList tests', function() { expect($tr.find('input:checkbox').prop('checked')).toEqual(true); expect($tr2.find('input:checkbox').prop('checked')).toEqual(true); - expect(FileList.findFileEl('Two.jpg').find('input:checkbox').prop('checked')).toEqual(true); - var selection = _.pluck(FileList.getSelectedFiles(), 'name'); + expect(fileList.findFileEl('Two.jpg').find('input:checkbox').prop('checked')).toEqual(true); + var selection = _.pluck(fileList.getSelectedFiles(), 'name'); expect(selection.length).toEqual(3); expect(selection).toContain('One.txt'); expect(selection).toContain('Two.jpg'); expect(selection).toContain('Three.pdf'); }); it('Selecting all files will automatically check "select all" checkbox', function() { - expect($('#select_all').prop('checked')).toEqual(false); + expect($('.select-all').prop('checked')).toEqual(false); $('#fileList tr td.filename input:checkbox').click(); - expect($('#select_all').prop('checked')).toEqual(true); + expect($('.select-all').prop('checked')).toEqual(true); }); it('Selecting all files on the first visible page will not automatically check "select all" checkbox', function() { - FileList.setFiles(generateFiles(0, 41)); - expect($('#select_all').prop('checked')).toEqual(false); + fileList.setFiles(generateFiles(0, 41)); + expect($('.select-all').prop('checked')).toEqual(false); $('#fileList tr td.filename input:checkbox').click(); - expect($('#select_all').prop('checked')).toEqual(false); + expect($('.select-all').prop('checked')).toEqual(false); }); it('Clicking "select all" will select/deselect all files', function() { - FileList.setFiles(generateFiles(0, 41)); - $('#select_all').click(); - expect($('#select_all').prop('checked')).toEqual(true); + fileList.setFiles(generateFiles(0, 41)); + $('.select-all').click(); + expect($('.select-all').prop('checked')).toEqual(true); $('#fileList tr input:checkbox').each(function() { expect($(this).prop('checked')).toEqual(true); }); - expect(_.pluck(FileList.getSelectedFiles(), 'name').length).toEqual(42); + expect(_.pluck(fileList.getSelectedFiles(), 'name').length).toEqual(42); - $('#select_all').click(); - expect($('#select_all').prop('checked')).toEqual(false); + $('.select-all').click(); + expect($('.select-all').prop('checked')).toEqual(false); $('#fileList tr input:checkbox').each(function() { expect($(this).prop('checked')).toEqual(false); }); - expect(_.pluck(FileList.getSelectedFiles(), 'name').length).toEqual(0); + expect(_.pluck(fileList.getSelectedFiles(), 'name').length).toEqual(0); }); it('Clicking "select all" then deselecting a file will uncheck "select all"', function() { - $('#select_all').click(); - expect($('#select_all').prop('checked')).toEqual(true); + $('.select-all').click(); + expect($('.select-all').prop('checked')).toEqual(true); - var $tr = FileList.findFileEl('One.txt'); + var $tr = fileList.findFileEl('One.txt'); $tr.find('input:checkbox').click(); - expect($('#select_all').prop('checked')).toEqual(false); - expect(_.pluck(FileList.getSelectedFiles(), 'name').length).toEqual(3); + expect($('.select-all').prop('checked')).toEqual(false); + expect(_.pluck(fileList.getSelectedFiles(), 'name').length).toEqual(3); }); it('Updates the selection summary when doing a few manipulations with "Select all"', function() { - $('#select_all').click(); - expect($('#select_all').prop('checked')).toEqual(true); + $('.select-all').click(); + expect($('.select-all').prop('checked')).toEqual(true); - var $tr = FileList.findFileEl('One.txt'); + var $tr = fileList.findFileEl('One.txt'); // unselect one $tr.find('input:checkbox').click(); - expect($('#select_all').prop('checked')).toEqual(false); - expect(_.pluck(FileList.getSelectedFiles(), 'name').length).toEqual(3); + expect($('.select-all').prop('checked')).toEqual(false); + expect(_.pluck(fileList.getSelectedFiles(), 'name').length).toEqual(3); // select all - $('#select_all').click(); - expect($('#select_all').prop('checked')).toEqual(true); - expect(_.pluck(FileList.getSelectedFiles(), 'name').length).toEqual(4); + $('.select-all').click(); + expect($('.select-all').prop('checked')).toEqual(true); + expect(_.pluck(fileList.getSelectedFiles(), 'name').length).toEqual(4); // unselect one $tr.find('input:checkbox').click(); - expect($('#select_all').prop('checked')).toEqual(false); - expect(_.pluck(FileList.getSelectedFiles(), 'name').length).toEqual(3); + expect($('.select-all').prop('checked')).toEqual(false); + expect(_.pluck(fileList.getSelectedFiles(), 'name').length).toEqual(3); // re-select it $tr.find('input:checkbox').click(); - expect($('#select_all').prop('checked')).toEqual(true); - expect(_.pluck(FileList.getSelectedFiles(), 'name').length).toEqual(4); + expect($('.select-all').prop('checked')).toEqual(true); + expect(_.pluck(fileList.getSelectedFiles(), 'name').length).toEqual(4); }); it('Auto-selects files on next page when "select all" is checked', function() { - FileList.setFiles(generateFiles(0, 41)); - $('#select_all').click(); + fileList.setFiles(generateFiles(0, 41)); + $('.select-all').click(); - expect(FileList.$fileList.find('tr input:checkbox:checked').length).toEqual(20); - FileList._nextPage(true); - expect(FileList.$fileList.find('tr input:checkbox:checked').length).toEqual(40); - FileList._nextPage(true); - expect(FileList.$fileList.find('tr input:checkbox:checked').length).toEqual(42); - expect(_.pluck(FileList.getSelectedFiles(), 'name').length).toEqual(42); + expect(fileList.$fileList.find('tr input:checkbox:checked').length).toEqual(20); + fileList._nextPage(true); + expect(fileList.$fileList.find('tr input:checkbox:checked').length).toEqual(40); + fileList._nextPage(true); + expect(fileList.$fileList.find('tr input:checkbox:checked').length).toEqual(42); + expect(_.pluck(fileList.getSelectedFiles(), 'name').length).toEqual(42); }); it('Selecting files updates selection summary', function() { - var $summary = $('#headerName span.name'); + var $summary = $('#headerName a.name>span:first'); expect($summary.text()).toEqual('Name'); - FileList.findFileEl('One.txt').find('input:checkbox').click(); - FileList.findFileEl('Three.pdf').find('input:checkbox').click(); - FileList.findFileEl('somedir').find('input:checkbox').click(); + fileList.findFileEl('One.txt').find('input:checkbox').click(); + fileList.findFileEl('Three.pdf').find('input:checkbox').click(); + fileList.findFileEl('somedir').find('input:checkbox').click(); expect($summary.text()).toEqual('1 folder & 2 files'); }); it('Unselecting files hides selection summary', function() { - var $summary = $('#headerName span.name'); - FileList.findFileEl('One.txt').find('input:checkbox').click().click(); + var $summary = $('#headerName a.name>span:first'); + fileList.findFileEl('One.txt').find('input:checkbox').click().click(); expect($summary.text()).toEqual('Name'); }); it('Select/deselect files shows/hides file actions', function() { var $actions = $('#headerName .selectedActions'); - var $checkbox = FileList.findFileEl('One.txt').find('input:checkbox'); + var $checkbox = fileList.findFileEl('One.txt').find('input:checkbox'); expect($actions.hasClass('hidden')).toEqual(true); $checkbox.click(); expect($actions.hasClass('hidden')).toEqual(false); @@ -1282,7 +1305,7 @@ describe('FileList tests', function() { expect($actions.hasClass('hidden')).toEqual(true); }); it('Selection is cleared when switching dirs', function() { - $('#select_all').click(); + $('.select-all').click(); var data = { status: 'success', data: { @@ -1296,31 +1319,43 @@ describe('FileList tests', function() { }, JSON.stringify(data) ]); - FileList.changeDirectory('/'); + fileList.changeDirectory('/'); fakeServer.respond(); - expect($('#select_all').prop('checked')).toEqual(false); - expect(_.pluck(FileList.getSelectedFiles(), 'name')).toEqual([]); + expect($('.select-all').prop('checked')).toEqual(false); + expect(_.pluck(fileList.getSelectedFiles(), 'name')).toEqual([]); }); it('getSelectedFiles returns the selected files even when they are on the next page', function() { var selectedFiles; - FileList.setFiles(generateFiles(0, 41)); - $('#select_all').click(); + fileList.setFiles(generateFiles(0, 41)); + $('.select-all').click(); // unselect one to not have the "allFiles" case - FileList.$fileList.find('tr input:checkbox:first').click(); + fileList.$fileList.find('tr input:checkbox:first').click(); // only 20 files visible, must still return all the selected ones - selectedFiles = _.pluck(FileList.getSelectedFiles(), 'name'); + selectedFiles = _.pluck(fileList.getSelectedFiles(), 'name'); expect(selectedFiles.length).toEqual(41); }); + describe('Selection overlay', function() { + it('show delete action according to directory permissions', function() { + fileList.setFiles(testFiles); + $('#permissions').val(OC.PERMISSION_READ | OC.PERMISSION_DELETE); + $('.select-all').click(); + expect(fileList.$el.find('.delete-selected').hasClass('hidden')).toEqual(false); + $('.select-all').click(); + $('#permissions').val(OC.PERMISSION_READ); + $('.select-all').click(); + expect(fileList.$el.find('.delete-selected').hasClass('hidden')).toEqual(true); + }); + }); describe('Actions', function() { beforeEach(function() { - FileList.findFileEl('One.txt').find('input:checkbox').click(); - FileList.findFileEl('Three.pdf').find('input:checkbox').click(); - FileList.findFileEl('somedir').find('input:checkbox').click(); + fileList.findFileEl('One.txt').find('input:checkbox').click(); + fileList.findFileEl('Three.pdf').find('input:checkbox').click(); + fileList.findFileEl('somedir').find('input:checkbox').click(); }); it('getSelectedFiles returns the selected file data', function() { - var files = FileList.getSelectedFiles(); + var files = fileList.getSelectedFiles(); expect(files.length).toEqual(3); expect(files[0]).toEqual({ id: 1, @@ -1348,8 +1383,8 @@ describe('FileList tests', function() { }); }); it('Removing a file removes it from the selection', function() { - FileList.remove('Three.pdf'); - var files = FileList.getSelectedFiles(); + fileList.remove('Three.pdf'); + var files = fileList.getSelectedFiles(); expect(files.length).toEqual(2); expect(files[0]).toEqual({ id: 1, @@ -1378,7 +1413,7 @@ describe('FileList tests', function() { }); it('Downloads root folder when all selected in root folder', function() { $('#dir').val('/'); - $('#select_all').click(); + $('.select-all').click(); var redirectStub = sinon.stub(OC, 'redirect'); $('.selectedActions .download').click(); expect(redirectStub.calledOnce).toEqual(true); @@ -1386,7 +1421,7 @@ describe('FileList tests', function() { redirectStub.restore(); }); it('Downloads parent folder when all selected in subfolder', function() { - $('#select_all').click(); + $('.select-all').click(); var redirectStub = sinon.stub(OC, 'redirect'); $('.selectedActions .download').click(); expect(redirectStub.calledOnce).toEqual(true); @@ -1408,14 +1443,14 @@ describe('FileList tests', function() { { 'Content-Type': 'application/json' }, JSON.stringify({status: 'success'}) ); - expect(FileList.findFileEl('One.txt').length).toEqual(0); - expect(FileList.findFileEl('Three.pdf').length).toEqual(0); - expect(FileList.findFileEl('somedir').length).toEqual(0); - expect(FileList.findFileEl('Two.jpg').length).toEqual(1); + expect(fileList.findFileEl('One.txt').length).toEqual(0); + expect(fileList.findFileEl('Three.pdf').length).toEqual(0); + expect(fileList.findFileEl('somedir').length).toEqual(0); + expect(fileList.findFileEl('Two.jpg').length).toEqual(1); }); it('Deletes all files when all selected when "Delete" clicked', function() { var request; - $('#select_all').click(); + $('.select-all').click(); $('.selectedActions .delete-selected').click(); expect(fakeServer.requests.length).toEqual(1); request = fakeServer.requests[0]; @@ -1427,9 +1462,154 @@ describe('FileList tests', function() { { 'Content-Type': 'application/json' }, JSON.stringify({status: 'success'}) ); - expect(FileList.isEmpty).toEqual(true); + expect(fileList.isEmpty).toEqual(true); }); }); }); + it('resets the file selection on reload', function() { + fileList.$el.find('.select-all').click(); + fileList.reload(); + expect(fileList.$el.find('.select-all').prop('checked')).toEqual(false); + expect(fileList.getSelectedFiles()).toEqual([]); + }); + }); + describe('Sorting files', function() { + it('Sorts by name by default', function() { + fileList.reload(); + expect(fakeServer.requests.length).toEqual(1); + var url = fakeServer.requests[0].url; + var query = OC.parseQueryString(url.substr(url.indexOf('?') + 1)); + expect(query.sort).toEqual('name'); + expect(query.sortdirection).toEqual('asc'); + }); + it('Reloads file list with a different sort when clicking on column header of unsorted column', function() { + fileList.$el.find('.column-size .columntitle').click(); + expect(fakeServer.requests.length).toEqual(1); + var url = fakeServer.requests[0].url; + var query = OC.parseQueryString(url.substr(url.indexOf('?') + 1)); + expect(query.sort).toEqual('size'); + expect(query.sortdirection).toEqual('asc'); + }); + it('Toggles sort direction when clicking on already sorted column', function() { + fileList.$el.find('.column-name .columntitle').click(); + expect(fakeServer.requests.length).toEqual(1); + var url = fakeServer.requests[0].url; + var query = OC.parseQueryString(url.substr(url.indexOf('?') + 1)); + expect(query.sort).toEqual('name'); + expect(query.sortdirection).toEqual('desc'); + }); + it('Toggles the sort indicator when clicking on a column header', function() { + var ASC_CLASS = fileList.SORT_INDICATOR_ASC_CLASS; + var DESC_CLASS = fileList.SORT_INDICATOR_DESC_CLASS; + fileList.$el.find('.column-size .columntitle').click(); + // moves triangle to size column + expect( + fileList.$el.find('.column-name .sort-indicator').hasClass(ASC_CLASS + ' ' + DESC_CLASS) + ).toEqual(false); + expect( + fileList.$el.find('.column-size .sort-indicator').hasClass(ASC_CLASS) + ).toEqual(true); + + // click again on size column, reverses direction + fileList.$el.find('.column-size .columntitle').click(); + expect( + fileList.$el.find('.column-size .sort-indicator').hasClass(DESC_CLASS) + ).toEqual(true); + + // click again on size column, reverses direction + fileList.$el.find('.column-size .columntitle').click(); + expect( + fileList.$el.find('.column-size .sort-indicator').hasClass(ASC_CLASS) + ).toEqual(true); + + // click on mtime column, moves indicator there + fileList.$el.find('.column-mtime .columntitle').click(); + expect( + fileList.$el.find('.column-size .sort-indicator').hasClass(ASC_CLASS + ' ' + DESC_CLASS) + ).toEqual(false); + expect( + fileList.$el.find('.column-mtime .sort-indicator').hasClass(ASC_CLASS) + ).toEqual(true); + }); + it('Uses correct sort comparator when inserting files', function() { + testFiles.sort(OCA.Files.FileList.Comparators.size); + // this will make it reload the testFiles with the correct sorting + fileList.$el.find('.column-size .columntitle').click(); + expect(fakeServer.requests.length).toEqual(1); + fakeServer.requests[0].respond( + 200, + { 'Content-Type': 'application/json' }, + JSON.stringify({ + status: 'success', + data: { + files: testFiles, + permissions: 31 + } + }) + ); + var newFileData = { + id: 999, + type: 'file', + name: 'new file.txt', + mimetype: 'text/plain', + size: 40001, + etag: '999' + }; + fileList.add(newFileData); + expect(fileList.files.length).toEqual(5); + expect(fileList.$fileList.find('tr').length).toEqual(5); + expect(fileList.findFileEl('One.txt').index()).toEqual(0); + expect(fileList.findFileEl('somedir').index()).toEqual(1); + expect(fileList.findFileEl('Two.jpg').index()).toEqual(2); + expect(fileList.findFileEl('new file.txt').index()).toEqual(3); + expect(fileList.findFileEl('Three.pdf').index()).toEqual(4); + }); + it('Uses correct reversed sort comparator when inserting files', function() { + testFiles.sort(OCA.Files.FileList.Comparators.size); + testFiles.reverse(); + // this will make it reload the testFiles with the correct sorting + fileList.$el.find('.column-size .columntitle').click(); + expect(fakeServer.requests.length).toEqual(1); + fakeServer.requests[0].respond( + 200, + { 'Content-Type': 'application/json' }, + JSON.stringify({ + status: 'success', + data: { + files: testFiles, + permissions: 31 + } + }) + ); + // reverse sort + fileList.$el.find('.column-size .columntitle').click(); + fakeServer.requests[1].respond( + 200, + { 'Content-Type': 'application/json' }, + JSON.stringify({ + status: 'success', + data: { + files: testFiles, + permissions: 31 + } + }) + ); + var newFileData = { + id: 999, + type: 'file', + name: 'new file.txt', + mimetype: 'text/plain', + size: 40001, + etag: '999' + }; + fileList.add(newFileData); + expect(fileList.files.length).toEqual(5); + expect(fileList.$fileList.find('tr').length).toEqual(5); + expect(fileList.findFileEl('One.txt').index()).toEqual(4); + expect(fileList.findFileEl('somedir').index()).toEqual(3); + expect(fileList.findFileEl('Two.jpg').index()).toEqual(2); + expect(fileList.findFileEl('new file.txt').index()).toEqual(1); + expect(fileList.findFileEl('Three.pdf').index()).toEqual(0); + }); }); }); diff --git a/apps/files/tests/js/filesSpec.js b/apps/files/tests/js/filesSpec.js index 7f8848619f500c57b795439783d3d29237a3a689..4f8d5a29318ee97776c7ef880d9053a0d08e472c 100644 --- a/apps/files/tests/js/filesSpec.js +++ b/apps/files/tests/js/filesSpec.js @@ -19,8 +19,9 @@ * */ -/* global OC, Files */ -describe('Files tests', function() { +describe('OCA.Files.Files tests', function() { + var Files = OCA.Files.Files; + describe('File name validation', function() { it('Validates correct file names', function() { var fileNames = [ @@ -83,18 +84,6 @@ describe('Files tests', function() { }); }); describe('getDownloadUrl', function() { - var curDirStub; - beforeEach(function() { - curDirStub = sinon.stub(FileList, 'getCurrentDirectory'); - }); - afterEach(function() { - curDirStub.restore(); - }); - it('returns the ajax download URL when only filename specified', function() { - curDirStub.returns('/subdir'); - var url = Files.getDownloadUrl('test file.txt'); - expect(url).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=test%20file.txt'); - }); it('returns the ajax download URL when filename and dir specified', function() { var url = Files.getDownloadUrl('test file.txt', '/subdir'); expect(url).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=test%20file.txt'); diff --git a/apps/files/tests/js/filesummarySpec.js b/apps/files/tests/js/filesummarySpec.js index c493700de3801d2d361092bdec90d8519c6c413e..5e39dd1d23282374a7cb396f4cf1655b3ee842f3 100644 --- a/apps/files/tests/js/filesummarySpec.js +++ b/apps/files/tests/js/filesummarySpec.js @@ -20,7 +20,8 @@ */ /* global FileSummary */ -describe('FileSummary tests', function() { +describe('OCA.Files.FileSummary tests', function() { + var FileSummary = OCA.Files.FileSummary; var $container; beforeEach(function() { diff --git a/apps/files/triggerupdate.php b/apps/files/triggerupdate.php index a37b9823add43ac72061790d987a9ec7610c8ab8..3f85da9913b04b1cd3d8955a508091d42caf991f 100644 --- a/apps/files/triggerupdate.php +++ b/apps/files/triggerupdate.php @@ -6,7 +6,7 @@ if (OC::$CLI) { if (count($argv) === 2) { $file = $argv[1]; list(, $user) = explode('/', $file); - OCP\JSON::checkUserExists($owner); + OCP\JSON::checkUserExists($user); OC_Util::setupFS($user); $view = new \OC\Files\View(''); /** diff --git a/apps/files_encryption/ajax/adminrecovery.php b/apps/files_encryption/ajax/adminrecovery.php index 61e43acc2c33141401c53df32649988705242727..303ba0e16e12dd9b71aa49ee163e8aaa99f0ddad 100644 --- a/apps/files_encryption/ajax/adminrecovery.php +++ b/apps/files_encryption/ajax/adminrecovery.php @@ -5,7 +5,7 @@ * This file is licensed under the Affero General Public License version 3 or later. * See the COPYING-README file. * - * @brief Script to handle admin settings for encrypted key recovery + * Script to handle admin settings for encrypted key recovery */ use OCA\Encryption; diff --git a/apps/files_encryption/ajax/changeRecoveryPassword.php b/apps/files_encryption/ajax/changeRecoveryPassword.php index 945f054ea844832c41de2ef90c9fe6e9b1535f91..0cb010d3b566be84dd1d9fae6a03b0786aef6587 100644 --- a/apps/files_encryption/ajax/changeRecoveryPassword.php +++ b/apps/files_encryption/ajax/changeRecoveryPassword.php @@ -5,7 +5,7 @@ * This file is licensed under the Affero General Public License version 3 or later. * See the COPYING-README file. * - * @brief Script to change recovery key password + * Script to change recovery key password * */ @@ -23,7 +23,7 @@ $oldPassword = $_POST['oldPassword']; $newPassword = $_POST['newPassword']; $view = new \OC\Files\View('/'); -$util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), \OCP\User::getUser()); +$util = new \OCA\Encryption\Util(new \OC\Files\View('/'), \OCP\User::getUser()); $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; diff --git a/apps/files_encryption/ajax/getMigrationStatus.php b/apps/files_encryption/ajax/getMigrationStatus.php index 7c9e0dcc51c51d7ecc54bfda8879b806da44be09..adceb949044efafab7fb346775924c841d9168f7 100644 --- a/apps/files_encryption/ajax/getMigrationStatus.php +++ b/apps/files_encryption/ajax/getMigrationStatus.php @@ -4,7 +4,7 @@ * This file is licensed under the Affero General Public License version 3 or later. * See the COPYING-README file. * - * @brief check migration status + * check migration status */ use OCA\Encryption\Util; @@ -18,7 +18,7 @@ $migrationStatus = Util::MIGRATION_COMPLETED; if ($loginname !== '' && $password !== '') { $username = \OCP\User::checkPassword($loginname, $password); if ($username) { - $util = new Util(new \OC_FilesystemView('/'), $username); + $util = new Util(new \OC\Files\View('/'), $username); $migrationStatus = $util->getMigrationStatus(); } } diff --git a/apps/files_encryption/ajax/updatePrivateKeyPassword.php b/apps/files_encryption/ajax/updatePrivateKeyPassword.php index 29c72952ae9de4457cc5d63340c4caef9658615f..f7d20c486cf41f200652b1e4fbfe5abae81ce0a9 100644 --- a/apps/files_encryption/ajax/updatePrivateKeyPassword.php +++ b/apps/files_encryption/ajax/updatePrivateKeyPassword.php @@ -5,7 +5,7 @@ * This file is licensed under the Affero General Public License version 3 or later. * See the COPYING-README file. * - * @brief Script to change recovery key password + * Script to change recovery key password * */ diff --git a/apps/files_encryption/ajax/userrecovery.php b/apps/files_encryption/ajax/userrecovery.php index d6c94bde81e5501981f13a084982d00b7932c515..0f3b973d69ab8be1938a0fcff07833f957b22b35 100644 --- a/apps/files_encryption/ajax/userrecovery.php +++ b/apps/files_encryption/ajax/userrecovery.php @@ -4,7 +4,7 @@ * This file is licensed under the Affero General Public License version 3 or later. * See the COPYING-README file. * - * @brief Script to handle admin settings for encrypted key recovery + * Script to handle admin settings for encrypted key recovery */ use OCA\Encryption; @@ -19,7 +19,7 @@ if ( ) { $userId = \OCP\USER::getUser(); - $view = new \OC_FilesystemView('/'); + $view = new \OC\Files\View('/'); $util = new \OCA\Encryption\Util($view, $userId); // Save recovery preference to DB diff --git a/apps/files_encryption/appinfo/app.php b/apps/files_encryption/appinfo/app.php index 21de421c1956efebd98a391bbf3db4dd6cc36aba..104e8568caa62f022f865f36b3e6bca25d749904 100644 --- a/apps/files_encryption/appinfo/app.php +++ b/apps/files_encryption/appinfo/app.php @@ -40,7 +40,7 @@ if (!OC_Config::getValue('maintenance', false)) { \OC_Util::setupFS(); } - $view = new OC_FilesystemView('/'); + $view = new OC\Files\View('/'); $sessionReady = OCA\Encryption\Helper::checkRequirements(); if($sessionReady) { diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index 5f0494e62ca38361e2b0b39c42b2218fef5b5536..c1ccb927df582224fe9fa92e94c75b68b7b3ca5f 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -36,7 +36,7 @@ class Hooks { private static $deleteFiles = array(); /** - * @brief Startup encryption backend upon user login + * Startup encryption backend upon user login * @note This method should never be called for users using client side encryption */ public static function login($params) { @@ -48,7 +48,7 @@ class Hooks { $l = new \OC_L10N('files_encryption'); - $view = new \OC_FilesystemView('/'); + $view = new \OC\Files\View('/'); // ensure filesystem is loaded if(!\OC\Files\Filesystem::$loaded) { @@ -93,7 +93,7 @@ class Hooks { // If migration not yet done if ($ready) { - $userView = new \OC_FilesystemView('/' . $params['uid']); + $userView = new \OC\Files\View('/' . $params['uid']); // Set legacy encryption key if it exists, to support // depreciated encryption system @@ -136,26 +136,26 @@ class Hooks { } /** - * @brief setup encryption backend upon user created + * setup encryption backend upon user created * @note This method should never be called for users using client side encryption */ public static function postCreateUser($params) { if (\OCP\App::isEnabled('files_encryption')) { - $view = new \OC_FilesystemView('/'); + $view = new \OC\Files\View('/'); $util = new Util($view, $params['uid']); Helper::setupUser($util, $params['password']); } } /** - * @brief cleanup encryption backend upon user deleted + * cleanup encryption backend upon user deleted * @note This method should never be called for users using client side encryption */ public static function postDeleteUser($params) { if (\OCP\App::isEnabled('files_encryption')) { - $view = new \OC_FilesystemView('/'); + $view = new \OC\Files\View('/'); // cleanup public key $publicKey = '/public-keys/' . $params['uid'] . '.public.key'; @@ -171,7 +171,7 @@ class Hooks { } /** - * @brief If the password can't be changed within ownCloud, than update the key password in advance. + * If the password can't be changed within ownCloud, than update the key password in advance. */ public static function preSetPassphrase($params) { if (\OCP\App::isEnabled('files_encryption')) { @@ -182,7 +182,7 @@ class Hooks { } /** - * @brief Change a user's encryption passphrase + * Change a user's encryption passphrase * @param array $params keys: uid, password */ public static function setPassphrase($params) { @@ -196,7 +196,7 @@ class Hooks { // the necessary keys) if (Crypt::mode() === 'server') { - $view = new \OC_FilesystemView('/'); + $view = new \OC\Files\View('/'); if ($params['uid'] === \OCP\User::getUser()) { @@ -259,10 +259,10 @@ class Hooks { } /* - * @brief check if files can be encrypted to every user. + * check if files can be encrypted to every user. */ /** - * @param $params + * @param array $params */ public static function preShared($params) { @@ -308,7 +308,7 @@ class Hooks { if ($params['itemType'] === 'file' || $params['itemType'] === 'folder') { - $view = new \OC_FilesystemView('/'); + $view = new \OC\Files\View('/'); $session = new \OCA\Encryption\Session($view); $userId = \OCP\User::getUser(); $util = new Util($view, $userId); @@ -350,7 +350,7 @@ class Hooks { if ($params['itemType'] === 'file' || $params['itemType'] === 'folder') { - $view = new \OC_FilesystemView('/'); + $view = new \OC\Files\View('/'); $userId = \OCP\User::getUser(); $util = new Util($view, $userId); $path = \OC\Files\Filesystem::getPath($params['fileSource']); @@ -398,12 +398,12 @@ class Hooks { } /** - * @brief mark file as renamed so that we know the original source after the file was renamed + * mark file as renamed so that we know the original source after the file was renamed * @param array $params with the old path and the new path */ public static function preRename($params) { $user = \OCP\User::getUser(); - $view = new \OC_FilesystemView('/'); + $view = new \OC\Files\View('/'); $util = new Util($view, $user); list($ownerOld, $pathOld) = $util->getUidAndFilename($params['oldpath']); @@ -421,8 +421,8 @@ class Hooks { } /** - * @brief after a file is renamed, rename its keyfile and share-keys also fix the file size and fix also the sharing - * @param array with oldpath and newpath + * after a file is renamed, rename its keyfile and share-keys also fix the file size and fix also the sharing + * @param array $params array with oldpath and newpath * * This function is connected to the rename signal of OC_Filesystem and adjust the name and location * of the stored versions along the actual file @@ -437,7 +437,7 @@ class Hooks { $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; - $view = new \OC_FilesystemView('/'); + $view = new \OC\Files\View('/'); $session = new \OCA\Encryption\Session($view); $userId = \OCP\User::getUser(); $util = new Util($view, $userId); @@ -557,7 +557,7 @@ class Hooks { } /** - * @brief if the file was really deleted we remove the encryption keys + * if the file was really deleted we remove the encryption keys * @param array $params * @return boolean|null */ @@ -597,7 +597,7 @@ class Hooks { } /** - * @brief remember the file which should be deleted and it's owner + * remember the file which should be deleted and it's owner * @param array $params * @return boolean|null */ @@ -610,7 +610,7 @@ class Hooks { return true; } - $util = new Util(new \OC_FilesystemView('/'), \OCP\USER::getUser()); + $util = new Util(new \OC\Files\View('/'), \OCP\USER::getUser()); list($owner, $ownerPath) = $util->getUidAndFilename($path); self::$deleteFiles[$params[\OC\Files\Filesystem::signal_param_path]] = array( diff --git a/apps/files_encryption/l10n/ast.php b/apps/files_encryption/l10n/ast.php index 7e08e073095487247c93f3b6da960ee610c49b57..8b51ec775db5521af73d9795ed614c4f9a42b510 100644 --- a/apps/files_encryption/l10n/ast.php +++ b/apps/files_encryption/l10n/ast.php @@ -1,13 +1,44 @@ "Contraseña camudada esitosamente.", -"Could not change the password. Maybe the old password was not correct." => "Nun pue camudase la contraseña. Quiciabes la contraseña vieya nun fore correuta.", -"personal settings" => "axustes personales", +"Recovery key successfully enabled" => "Habilitóse la recuperación de ficheros", +"Could not enable recovery key. Please check your recovery key password!" => "Nun pudo habilitase la clave de recuperación. Por favor comprueba la contraseña.", +"Recovery key successfully disabled" => "Clave de recuperación deshabilitada", +"Could not disable recovery key. Please check your recovery key password!" => "Nun pudo deshabilitase la clave de recuperación. Por favor comprueba la contraseña!", +"Password successfully changed." => "Camudóse la contraseña", +"Could not change the password. Maybe the old password was not correct." => "Nun pudo camudase la contraseña. Comprueba que la contraseña actual seya correuta.", +"Private key password successfully updated." => "Contraseña de clave privada anovada correchamente.", +"Could not update the private key password. Maybe the old password was not correct." => "Nun pudo camudase la contraseña. Pue que la contraseña antigua nun seya correuta.", +"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "¡L'aplicación de cifráu nun s'anició! Seique se restableciera mentanto la sesión. Por favor intenta zarrar la sesión y volver a aniciala p'aniciar l'aplicación de cifráu.", +"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "¡La clave privada nun ye válida! Seique la contraseña se camudase dende fuera de %s (Ex:El to direutoriu corporativu). Pues anovar la contraseña de la clave privada nes tos opciones personales pa recuperar l'accesu a los ficheros.", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Nun pudo descifrase esti ficheru, dablemente seya un ficheru compartíu. Solicita al propietariu del mesmu que vuelva a compartilu contigo.", +"Unknown error please check your system settings or contact your administrator" => "Fallu desconocíu. Verifica la configuración del sistema o ponte en contautu col alministrador", +"Missing requirements." => "Requisitos incompletos.", +"Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Por favor, asegúrate de que PHP 5.3.3 o postreru ta instaláu y que la estensión OpenSSL de PHP ta habilitada y configurada correutamente. Pel momentu, l'aplicación de cifráu deshabilitóse.", +"Following users are not set up for encryption:" => "Los siguientes usuarios nun se configuraron pal cifráu:", +"Initial encryption started... This can take some time. Please wait." => "Cifráu aniciáu..... Esto pue llevar un tiempu. Por favor espera.", +"Initial encryption running... Please try again later." => "Cifráu inicial en cursu... Inténtalo dempués.", +"Go directly to your " => "Dir direutamente a", +"personal settings" => "opciones personales", "Encryption" => "Cifráu", -"Enabled" => "Habilitáu", +"Enable recovery key (allow to recover users files in case of password loss):" => "Habilitar la clave de recuperación (permite recuperar los ficheros del usuariu en casu de perda de la contraseña);", +"Recovery key password" => "Contraseña de clave de recuperación", +"Repeat Recovery key password" => "Repeti la contraseña de clave de recuperación", +"Enabled" => "Habilitar", "Disabled" => "Deshabilitáu", -"Change Password" => "Camudar conseña", -" If you don't remember your old password you can ask your administrator to recover your files." => "Si nun recuerdes la to contraseña vieya pues entrugar al to alministrador pa recuperar los tos ficheros.", -"Could not update file recovery" => "Nun pue anovase'l ficheru de recuperación" +"Change recovery key password:" => "Camudar la contraseña de la clave de recuperación", +"Old Recovery key password" => "Clave de recuperación vieya", +"New Recovery key password" => "Clave de recuperación nueva", +"Repeat New Recovery key password" => "Repetir la clave de recuperación nueva", +"Change Password" => "Camudar contraseña", +"Your private key password no longer match your log-in password:" => "La to contraseña de clave privada yá nun concasa cola contraseña d'accesu:", +"Set your old private key password to your current log-in password." => "Afitar la contraseña de la to clave privada vieya a la to contraseña actual d'accesu.", +" If you don't remember your old password you can ask your administrator to recover your files." => "Si nun recuerdes la contraseña vieya, pues pidir a alministrador que te recupere los ficheros.", +"Old log-in password" => "Contraseña d'accesu vieya", +"Current log-in password" => "Contraseña d'accesu actual", +"Update Private Key Password" => "Anovar Contraseña de Clave Privada", +"Enable password recovery:" => "Habilitar la recuperación de contraseña:", +"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Habilitar esta opción va permitite volver a tener accesu a los ficheros cifraos en casu de perda de contraseña", +"File recovery settings updated" => "Opciones de recuperación de ficheros anovada", +"Could not update file recovery" => "Nun pudo anovase la recuperación de ficheros" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_encryption/l10n/fa.php b/apps/files_encryption/l10n/fa.php index 3f8d631e1067a885bceb3ab039c04eb5decae9b6..420fd7423f8448b09f356a505341b778963bb1be 100644 --- a/apps/files_encryption/l10n/fa.php +++ b/apps/files_encryption/l10n/fa.php @@ -9,6 +9,7 @@ $TRANSLATIONS = array( "Private key password successfully updated." => "رمزعبور کلید خصوصی با موفقیت به روز شد.", "Could not update the private key password. Maybe the old password was not correct." => "رمزعبور کلید خصوصی را نمی تواند به روز کند. شاید رمزعبور قدیمی صحیح نمی باشد.", "Missing requirements." => "نیازمندی های گمشده", +"Following users are not set up for encryption:" => "کاربران زیر برای رمزنگاری تنظیم نشده اند", "personal settings" => "تنظیمات شخصی", "Encryption" => "رمزگذاری", "Enable recovery key (allow to recover users files in case of password loss):" => "فعال کردن کلید بازیابی(اجازه بازیابی فایل های کاربران در صورت از دست دادن رمزعبور):", diff --git a/apps/files_encryption/l10n/pt_PT.php b/apps/files_encryption/l10n/pt_PT.php index 9a1963953e3427e2b07dd7c6afb60b19c11c9bc0..409f1917a4794033fb1f017962cbd9a9339dbaec 100644 --- a/apps/files_encryption/l10n/pt_PT.php +++ b/apps/files_encryption/l10n/pt_PT.php @@ -10,17 +10,21 @@ $TRANSLATIONS = array( "Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Não foi possível desencriptar este ficheiro, possivelmente é um ficheiro partilhado. Peça ao proprietário do ficheiro para voltar a partilhar o ficheiro consigo.", "Unknown error please check your system settings or contact your administrator" => "Erro desconhecido. Verifique por favor as definições do sistema ou contacte o seu administrador", "Missing requirements." => "Faltam alguns requisitos.", +"Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Por favor, certifique-se que PHP 5.3.3 ou mais recente está instalado e que OpenSSL juntamente com a extensão PHP está ativada e corretamente configurada. Por agora, a aplicação de encriptação está desactivada.", "Following users are not set up for encryption:" => "Os utilizadores seguintes não estão marcados para cifragem:", +"Initial encryption started... This can take some time. Please wait." => "A encriptação inicial começou... Pode demorar algum tempo. Aguarde, por favor.", "Go directly to your " => "Ir directamente para o seu", "personal settings" => "configurações personalizadas ", "Encryption" => "Encriptação", "Enable recovery key (allow to recover users files in case of password loss):" => "Active a chave de recuperação (permite recuperar os ficheiros no caso de perda da password):", "Recovery key password" => "Chave de recuperação da conta", +"Repeat Recovery key password" => "Repetir a chave de recuperação da conta", "Enabled" => "Activado", "Disabled" => "Desactivado", "Change recovery key password:" => "Alterar a chave de recuperação:", "Old Recovery key password" => "Chave anterior de recuperação da conta", "New Recovery key password" => "Nova chave de recuperação da conta", +"Repeat New Recovery key password" => "Repetir a nova chave de recuperação da conta", "Change Password" => "Mudar a Password", "Old log-in password" => "Password anterior da conta", "Current log-in password" => "Password actual da conta", diff --git a/apps/files_encryption/l10n/tr.php b/apps/files_encryption/l10n/tr.php index 85e35f5dddf93ad177c59f3132ac8d0899913d42..ba87330c480e5490a58676d80906b20d343391cb 100644 --- a/apps/files_encryption/l10n/tr.php +++ b/apps/files_encryption/l10n/tr.php @@ -9,7 +9,7 @@ $TRANSLATIONS = array( "Private key password successfully updated." => "Gizli anahtar parolası başarıyla güncellendi", "Could not update the private key password. Maybe the old password was not correct." => "Gizli anahtar parolası güncellenemedi. Eski parola hatalı olabilir.", "Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "Şifreleme uygulaması başlatılamadı! Oturumunuz sırasında şifreleme uygulaması tekrar etkinleştirilmiş olabilir. Lütfen şifreleme uygulamasını başlatmak için oturumu kapatıp yeniden oturum açmayı deneyin.", -"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Gizli anahtarınız geçerli değil! Muhtemelen parolanız ownCloud sistemi %s dışarısında değiştirildi (örn. şirket dizininde). Gizli anahtar parolanızı kişisel ayarlarınızda güncelleyerek şifreli dosyalarınıza erişimi kurtarabilirsiniz.", +"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Gizli anahtarınız geçerli değil! Muhtemelen parolanız %s dışarısında değiştirildi (örn. şirket dizininde). Gizli anahtar parolanızı kişisel ayarlarınızda güncelleyerek şifreli dosyalarınıza erişimi kurtarabilirsiniz.", "Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Bu dosya muhtemelen bir paylaşılan dosya olduğundan şifresi çözülemiyor. Lütfen dosyayı sizinle bir daha paylaşması için dosya sahibi ile iletişime geçin.", "Unknown error please check your system settings or contact your administrator" => "Bilinmeyen hata. Lütfen sistem ayarlarınızı denetleyin veya yöneticiniz ile iletişime geçin", "Missing requirements." => "Gereklilikler eksik.", diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index a4f7bd35497543c000c43358b0118a6c482ef6e6..ec7b3bc92e47c20994769c97804cb4232a9914dc 100755 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -40,7 +40,7 @@ class Crypt { /** - * @brief return encryption mode client or server side encryption + * return encryption mode client or server side encryption * @param string $user name (use system wide setting if name=null) * @return string 'client' or 'server' */ @@ -51,7 +51,7 @@ class Crypt { } /** - * @brief Create a new encryption keypair + * Create a new encryption keypair * @return array publicKey, privatekey */ public static function createKeypair() { @@ -85,7 +85,7 @@ class Crypt { } /** - * @brief Add arbitrary padding to encrypted data + * Add arbitrary padding to encrypted data * @param string $data data to be padded * @return string padded data * @note In order to end up with data exactly 8192 bytes long we must @@ -102,7 +102,7 @@ class Crypt { } /** - * @brief Remove arbitrary padding to encrypted data + * Remove arbitrary padding to encrypted data * @param string $padded padded data to remove padding from * @return string unpadded data on success, false on error */ @@ -124,8 +124,8 @@ class Crypt { } /** - * @brief Check if a file's contents contains an IV and is symmetrically encrypted - * @param $content + * Check if a file's contents contains an IV and is symmetrically encrypted + * @param string $content * @return boolean * @note see also OCA\Encryption\Util->isEncryptedPath() */ @@ -178,11 +178,10 @@ class Crypt { } /** - * @brief Check if a file is encrypted via legacy system - * @param $data + * Check if a file is encrypted via legacy system + * @param boolean $isCatFileContent * @param string $relPath The path of the file, relative to user/data; * e.g. filename or /Docs/filename, NOT admin/files/filename - * @param boolean $isCatFileContent * @return boolean */ public static function isLegacyEncryptedContent($isCatFileContent, $relPath) { @@ -209,7 +208,7 @@ class Crypt { } /** - * @brief Symmetrically encrypt a string + * Symmetrically encrypt a string * @param string $plainContent * @param string $iv * @param string $passphrase @@ -229,7 +228,7 @@ class Crypt { } /** - * @brief Symmetrically decrypt a string + * Symmetrically decrypt a string * @param string $encryptedContent * @param string $iv * @param string $passphrase @@ -251,10 +250,10 @@ class Crypt { } /** - * @brief Concatenate encrypted data with its IV and padding + * Concatenate encrypted data with its IV and padding * @param string $content content to be concatenated * @param string $iv IV to be concatenated - * @returns string concatenated content + * @return string concatenated content */ private static function concatIv($content, $iv) { @@ -265,9 +264,9 @@ class Crypt { } /** - * @brief Split concatenated data and IV into respective parts + * Split concatenated data and IV into respective parts * @param string $catFile concatenated data to be split - * @returns array keys: encrypted, iv + * @return array keys: encrypted, iv */ private static function splitIv($catFile) { @@ -290,7 +289,7 @@ class Crypt { } /** - * @brief Symmetrically encrypts a string and returns keyfile content + * Symmetrically encrypts a string and returns keyfile content * @param string $plainContent content to be encrypted in keyfile * @param string $passphrase * @return false|string encrypted content combined with IV @@ -322,15 +321,15 @@ class Crypt { /** - * @brief Symmetrically decrypts keyfile content - * @param $keyfileContent + * Symmetrically decrypts keyfile content + * @param string $keyfileContent * @param string $passphrase * @throws \Exception * @return string|false * @internal param string $source * @internal param string $target * @internal param string $key the decryption key - * @returns string decrypted content + * @return string decrypted content * * This function decrypts a file */ @@ -359,10 +358,10 @@ class Crypt { } /** - * @brief Decrypt private key and check if the result is a valid keyfile + * Decrypt private key and check if the result is a valid keyfile * @param string $encryptedKey encrypted keyfile * @param string $passphrase to decrypt keyfile - * @returns encrypted private key or false + * @return string|false encrypted private key or false * * This function decrypts a file */ @@ -386,10 +385,10 @@ class Crypt { } /** - * @brief Create asymmetrically encrypted keyfile content using a generated key + * Create asymmetrically encrypted keyfile content using a generated key * @param string $plainContent content to be encrypted * @param array $publicKeys array keys must be the userId of corresponding user - * @returns array keys: keys (array, key = userId), data + * @return array keys: keys (array, key = userId), data * @note symmetricDecryptFileContent() can decrypt files created using this method */ public static function multiKeyEncrypt($plainContent, array $publicKeys) { @@ -434,13 +433,13 @@ class Crypt { } /** - * @brief Asymmetrically encrypt a file using multiple public keys - * @param $encryptedContent - * @param $shareKey - * @param $privateKey + * Asymmetrically encrypt a file using multiple public keys + * @param string $encryptedContent + * @param string $shareKey + * @param mixed $privateKey * @return false|string * @internal param string $plainContent content to be encrypted - * @returns string $plainContent decrypted string + * @return string $plainContent decrypted string * @note symmetricDecryptFileContent() can be used to decrypt files created using this method * * This function decrypts a file @@ -468,7 +467,7 @@ class Crypt { } /** - * @brief Generates a pseudo random initialisation vector + * Generates a pseudo random initialisation vector * @return String $iv generated IV */ private static function generateIv() { @@ -497,8 +496,8 @@ class Crypt { } /** - * @brief Generate a pseudo random 256-bit ASCII key, used as file key - * @returns $key Generated key + * Generate a pseudo random 256-bit ASCII key, used as file key + * @return string|false Generated key */ public static function generateKey() { @@ -523,8 +522,8 @@ class Crypt { } /** - * @brief Get the blowfish encryption handler for a key - * @param $key string (optional) + * Get the blowfish encryption handler for a key + * @param string $key (optional) * @return \Crypt_Blowfish blowfish object * * if the key is left out, the default handler will be used @@ -544,7 +543,7 @@ class Crypt { } /** - * @brief decrypts content using legacy blowfish system + * decrypts content using legacy blowfish system * @param string $content the cleartext message you want to decrypt * @param string $passphrase * @return string cleartext content @@ -561,7 +560,7 @@ class Crypt { } /** - * @param $data + * @param string $data * @param string $key * @param int $maxLength * @return string diff --git a/apps/files_encryption/lib/helper.php b/apps/files_encryption/lib/helper.php index 8cbbe8a45a6ef62f638a675414d392f486887ba4..564e97e0592765dcea1878b25dd45e6b66d65837 100755 --- a/apps/files_encryption/lib/helper.php +++ b/apps/files_encryption/lib/helper.php @@ -24,7 +24,7 @@ namespace OCA\Encryption; /** - * @brief Class to manage registration of hooks an various helper methods + * Class to manage registration of hooks an various helper methods * @package OCA\Encryption */ class Helper { @@ -32,7 +32,7 @@ class Helper { private static $tmpFileMapping; // Map tmp files to files in data/user/files /** - * @brief register share related hooks + * register share related hooks * */ public static function registerShareHooks() { @@ -43,7 +43,7 @@ class Helper { } /** - * @brief register user related hooks + * register user related hooks * */ public static function registerUserHooks() { @@ -56,7 +56,7 @@ class Helper { } /** - * @brief register filesystem related hooks + * register filesystem related hooks * */ public static function registerFilesystemHooks() { @@ -68,7 +68,7 @@ class Helper { } /** - * @brief register app management related hooks + * register app management related hooks * */ public static function registerAppHooks() { @@ -78,7 +78,7 @@ class Helper { } /** - * @brief setup user for files_encryption + * setup user for files_encryption * * @param Util $util * @param string $password @@ -100,9 +100,9 @@ class Helper { } /** - * @brief enable recovery + * enable recovery * - * @param $recoveryKeyId + * @param string $recoveryKeyId * @param string $recoveryPassword * @internal param \OCA\Encryption\Util $util * @internal param string $password @@ -153,7 +153,7 @@ class Helper { $return = true; } else { // get recovery key and check the password - $util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), \OCP\User::getUser()); + $util = new \OCA\Encryption\Util(new \OC\Files\View('/'), \OCP\User::getUser()); $return = $util->checkRecoveryPassword($recoveryPassword); if ($return) { $appConfig->setValue('files_encryption', 'recoveryAdminEnabled', 1); @@ -164,7 +164,7 @@ class Helper { } /** - * @brief Check if a path is a .part file + * Check if a path is a .part file * @param string $path Path that may identify a .part file * @return bool */ @@ -181,7 +181,7 @@ class Helper { /** - * @brief Remove .path extension from a file path + * Remove .path extension from a file path * @param string $path Path that may identify a .part file * @return string File path without .part extension * @note this is needed for reusing keys @@ -208,13 +208,13 @@ class Helper { } /** - * @brief disable recovery + * disable recovery * * @param string $recoveryPassword * @return bool */ public static function adminDisableRecovery($recoveryPassword) { - $util = new Util(new \OC_FilesystemView('/'), \OCP\User::getUser()); + $util = new Util(new \OC\Files\View('/'), \OCP\User::getUser()); $return = $util->checkRecoveryPassword($recoveryPassword); if ($return) { @@ -227,7 +227,7 @@ class Helper { /** - * @brief checks if access is public/anonymous user + * checks if access is public/anonymous user * @return bool */ public static function isPublicAccess() { @@ -239,7 +239,7 @@ class Helper { } /** - * @brief Format a path to be relative to the /user/files/ directory + * Format a path to be relative to the /user/files/ directory * @param string $path the absolute path * @return string e.g. turns '/admin/files/test.txt' into 'test.txt' */ @@ -259,7 +259,7 @@ class Helper { } /** - * @brief try to get the user from the path if no user is logged in + * try to get the user from the path if no user is logged in * @param string $path * @return mixed user or false if we couldn't determine a user */ @@ -294,7 +294,7 @@ class Helper { } /** - * @brief get path to the corresponding file in data/user/files if path points + * get path to the corresponding file in data/user/files if path points * to a version or to a file in cache * @param string $path path to a version or a file in the trash * @return string path to corresponding file relative to data/user/files @@ -327,12 +327,12 @@ class Helper { } /** - * @brief create directory recursively + * create directory recursively * @param string $path * @param \OC\Files\View $view */ public static function mkdirr($path, $view) { - $dirname = \OC_Filesystem::normalizePath(dirname($path)); + $dirname = \OC\Files\Filesystem::normalizePath(dirname($path)); $dirParts = explode('/', $dirname); $dir = ""; foreach ($dirParts as $part) { @@ -344,7 +344,7 @@ class Helper { } /** - * @brief redirect to a error page + * redirect to a error page * @param Session $session */ public static function redirectToErrorPage($session, $errorCode = null) { @@ -428,7 +428,7 @@ class Helper { } /** - * @brief glob uses different pattern than regular expressions, escape glob pattern only + * glob uses different pattern than regular expressions, escape glob pattern only * @param string $path unescaped path * @return string path */ @@ -437,7 +437,7 @@ class Helper { } /** - * @brief remember from which file the tmp file (getLocalFile() call) was created + * remember from which file the tmp file (getLocalFile() call) was created * @param string $tmpFile path of tmp file * @param string $originalFile path of the original file relative to data/ */ @@ -446,7 +446,7 @@ class Helper { } /** - * @brief get the path of the original file + * get the path of the original file * @param string $tmpFile path of the tmp file * @return string|false path of the original file or false */ diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index cb9f5e64af37aa3e54f64a0b18ddfa959a61fbc9..3c51c5efba20759d6ceab8fbb157528aedbc2d81 100755 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -24,20 +24,20 @@ namespace OCA\Encryption; /** - * @brief Class to manage storage and retrieval of encryption keys + * Class to manage storage and retrieval of encryption keys * @note Where a method requires a view object, it's root must be '/' */ class Keymanager { /** - * @brief retrieve the ENCRYPTED private key from a user + * retrieve the ENCRYPTED private key from a user * - * @param \OC_FilesystemView $view + * @param \OC\Files\View $view * @param string $user * @return string private key or false (hopefully) * @note the key returned by this method must be decrypted before use */ - public static function getPrivateKey(\OC_FilesystemView $view, $user) { + public static function getPrivateKey(\OC\Files\View $view, $user) { $path = '/' . $user . '/' . 'files_encryption' . '/' . $user . '.private.key'; $key = false; @@ -55,12 +55,12 @@ class Keymanager { } /** - * @brief retrieve public key for a specified user - * @param \OC_FilesystemView $view - * @param $userId + * retrieve public key for a specified user + * @param \OC\Files\View $view + * @param string $userId * @return string public key or false */ - public static function getPublicKey(\OC_FilesystemView $view, $userId) { + public static function getPublicKey(\OC\Files\View $view, $userId) { $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; @@ -74,12 +74,12 @@ class Keymanager { } /** - * @brief Retrieve a user's public and private key - * @param \OC_FilesystemView $view - * @param $userId + * Retrieve a user's public and private key + * @param \OC\Files\View $view + * @param string $userId * @return array keys: privateKey, publicKey */ - public static function getUserKeys(\OC_FilesystemView $view, $userId) { + public static function getUserKeys(\OC\Files\View $view, $userId) { return array( 'publicKey' => self::getPublicKey($view, $userId), @@ -89,12 +89,12 @@ class Keymanager { } /** - * @brief Retrieve public keys for given users - * @param \OC_FilesystemView $view + * Retrieve public keys for given users + * @param \OC\Files\View $view * @param array $userIds * @return array of public keys for the specified users */ - public static function getPublicKeys(\OC_FilesystemView $view, array $userIds) { + public static function getPublicKeys(\OC\Files\View $view, array $userIds) { $keys = array(); @@ -109,9 +109,9 @@ class Keymanager { } /** - * @brief store file encryption key + * store file encryption key * - * @param \OC_FilesystemView $view + * @param \OC\Files\View $view * @param \OCA\Encryption\Util $util * @param string $path relative path of the file, including filename * @param string $catfile keyfile content @@ -119,7 +119,7 @@ class Keymanager { * @note The keyfile is not encrypted here. Client code must * asymmetrically encrypt the keyfile before passing it to this method */ - public static function setFileKey(\OC_FilesystemView $view, $util, $path, $catfile) { + public static function setFileKey(\OC\Files\View $view, $util, $path, $catfile) { $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; @@ -167,8 +167,8 @@ class Keymanager { } /** - * @brief retrieve keyfile for an encrypted file - * @param \OC_FilesystemView $view + * retrieve keyfile for an encrypted file + * @param \OC\Files\View $view * @param \OCA\Encryption\Util $util * @param string|false $filePath * @internal param \OCA\Encryption\file $string name @@ -210,9 +210,9 @@ class Keymanager { } /** - * @brief Delete a keyfile + * Delete a keyfile * - * @param \OC_FilesystemView $view + * @param \OC\Files\View $view * @param string $path path of the file the key belongs to * @param string $userId the user to whom the file belongs * @return bool Outcome of unlink operation @@ -266,7 +266,7 @@ class Keymanager { } /** - * @brief store private key from the user + * store private key from the user * @param string $key * @return bool * @note Encryption of the private key must be performed by client code @@ -276,7 +276,7 @@ class Keymanager { $user = \OCP\User::getUser(); - $view = new \OC_FilesystemView('/' . $user . '/files_encryption'); + $view = new \OC\Files\View('/' . $user . '/files_encryption'); $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; @@ -293,16 +293,16 @@ class Keymanager { } /** - * @brief store share key + * store share key * - * @param \OC_FilesystemView $view + * @param \OC\Files\View $view * @param string $path where the share key is stored - * @param $shareKey + * @param string $shareKey * @return bool true/false * @note The keyfile is not encrypted here. Client code must * asymmetrically encrypt the keyfile before passing it to this method */ - private static function setShareKey(\OC_FilesystemView $view, $path, $shareKey) { + private static function setShareKey(\OC\Files\View $view, $path, $shareKey) { $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; @@ -319,14 +319,14 @@ class Keymanager { } /** - * @brief store multiple share keys for a single file - * @param \OC_FilesystemView $view + * store multiple share keys for a single file + * @param \OC\Files\View $view * @param \OCA\Encryption\Util $util * @param string $path * @param array $shareKeys * @return bool */ - public static function setShareKeys(\OC_FilesystemView $view, $util, $path, array $shareKeys) { + public static function setShareKeys(\OC\Files\View $view, $util, $path, array $shareKeys) { // $shareKeys must be an array with the following format: // [userId] => [encrypted key] @@ -365,8 +365,8 @@ class Keymanager { } /** - * @brief retrieve shareKey for an encrypted file - * @param \OC_FilesystemView $view + * retrieve shareKey for an encrypted file + * @param \OC\Files\View $view * @param string $userId * @param \OCA\Encryption\Util $util * @param string $filePath @@ -374,7 +374,7 @@ class Keymanager { * @note The sharekey returned is encrypted. Decryption * of the keyfile must be performed by client code */ - public static function getShareKey(\OC_FilesystemView $view, $userId, $util, $filePath) { + public static function getShareKey(\OC\Files\View $view, $userId, $util, $filePath) { // try reusing key file if part file $proxyStatus = \OC_FileProxy::$enabled; @@ -406,8 +406,8 @@ class Keymanager { } /** - * @brief delete all share keys of a given file - * @param \OC_FilesystemView $view + * delete all share keys of a given file + * @param \OC\Files\View $view * @param string $userId owner of the file * @param string $filePath path to the file, relative to the owners file dir */ @@ -445,9 +445,9 @@ class Keymanager { } /** - * @brief Delete a single user's shareKey for a single file + * Delete a single user's shareKey for a single file */ - public static function delShareKey(\OC_FilesystemView $view, $userIds, $filePath) { + public static function delShareKey(\OC\Files\View $view, $userIds, $filePath) { $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; @@ -486,7 +486,7 @@ class Keymanager { } /** - * @brief recursively delete share keys from given users + * recursively delete share keys from given users * * @param string $dir directory * @param array $userIds user ids for which the share keys should be deleted @@ -512,11 +512,11 @@ class Keymanager { } /** - * @brief Make preparations to vars and filesystem for saving a keyfile + * Make preparations to vars and filesystem for saving a keyfile * @param string|boolean $path * @param string $basePath */ - public static function keySetPreparation(\OC_FilesystemView $view, $path, $basePath, $userId) { + public static function keySetPreparation(\OC\Files\View $view, $path, $basePath, $userId) { $targetPath = ltrim($path, '/'); @@ -542,7 +542,7 @@ class Keymanager { } /** - * @brief extract filename from share key name + * extract filename from share key name * @param string $shareKey (filename.userid.sharekey) * @return string|false filename or false */ diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index 7be82c313e494805129809658341399777f74d13..ae3df834e9f417394a65f732b0338c4a736b5a57 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -24,7 +24,7 @@ */ /** - * @brief Encryption proxy which handles filesystem operations before and after + * Encryption proxy which handles filesystem operations before and after * execution and encrypts, and handles keyfiles accordingly. Used for * webui. */ @@ -65,7 +65,7 @@ class Proxy extends \OC_FileProxy { return false; } - $view = new \OC_FilesystemView(''); + $view = new \OC\Files\View(''); $util = new Util($view, $userId); // for write operation we always encrypt the files, for read operations @@ -79,8 +79,8 @@ class Proxy extends \OC_FileProxy { } /** - * @param $path - * @param $data + * @param string $path + * @param string $data * @return bool */ public function preFile_put_contents($path, &$data) { @@ -90,7 +90,7 @@ class Proxy extends \OC_FileProxy { if (!is_resource($data)) { // get root view - $view = new \OC_FilesystemView('/'); + $view = new \OC\Files\View('/'); // get relative path $relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path); @@ -101,7 +101,7 @@ class Proxy extends \OC_FileProxy { // create random cache folder $cacheFolder = rand(); - $path_slices = explode('/', \OC_Filesystem::normalizePath($path)); + $path_slices = explode('/', \OC\Files\Filesystem::normalizePath($path)); $path_slices[2] = "cache/".$cacheFolder; $tmpPath = implode('/', $path_slices); @@ -125,7 +125,7 @@ class Proxy extends \OC_FileProxy { // in the post proxy $tmpFileInfo = $view->getFileInfo($tmpPath); if ( isset($tmpFileInfo['size']) ) { - self::$unencryptedSizes[\OC_Filesystem::normalizePath($path)] = $tmpFileInfo['size']; + self::$unencryptedSizes[\OC\Files\Filesystem::normalizePath($path)] = $tmpFileInfo['size']; } // remove our temp file @@ -144,15 +144,15 @@ class Proxy extends \OC_FileProxy { } /** - * @brief update file cache with the new unencrypted size after file was written + * update file cache with the new unencrypted size after file was written * @param string $path * @param mixed $result * @return mixed */ public function postFile_put_contents($path, $result) { - $normalizedPath = \OC_Filesystem::normalizePath($path); + $normalizedPath = \OC\Files\Filesystem::normalizePath($path); if ( isset(self::$unencryptedSizes[$normalizedPath]) ) { - $view = new \OC_FilesystemView('/'); + $view = new \OC\Files\View('/'); $view->putFileInfo($normalizedPath, array('encrypted' => true, 'unencrypted_size' => self::$unencryptedSizes[$normalizedPath])); unset(self::$unencryptedSizes[$normalizedPath]); @@ -168,7 +168,7 @@ class Proxy extends \OC_FileProxy { public function postFile_get_contents($path, $data) { $plainData = null; - $view = new \OC_FilesystemView('/'); + $view = new \OC\Files\View('/'); // init session $session = new \OCA\Encryption\Session($view); @@ -212,7 +212,7 @@ class Proxy extends \OC_FileProxy { } /** - * @brief remember initial fopen mode because sometimes it gets changed during the request + * remember initial fopen mode because sometimes it gets changed during the request * @param string $path path * @param string $mode type of access */ @@ -225,8 +225,8 @@ class Proxy extends \OC_FileProxy { /** - * @param $path - * @param $result + * @param string $path + * @param resource $result * @return resource */ public function postFopen($path, &$result) { @@ -261,8 +261,8 @@ class Proxy extends \OC_FileProxy { } /** - * @param $path - * @param $data + * @param string $path + * @param array $data * @return array */ public function postGetFileInfo($path, $data) { @@ -285,13 +285,13 @@ class Proxy extends \OC_FileProxy { } /** - * @param $path - * @param $size - * @return bool + * @param string $path + * @param int $size + * @return int|bool */ public function postFileSize($path, $size) { - $view = new \OC_FilesystemView('/'); + $view = new \OC\Files\View('/'); $userId = Helper::getUser($path); $util = new Util($view, $userId); diff --git a/apps/files_encryption/lib/session.php b/apps/files_encryption/lib/session.php index 3daaa06425faf30dcbb5b65c7a6334780bb75f06..93be6691f96bbc0d0e6db2db632f7b8a1357782a 100644 --- a/apps/files_encryption/lib/session.php +++ b/apps/files_encryption/lib/session.php @@ -36,8 +36,8 @@ class Session { /** - * @brief if session is started, check if ownCloud key pair is set up, if not create it - * @param \OC_FilesystemView $view + * if session is started, check if ownCloud key pair is set up, if not create it + * @param \OC\Files\View $view * * @note The ownCloud key pair is used to allow public link sharing even if encryption is enabled */ @@ -105,7 +105,7 @@ class Session { } /** - * @brief Sets user private key to session + * Sets user private key to session * @param string $privateKey * @return bool * @@ -120,8 +120,8 @@ class Session { } /** - * @brief Sets status of encryption app - * @param string $init INIT_SUCCESSFUL, INIT_EXECUTED, NOT_INOITIALIZED + * Sets status of encryption app + * @param string $init INIT_SUCCESSFUL, INIT_EXECUTED, NOT_INITIALIZED * @return bool * * @note this doesn not indicate of the init was successful, we just remeber the try! @@ -135,7 +135,7 @@ class Session { } /** - * @brief remove encryption keys and init status from session + * remove encryption keys and init status from session */ public function closeSession() { \OC::$session->remove('encryptionInitialized'); @@ -144,8 +144,8 @@ class Session { /** - * @brief Gets status if we already tried to initialize the encryption app - * @returns init status INIT_SUCCESSFUL, INIT_EXECUTED, NOT_INOITIALIZED + * Gets status if we already tried to initialize the encryption app + * @return string init status INIT_SUCCESSFUL, INIT_EXECUTED, NOT_INITIALIZED * * @note this doesn not indicate of the init was successful, we just remeber the try! */ @@ -158,8 +158,8 @@ class Session { } /** - * @brief Gets user or public share private key from session - * @returns string $privateKey The user's plaintext private key + * Gets user or public share private key from session + * @return string $privateKey The user's plaintext private key * */ public function getPrivateKey() { @@ -176,7 +176,7 @@ class Session { } /** - * @brief Sets public user private key to session + * Sets public user private key to session * @param string $privateKey * @return bool */ @@ -189,8 +189,8 @@ class Session { } /** - * @brief Gets public share private key from session - * @returns string $privateKey + * Gets public share private key from session + * @return string $privateKey * */ public function getPublicSharePrivateKey() { @@ -204,7 +204,7 @@ class Session { /** - * @brief Sets user legacy key to session + * Sets user legacy key to session * @param string $legacyKey * @return bool */ @@ -216,8 +216,8 @@ class Session { } /** - * @brief Gets user legacy key from session - * @returns string $legacyKey The user's plaintext legacy key + * Gets user legacy key from session + * @return string $legacyKey The user's plaintext legacy key * */ public function getLegacyKey() { diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php index df5de558867867f41c38d1c9b2548ada7264d1b6..341114214d50227ff7c39dea15b5e53056e335f8 100644 --- a/apps/files_encryption/lib/stream.php +++ b/apps/files_encryption/lib/stream.php @@ -31,7 +31,7 @@ namespace OCA\Encryption; /** - * @brief Provides 'crypt://' stream wrapper protocol. + * Provides 'crypt://' stream wrapper protocol. * @note We use a stream wrapper because it is the most secure way to handle * decrypted content transfers. There is no safe way to decrypt the entire file * somewhere on the server, so we have to encrypt and decrypt blocks on the fly. @@ -79,10 +79,10 @@ class Stream { private $privateKey; /** - * @param $path raw path relative to data/ - * @param $mode - * @param $options - * @param $opened_path + * @param string $path raw path relative to data/ + * @param string $mode + * @param int $options + * @param string $opened_path * @return bool */ public function stream_open($path, $mode, $options, &$opened_path) { @@ -91,7 +91,7 @@ class Stream { $this->newFile = false; if (!isset($this->rootView)) { - $this->rootView = new \OC_FilesystemView('/'); + $this->rootView = new \OC\Files\View('/'); } $this->session = new \OCA\Encryption\Session($this->rootView); @@ -179,15 +179,15 @@ class Stream { } /** - * @brief Returns the current position of the file pointer - * @return int position of the file pointer + * Returns the current position of the file pointer + * @return int position of the file pointer */ public function stream_tell() { return ftell($this->handle); } /** - * @param $offset + * @param int $offset * @param int $whence * @return bool true if fseek was successful, otherwise false */ @@ -202,7 +202,7 @@ class Stream { } /** - * @param $count + * @param int $count * @return bool|string * @throws \Exception */ @@ -246,7 +246,7 @@ class Stream { } /** - * @brief Encrypt and pad data ready for writing to disk + * Encrypt and pad data ready for writing to disk * @param string $plainData data to be encrypted * @param string $key key to use for encryption * @return string encrypted data on success, false on failure @@ -267,7 +267,7 @@ class Stream { } /** - * @brief Fetch the plain encryption key for the file and set it as plainKey property + * Fetch the plain encryption key for the file and set it as plainKey property * @internal param bool $generate if true, a new key will be generated if none can be found * @return bool true on key found and set, false on key not found and new key generated and set */ @@ -318,7 +318,7 @@ class Stream { } /** - * @brief Handle plain data from the stream, and write it in 8192 byte blocks + * Handle plain data from the stream, and write it in 8192 byte blocks * @param string $data data to be written to disk * @note the data will be written to the path stored in the stream handle, set in stream_open() * @note $data is only ever be a maximum of 8192 bytes long. This is set by PHP internally. stream_write() is called multiple times in a loop on data larger than 8192 bytes @@ -426,9 +426,9 @@ class Stream { /** - * @param $option - * @param $arg1 - * @param $arg2 + * @param int $option + * @param int $arg1 + * @param int|null $arg2 */ public function stream_set_option($option, $arg1, $arg2) { $return = false; @@ -454,7 +454,7 @@ class Stream { } /** - * @param $mode + * @param int $mode */ public function stream_lock($mode) { return flock($this->handle, $mode); diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index 6372ab31b6ec1c2e111825f26dc0926cd2ad4dd3..d20efc3ac7be9894eb3ed55179324103bc812e1c 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -25,8 +25,8 @@ namespace OCA\Encryption; /** - * @brief Class for utilities relating to encrypted file storage system - * @param \OC_FilesystemView $view expected to have OC '/' as root path + * Class for utilities relating to encrypted file storage system + * @param \OC\Files\View $view expected to have OC '/' as root path * @param string $userId ID of the logged in user * @param int $client indicating status of client side encryption. Currently * unused, likely to become obsolete shortly @@ -38,7 +38,7 @@ class Util { const MIGRATION_IN_PROGRESS = -1; // migration is running const MIGRATION_OPEN = 0; // user still needs to be migrated - private $view; // OC_FilesystemView object for filesystem operations + private $view; // OC\Files\View object for filesystem operations private $userId; // ID of the user we use to encrypt/decrypt files private $keyId; // ID of the key we want to manipulate private $client; // Client side encryption mode flag @@ -53,8 +53,8 @@ class Util { private $isPublic; /** - * @param \OC_FilesystemView $view - * @param $userId + * @param \OC\Files\View $view + * @param string $userId * @param bool $client */ public function __construct($view, $userId, $client = false) { @@ -111,7 +111,7 @@ class Util { } /** - * @brief check if the users private & public key exists + * check if the users private & public key exists * @return boolean */ public function userKeysExists() { @@ -125,7 +125,7 @@ class Util { } /** - * @brief Sets up user folders and keys for serverside encryption + * Sets up user folders and keys for serverside encryption * * @param string $passphrase to encrypt server-stored private key with * @return bool @@ -222,7 +222,7 @@ class Util { } /** - * @brief Check whether pwd recovery is enabled for a given user + * Check whether pwd recovery is enabled for a given user * @return bool 1 = yes, 0 = no, false = no record * * @note If records are not being returned, check for a hidden space @@ -264,7 +264,7 @@ class Util { } /** - * @brief Enable / disable pwd recovery for a given user + * Enable / disable pwd recovery for a given user * @param bool $enabled Whether to enable or disable recovery * @return bool */ @@ -300,7 +300,7 @@ class Util { } /** - * @brief Find all files and their encryption status within a directory + * Find all files and their encryption status within a directory * @param string $directory The path of the parent directory to search * @param bool $found the founded files if called again * @return mixed false if 0 found, array on success. Keys: name, path @@ -421,7 +421,7 @@ class Util { } /** - * @brief Check if a given path identifies an encrypted file + * Check if a given path identifies an encrypted file * @param string $path * @return boolean */ @@ -463,7 +463,7 @@ class Util { } /** - * @brief get the file size of the unencrypted file + * get the file size of the unencrypted file * @param string $path absolute path * @return bool */ @@ -537,7 +537,7 @@ class Util { } /** - * @brief fix the file size of the encrypted file + * fix the file size of the encrypted file * @param string $path absolute path * @return boolean true / false if file is encrypted */ @@ -594,7 +594,7 @@ class Util { } /** - * @brief encrypt versions from given file + * encrypt versions from given file * @param array $filelist list of encrypted files, relative to data/user/files * @return boolean */ @@ -640,7 +640,7 @@ class Util { } /** - * @brief decrypt versions from given file + * decrypt versions from given file * @param string $filelist list of decrypted files, relative to data/user/files * @return boolean */ @@ -686,7 +686,7 @@ class Util { } /** - * @brief Decrypt all files + * Decrypt all files * @return bool */ public function decryptAll() { @@ -788,8 +788,8 @@ class Util { } if ($successful) { - $this->view->deleteAll($this->keyfilesPath); - $this->view->deleteAll($this->shareKeysPath); + $this->view->rename($this->keyfilesPath, $this->keyfilesPath . '.backup'); + $this->view->rename($this->shareKeysPath, $this->shareKeysPath . '.backup'); } \OC_FileProxy::$enabled = true; @@ -799,7 +799,7 @@ class Util { } /** - * @brief Encrypt all files in a directory + * Encrypt all files in a directory * @param string $dirPath the directory whose files will be encrypted * @param null $legacyPassphrase * @param null $newPassphrase @@ -926,7 +926,7 @@ class Util { } /** - * @brief Return important encryption related paths + * Return important encryption related paths * @param string $pathName Name of the directory to return the path of * @return string path */ @@ -970,7 +970,7 @@ class Util { } /** - * @brief Filter an array of UIDs to return only ones ready for sharing + * Filter an array of UIDs to return only ones ready for sharing * @param array $unfilteredUsers users to be checked for sharing readiness * @return array as multi-dimensional array. keys: ready, unready */ @@ -1017,7 +1017,7 @@ class Util { } /** - * @brief Decrypt a keyfile + * Decrypt a keyfile * @param string $filePath * @param string $privateKey * @return false|string @@ -1036,7 +1036,7 @@ class Util { } /** - * @brief Encrypt keyfile to multiple users + * Encrypt keyfile to multiple users * @param Session $session * @param array $users list of users which should be able to access the file * @param string $filePath path of the file to be shared @@ -1097,7 +1097,7 @@ class Util { } /** - * @brief Find, sanitise and format users sharing a file + * Find, sanitise and format users sharing a file * @note This wraps other methods into a portable bundle * @param boolean $sharingEnabled * @param string $filePath path relativ to current users files folder @@ -1176,7 +1176,7 @@ class Util { } /** - * @brief set migration status + * set migration status * @param int $status * @return boolean */ @@ -1199,7 +1199,7 @@ class Util { } /** - * @brief start migration mode to initially encrypt users data + * start migration mode to initially encrypt users data * @return boolean */ public function beginMigration() { @@ -1221,7 +1221,7 @@ class Util { } /** - * @brief close migration mode after users data has been encrypted successfully + * close migration mode after users data has been encrypted successfully * @return boolean */ public function finishMigration() { @@ -1237,8 +1237,8 @@ class Util { } /** - * @brief check if files are already migrated to the encryption system - * @return migration status, false = in case of no record + * check if files are already migrated to the encryption system + * @return int|false migration status, false = in case of no record * @note If records are not being returned, check for a hidden space * at the start of the uid in db */ @@ -1288,7 +1288,7 @@ class Util { } /** - * @brief get uid of the owners of the file and the path to the file + * get uid of the owners of the file and the path to the file * @param string $path Path of the file to check * @throws \Exception * @note $shareFilePath must be relative to data/UID/files. Files @@ -1361,13 +1361,13 @@ class Util { return array( $fileOwnerUid, - \OC_Filesystem::normalizePath($filename) + \OC\Files\Filesystem::normalizePath($filename) ); } } /** - * @brief go recursively through a dir and collect all files and sub files. + * go recursively through a dir and collect all files and sub files. * @param string $dir relative to the users files folder * @return array with list of files relative to the users files folder */ @@ -1397,9 +1397,8 @@ class Util { } /** - * @brief get owner of the shared files. - * @param $id - * @internal param int $Id of a share + * get owner of the shared files. + * @param int $id ID of a share * @return string owner */ public function getOwnerFromSharedFile($id) { @@ -1479,7 +1478,7 @@ class Util { } /** - * @param $password + * @param string $password * @return bool */ public function checkRecoveryPassword($password) { @@ -1512,7 +1511,7 @@ class Util { } /** - * @brief add recovery key to all encrypted files + * add recovery key to all encrypted files */ public function addRecoveryKeys($path = '/') { $dirContent = $this->view->getDirectoryContent($this->keyfilesPath . $path); @@ -1522,7 +1521,7 @@ class Util { if ($item['type'] === 'dir') { $this->addRecoveryKeys($filePath . '/'); } else { - $session = new \OCA\Encryption\Session(new \OC_FilesystemView('/')); + $session = new \OCA\Encryption\Session(new \OC\Files\View('/')); $sharingEnabled = \OCP\Share::isEnabled(); // remove '.key' extension from path e.g. 'file.txt.key' to 'file.txt' $file = substr($filePath, 0, -4); @@ -1533,7 +1532,7 @@ class Util { } /** - * @brief remove recovery key to all encrypted files + * remove recovery key to all encrypted files */ public function removeRecoveryKeys($path = '/') { $dirContent = $this->view->getDirectoryContent($this->keyfilesPath . $path); @@ -1551,7 +1550,7 @@ class Util { } /** - * @brief decrypt given file with recovery key and encrypt it again to the owner and his new key + * decrypt given file with recovery key and encrypt it again to the owner and his new key * @param string $file * @param string $privateKey recovery key to decrypt the file */ @@ -1599,7 +1598,7 @@ class Util { } /** - * @brief collect all files and recover them one by one + * collect all files and recover them one by one * @param string $path to look for files keys * @param string $privateKey private recovery key which is used to decrypt the files */ @@ -1619,7 +1618,7 @@ class Util { } /** - * @brief recover users files in case of password lost + * recover users files in case of password lost * @param string $recoveryPassword */ public function recoverUsersFiles($recoveryPassword) { @@ -1638,8 +1637,8 @@ class Util { } /** - * @brief check if the file is stored on a system wide mount point - * @param $path relative to /data/user with leading '/' + * check if the file is stored on a system wide mount point + * @param string $path relative to /data/user with leading '/' * @return boolean */ public function isSystemWideMountPoint($path) { @@ -1655,7 +1654,7 @@ class Util { } /** - * @brief decrypt private key and add it to the current session + * decrypt private key and add it to the current session * @param array $params with 'uid' and 'password' * @return mixed session or false */ @@ -1683,7 +1682,7 @@ class Util { } /* - * @brief remove encryption related keys from the session + * remove encryption related keys from the session */ public function closeEncryptionSession() { $session = new \OCA\Encryption\Session($this->view); diff --git a/apps/files_encryption/settings-personal.php b/apps/files_encryption/settings-personal.php index 09e9df05352a9a121761f07d979534e95a826147..e9875518f67956b3f7227b735bac07eb7d51cbbd 100644 --- a/apps/files_encryption/settings-personal.php +++ b/apps/files_encryption/settings-personal.php @@ -12,7 +12,7 @@ $tmpl = new OCP\Template('files_encryption', 'settings-personal'); $user = \OCP\USER::getUser(); -$view = new \OC_FilesystemView('/'); +$view = new \OC\Files\View('/'); $util = new \OCA\Encryption\Util($view, $user); $session = new \OCA\Encryption\Session($view); diff --git a/apps/files_encryption/tests/crypt.php b/apps/files_encryption/tests/crypt.php index 123943ea26a9c6cca7593f508c38f7aebf587808..b22cd214eaaad1738e1b6590f8dc42ec5f05198d 100755 --- a/apps/files_encryption/tests/crypt.php +++ b/apps/files_encryption/tests/crypt.php @@ -34,7 +34,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { public $dataUrl; public $dataShort; /** - * @var OC_FilesystemView + * @var OC\Files\View */ public $view; public $legacyEncryptedData; @@ -79,7 +79,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { $this->genPublicKey = $keypair['publicKey']; $this->genPrivateKey = $keypair['privateKey']; - $this->view = new \OC_FilesystemView('/'); + $this->view = new \OC\Files\View('/'); // remember files_trashbin state $this->stateFilesTrashbin = OC_App::isEnabled('files_trashbin'); @@ -157,7 +157,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { $filename = 'tmp-' . uniqid() . '.test'; - $util = new Encryption\Util(new \OC_FilesystemView(), $this->userId); + $util = new Encryption\Util(new \OC\Files\View(), $this->userId); $cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/'. $filename, $this->dataShort); @@ -206,7 +206,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { /** * @medium - * @brief Test that data that is written by the crypto stream wrapper + * Test that data that is written by the crypto stream wrapper * @note Encrypted data is manually prepared and decrypted here to avoid dependency on success of stream_read * @note If this test fails with truncate content, check that enough array slices are being rejoined to form $e, as the crypt.php file may have gotten longer and broken the manual * reassembly of its data @@ -216,7 +216,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { // Generate a a random filename $filename = 'tmp-' . uniqid() . '.test'; - $util = new Encryption\Util(new \OC_FilesystemView(), $this->userId); + $util = new Encryption\Util(new \OC\Files\View(), $this->userId); // Save long data as encrypted file using stream wrapper $cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/' . $filename, $this->dataLong . $this->dataLong); @@ -293,7 +293,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { /** * @medium - * @brief Test that data that is read by the crypto stream wrapper + * Test that data that is read by the crypto stream wrapper */ function testSymmetricStreamDecryptShortFileContent() { @@ -388,7 +388,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { /** * @medium - * @brief test decryption using legacy blowfish method + * test decryption using legacy blowfish method */ function testLegacyDecryptShort() { @@ -402,7 +402,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { /** * @medium - * @brief test decryption using legacy blowfish method + * test decryption using legacy blowfish method */ function testLegacyDecryptLong() { @@ -660,9 +660,9 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { /** - * @brief encryption using legacy blowfish method + * encryption using legacy blowfish method * @param string $data data to encrypt - * @param $passwd string password + * @param string $passwd password * @return string */ function legacyEncrypt($data, $passwd) { diff --git a/apps/files_encryption/tests/hooks.php b/apps/files_encryption/tests/hooks.php index 047084ca2c177713202d75b30fd402c067027e90..fcb369c7238eec877bfdc0d0ca996fcd97d1f1d2 100644 --- a/apps/files_encryption/tests/hooks.php +++ b/apps/files_encryption/tests/hooks.php @@ -32,7 +32,7 @@ use OCA\Encryption; /** * Class Test_Encryption_Hooks - * @brief this class provide basic hook app tests + * this class provide basic hook app tests */ class Test_Encryption_Hooks extends \PHPUnit_Framework_TestCase { @@ -40,7 +40,7 @@ class Test_Encryption_Hooks extends \PHPUnit_Framework_TestCase { const TEST_ENCRYPTION_HOOKS_USER2 = "test-encryption-hooks-user2"; /** - * @var \OC_FilesystemView + * @var \OC\Files\View */ public $user1View; // view on /data/user1/files public $user2View; // view on /data/user2/files @@ -83,9 +83,9 @@ class Test_Encryption_Hooks extends \PHPUnit_Framework_TestCase { \OC_User::setUserId(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1); // init filesystem view - $this->user1View = new \OC_FilesystemView('/'. \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1 . '/files'); - $this->user2View = new \OC_FilesystemView('/'. \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2 . '/files'); - $this->rootView = new \OC_FilesystemView('/'); + $this->user1View = new \OC\Files\View('/'. \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1 . '/files'); + $this->user2View = new \OC\Files\View('/'. \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2 . '/files'); + $this->rootView = new \OC\Files\View('/'); // init short data $this->data = 'hats'; @@ -259,7 +259,7 @@ class Test_Encryption_Hooks extends \PHPUnit_Framework_TestCase { } /** - * @brief test rename operation + * test rename operation */ function testRenameHook() { diff --git a/apps/files_encryption/tests/keymanager.php b/apps/files_encryption/tests/keymanager.php index 0caf12e91a3eb2eae92b83ce741208792ea80292..2bd2ddc8e68d13d5973e5a23748edc1750c4bcf4 100644 --- a/apps/files_encryption/tests/keymanager.php +++ b/apps/files_encryption/tests/keymanager.php @@ -29,7 +29,7 @@ class Test_Encryption_Keymanager extends \PHPUnit_Framework_TestCase { public $pass; public $stateFilesTrashbin; /** - * @var OC_FilesystemView + * @var OC\Files\View */ public $view; public $randomKey; @@ -68,7 +68,7 @@ class Test_Encryption_Keymanager extends \PHPUnit_Framework_TestCase { $this->genPublicKey = $keypair['publicKey']; $this->genPrivateKey = $keypair['privateKey']; - $this->view = new \OC_FilesystemView('/'); + $this->view = new \OC\Files\View('/'); \OC_User::setUserId(\Test_Encryption_Keymanager::TEST_USER); $this->userId = \Test_Encryption_Keymanager::TEST_USER; @@ -257,4 +257,4 @@ class TestProtectedKeymanagerMethods extends \OCA\Encryption\Keymanager { public static function testGetFilenameFromShareKey($sharekey) { return self::getFilenameFromShareKey($sharekey); } -} \ No newline at end of file +} diff --git a/apps/files_encryption/tests/proxy.php b/apps/files_encryption/tests/proxy.php index 647ee955eb1ac7d763f1504956c725459af475ce..8d6bc81b08d217b03e61ca09cb7cf62fa78f8469 100644 --- a/apps/files_encryption/tests/proxy.php +++ b/apps/files_encryption/tests/proxy.php @@ -33,7 +33,7 @@ use OCA\Encryption; /** * Class Test_Encryption_Proxy - * @brief this class provide basic proxy app tests + * this class provide basic proxy app tests */ class Test_Encryption_Proxy extends \PHPUnit_Framework_TestCase { @@ -42,7 +42,7 @@ class Test_Encryption_Proxy extends \PHPUnit_Framework_TestCase { public $userId; public $pass; /** - * @var \OC_FilesystemView + * @var \OC\Files\View */ public $view; // view in /data/user/files public $rootView; // view on /data/user @@ -75,8 +75,8 @@ class Test_Encryption_Proxy extends \PHPUnit_Framework_TestCase { $this->pass = \Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1; // init filesystem view - $this->view = new \OC_FilesystemView('/'. \Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1 . '/files'); - $this->rootView = new \OC_FilesystemView('/'. \Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1 ); + $this->view = new \OC\Files\View('/'. \Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1 . '/files'); + $this->rootView = new \OC\Files\View('/'. \Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1 ); // init short data $this->data = 'hats'; @@ -91,7 +91,7 @@ class Test_Encryption_Proxy extends \PHPUnit_Framework_TestCase { /** * @medium - * @brief test if postFileSize returns the unencrypted file size + * test if postFileSize returns the unencrypted file size */ function testPostFileSize() { diff --git a/apps/files_encryption/tests/share.php b/apps/files_encryption/tests/share.php index 512671c5767b5140c7d93de0727751e4c07080c4..bb3d7505a5df6adc0b96e8a055c147204ef0da42 100755 --- a/apps/files_encryption/tests/share.php +++ b/apps/files_encryption/tests/share.php @@ -48,7 +48,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { public $filename; public $dataShort; /** - * @var OC_FilesystemView + * @var OC\Files\View */ public $view; public $folder1; @@ -92,7 +92,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { function setUp() { $this->dataShort = 'hats'; - $this->view = new \OC_FilesystemView('/'); + $this->view = new \OC\Files\View('/'); $this->folder1 = '/folder1'; $this->subfolder = '/subfolder1'; @@ -669,7 +669,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { // login as admin \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); - $util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); + $util = new \OCA\Encryption\Util(new \OC\Files\View('/'), \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); // check if recovery password match $this->assertTrue($util->checkRecoveryPassword('test123')); @@ -777,7 +777,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { // login as user2 \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); - $util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); + $util = new \OCA\Encryption\Util(new \OC\Files\View('/'), \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); // enable recovery for admin $this->assertTrue($util->setRecoveryForUser(1)); @@ -959,7 +959,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { /** - * @brief test moving a shared file out of the Shared folder + * test moving a shared file out of the Shared folder */ function testRename() { diff --git a/apps/files_encryption/tests/stream.php b/apps/files_encryption/tests/stream.php index fed2e7d89d10d8eacc6d3d3ef36a5ea53a9ac584..5df9cdbe1f1468c56232a90b368d6d31bd559448 100644 --- a/apps/files_encryption/tests/stream.php +++ b/apps/files_encryption/tests/stream.php @@ -33,7 +33,7 @@ use OCA\Encryption; /** * Class Test_Encryption_Stream - * @brief this class provide basic stream tests + * this class provide basic stream tests */ class Test_Encryption_Stream extends \PHPUnit_Framework_TestCase { @@ -42,7 +42,7 @@ class Test_Encryption_Stream extends \PHPUnit_Framework_TestCase { public $userId; public $pass; /** - * @var \OC_FilesystemView + * @var \OC\Files\View */ public $view; public $dataShort; @@ -71,7 +71,7 @@ class Test_Encryption_Stream extends \PHPUnit_Framework_TestCase { $this->pass = \Test_Encryption_Stream::TEST_ENCRYPTION_STREAM_USER1; // init filesystem view - $this->view = new \OC_FilesystemView('/'); + $this->view = new \OC\Files\View('/'); // init short data $this->dataShort = 'hats'; @@ -183,7 +183,7 @@ class Test_Encryption_Stream extends \PHPUnit_Framework_TestCase { /** * @medium - * @brief test if stream wrapper can read files outside from the data folder + * test if stream wrapper can read files outside from the data folder */ function testStreamFromLocalFile() { diff --git a/apps/files_encryption/tests/trashbin.php b/apps/files_encryption/tests/trashbin.php index 2f9ecfd9d5d1faab63f2b3d37d4a422a42aefed1..5d54b7db24f0b989f03bfad72e38b7ee4bdf5eda 100755 --- a/apps/files_encryption/tests/trashbin.php +++ b/apps/files_encryption/tests/trashbin.php @@ -34,7 +34,7 @@ use OCA\Encryption; /** * Class Test_Encryption_Trashbin - * @brief this class provide basic trashbin app tests + * this class provide basic trashbin app tests */ class Test_Encryption_Trashbin extends \PHPUnit_Framework_TestCase { @@ -43,7 +43,7 @@ class Test_Encryption_Trashbin extends \PHPUnit_Framework_TestCase { public $userId; public $pass; /** - * @var \OC_FilesystemView + * @var \OC\Files\View */ public $view; public $dataShort; @@ -81,7 +81,7 @@ class Test_Encryption_Trashbin extends \PHPUnit_Framework_TestCase { $this->pass = \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1; // init filesystem view - $this->view = new \OC_FilesystemView('/'); + $this->view = new \OC\Files\View('/'); // init short data $this->dataShort = 'hats'; @@ -114,7 +114,7 @@ class Test_Encryption_Trashbin extends \PHPUnit_Framework_TestCase { /** * @medium - * @brief test delete file + * test delete file */ function testDeleteFile() { @@ -186,7 +186,7 @@ class Test_Encryption_Trashbin extends \PHPUnit_Framework_TestCase { /** * @medium - * @brief test restore file + * test restore file * * @depends testDeleteFile */ @@ -218,7 +218,7 @@ class Test_Encryption_Trashbin extends \PHPUnit_Framework_TestCase { /** * @medium - * @brief test delete file forever + * test delete file forever */ function testPermanentDeleteFile() { diff --git a/apps/files_encryption/tests/util.php b/apps/files_encryption/tests/util.php index 88ded7ec40a4b591bf5b5c9359e3ec5950a6b41a..a4dcc5cc8bdcffa26e86c55cbefec523e1df21e4 100755 --- a/apps/files_encryption/tests/util.php +++ b/apps/files_encryption/tests/util.php @@ -29,7 +29,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { public $publicKeyDir; public $pass; /** - * @var OC_FilesystemView + * @var OC\Files\View */ public $view; public $keyfilesPath; @@ -92,7 +92,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { $this->privateKeyPath = $this->encryptionDir . '/' . $this->userId . '.private.key'; // e.g. data/admin/admin.private.key - $this->view = new \OC_FilesystemView('/'); + $this->view = new \OC\Files\View('/'); $this->util = new Encryption\Util($this->view, $this->userId); @@ -121,7 +121,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { /** * @medium - * @brief test that paths set during User construction are correct + * test that paths set during User construction are correct */ function testKeyPaths() { $util = new Encryption\Util($this->view, $this->userId); @@ -136,7 +136,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { /** * @medium - * @brief test detection of encrypted files + * test detection of encrypted files */ function testIsEncryptedPath() { @@ -171,7 +171,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { /** * @medium - * @brief test setup of encryption directories + * test setup of encryption directories */ function testSetupServerSide() { $this->assertEquals(true, $this->util->setupServerSide($this->pass)); @@ -179,14 +179,14 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { /** * @medium - * @brief test checking whether account is ready for encryption, + * test checking whether account is ready for encryption, */ function testUserIsReady() { $this->assertEquals(true, $this->util->ready()); } /** - * @brief test checking whether account is not ready for encryption, + * test checking whether account is not ready for encryption, */ // function testUserIsNotReady() { // $this->view->unlink($this->publicKeyDir); @@ -200,12 +200,12 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { /** * @medium - * @brief test checking whether account is not ready for encryption, + * test checking whether account is not ready for encryption, */ function testIsLegacyUser() { \Test_Encryption_Util::loginHelper(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER); - $userView = new \OC_FilesystemView('/' . \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER); + $userView = new \OC\Files\View('/' . \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER); // Disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; @@ -279,7 +279,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { } /** -< * @brief Test that data that is read by the crypto stream wrapper +< * Test that data that is read by the crypto stream wrapper */ function testGetFileSize() { \Test_Encryption_Util::loginHelper(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1); @@ -384,7 +384,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { $params = array('uid' => \OCP\User::getUser(), 'password' => \OCP\User::getUser()); - $view = new OC_FilesystemView('/'); + $view = new OC\Files\View('/'); $util = new \OCA\Encryption\Util($view, \OCP\User::getUser()); $result = $util->initEncryption($params); @@ -413,8 +413,16 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { // file should no longer be encrypted $this->assertEquals(0, $fileInfoUnencrypted['encrypted']); + // check if the keys where moved to the backup location + $this->assertTrue($this->view->is_dir($this->userId . '/files_encryption/keyfiles.backup')); + $this->assertTrue($this->view->file_exists($this->userId . '/files_encryption/keyfiles.backup/' . $filename . '.key')); + $this->assertTrue($this->view->is_dir($this->userId . '/files_encryption/share-keys.backup')); + $this->assertTrue($this->view->file_exists($this->userId . '/files_encryption/share-keys.backup/' . $filename . '.' . $user . '.shareKey')); + // cleanup $this->view->unlink($this->userId . '/files/' . $filename); + $this->view->deleteAll($this->userId . '/files_encryption/keyfiles.backup'); + $this->view->deleteAll($this->userId . '/files_encryption/share-keys.backup'); OC_App::enable('files_encryption'); } @@ -485,8 +493,11 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { $this->assertFalse($this->view->is_dir($this->userId . '/files_encryption/keyfiles/')); $this->assertFalse($this->view->is_dir($this->userId . '/files_encryption/share-keys/')); + //cleanup $this->view->unlink($this->userId . '/files/' . $file1); $this->view->unlink($this->userId . '/files/' . $file2); + $this->view->deleteAll($this->userId . '/files_encryption/keyfiles.backup'); + $this->view->deleteAll($this->userId . '/files_encryption/share-keys.backup'); } @@ -496,8 +507,8 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { function testEncryptLegacyFiles() { \Test_Encryption_Util::loginHelper(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER); - $userView = new \OC_FilesystemView('/' . \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER); - $view = new \OC_FilesystemView('/' . \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER . '/files'); + $userView = new \OC\Files\View('/' . \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER); + $view = new \OC\Files\View('/' . \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER . '/files'); // Disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; @@ -543,7 +554,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { } /** - * @param $user + * @param string $user * @param bool $create * @param bool $password */ @@ -584,7 +595,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { * to be able to test the migration path * * @param integer $status needed migration status for test - * @param $user for which user the status should be set + * @param string $user for which user the status should be set * @return boolean */ private function setMigrationStatus($status, $user) { diff --git a/apps/files_encryption/tests/webdav.php b/apps/files_encryption/tests/webdav.php index 1fe4c13d59e8bae7622d38848fd4281bfcf9d410..d33dc58cf920a80d1a016efdcfc35fec30be17af 100755 --- a/apps/files_encryption/tests/webdav.php +++ b/apps/files_encryption/tests/webdav.php @@ -34,7 +34,7 @@ use OCA\Encryption; /** * Class Test_Encryption_Webdav * - * @brief this class provide basic webdav tests for PUT,GET and DELETE + * this class provide basic webdav tests for PUT,GET and DELETE */ class Test_Encryption_Webdav extends \PHPUnit_Framework_TestCase { @@ -43,7 +43,7 @@ class Test_Encryption_Webdav extends \PHPUnit_Framework_TestCase { public $userId; public $pass; /** - * @var \OC_FilesystemView + * @var \OC\Files\View */ public $view; public $dataShort; @@ -82,7 +82,7 @@ class Test_Encryption_Webdav extends \PHPUnit_Framework_TestCase { $this->pass = \Test_Encryption_Webdav::TEST_ENCRYPTION_WEBDAV_USER1; // init filesystem view - $this->view = new \OC_FilesystemView('/'); + $this->view = new \OC\Files\View('/'); // init short data $this->dataShort = 'hats'; @@ -112,7 +112,7 @@ class Test_Encryption_Webdav extends \PHPUnit_Framework_TestCase { } /** - * @brief test webdav put random file + * test webdav put random file */ function testWebdavPUT() { @@ -167,7 +167,7 @@ class Test_Encryption_Webdav extends \PHPUnit_Framework_TestCase { } /** - * @brief test webdav get random file + * test webdav get random file * * @depends testWebdavPUT */ @@ -190,7 +190,7 @@ class Test_Encryption_Webdav extends \PHPUnit_Framework_TestCase { } /** - * @brief test webdav delete random file + * test webdav delete random file * @depends testWebdavGET */ function testWebdavDELETE($filename) { @@ -216,7 +216,7 @@ class Test_Encryption_Webdav extends \PHPUnit_Framework_TestCase { } /** - * @brief handle webdav request + * handle webdav request * * @param bool $body * diff --git a/apps/files_external/appinfo/app.php b/apps/files_external/appinfo/app.php index 003665486f810bff0f0fdc97ff7fd2eefbf5dd31..e8ed8950c3a987930a55bb7c5713a3caf7621985 100644 --- a/apps/files_external/appinfo/app.php +++ b/apps/files_external/appinfo/app.php @@ -70,7 +70,7 @@ OC_Mount_Config::registerBackend('\OC\Files\Storage\Dropbox', array( OC_Mount_Config::registerBackend('\OC\Files\Storage\FTP', array( 'backend' => 'FTP', 'configuration' => array( - 'host' => (string)$l->t('URL'), + 'host' => (string)$l->t('Host'), 'user' => (string)$l->t('Username'), 'password' => '*'.$l->t('Password'), 'root' => '&'.$l->t('Root'), @@ -108,7 +108,7 @@ if (!OC_Util::runningOnWindows()) { OC_Mount_Config::registerBackend('\OC\Files\Storage\SMB', array( 'backend' => 'SMB / CIFS', 'configuration' => array( - 'host' => (string)$l->t('URL'), + 'host' => (string)$l->t('Host'), 'user' => (string)$l->t('Username'), 'password' => '*'.$l->t('Password'), 'share' => (string)$l->t('Share'), @@ -118,7 +118,7 @@ if (!OC_Util::runningOnWindows()) { OC_Mount_Config::registerBackend('\OC\Files\Storage\SMB_OC', array( 'backend' => (string)$l->t('SMB / CIFS using OC login'), 'configuration' => array( - 'host' => (string)$l->t('URL'), + 'host' => (string)$l->t('Host'), 'username_as_share' => '!'.$l->t('Username as share'), 'share' => '&'.$l->t('Share'), 'root' => '&'.$l->t('Root')), @@ -148,7 +148,7 @@ OC_Mount_Config::registerBackend('\OC\Files\Storage\OwnCloud', array( OC_Mount_Config::registerBackend('\OC\Files\Storage\SFTP', array( 'backend' => 'SFTP', 'configuration' => array( - 'host' => (string)$l->t('URL'), + 'host' => (string)$l->t('Host'), 'user' => (string)$l->t('Username'), 'password' => '*'.$l->t('Password'), 'root' => '&'.$l->t('Root')))); diff --git a/apps/files_external/l10n/ar.php b/apps/files_external/l10n/ar.php index 5bef941c19ce2e53d4a49d9d5059a183c94df643..eb1150eb95ecfdc319362d21e1ba928a8aba9656 100644 --- a/apps/files_external/l10n/ar.php +++ b/apps/files_external/l10n/ar.php @@ -1,10 +1,11 @@ "المكان", -"URL" => "عنوان الموقع", +"Host" => "المضيف", "Username" => "إسم المستخدم", "Password" => "كلمة السر", "Share" => "شارك", +"URL" => "عنوان الموقع", "Saved" => "حفظ", "Folder name" => "اسم المجلد", "Options" => "خيارات", diff --git a/apps/files_external/l10n/ast.php b/apps/files_external/l10n/ast.php index add498191546d5628112ec34ac5f306bb1d3a252..faf0388dd91799c8ef82cab61f15be78c2c19410 100644 --- a/apps/files_external/l10n/ast.php +++ b/apps/files_external/l10n/ast.php @@ -2,16 +2,69 @@ $TRANSLATIONS = array( "Local" => "Llocal", "Location" => "Llocalización", -"URL" => "URL", +"Amazon S3" => "Amazon S3", +"Key" => "Clave", +"Secret" => "Secretu", +"Bucket" => "Depósitu", +"Amazon S3 and compliant" => "Amazon S3 y compatibilidá", +"Access Key" => "Clave d'accesu", +"Secret Key" => "Clave Secreta", +"Hostname (optional)" => "Nome d'equipu (opcional)", +"Port (optional)" => "Puertu (opcional)", +"Region (optional)" => "Rexón (opcional)", +"Enable SSL" => "Habilitar SSL", +"Enable Path Style" => "Habilitar Estilu de ruta", +"App key" => "App principal", +"App secret" => "App secreta", +"Host" => "Sirvidor", "Username" => "Nome d'usuariu", "Password" => "Contraseña", +"Root" => "Raíz", +"Secure ftps://" => "Secure ftps://", +"Client ID" => "ID de veceru", +"Client secret" => "Veceru secretu", +"OpenStack Object Storage" => "OpenStack Object Storage", +"Username (required)" => "Nome d'usuariu (necesariu)", +"Bucket (required)" => "Depósitu (necesariu)", +"Region (optional for OpenStack Object Storage)" => "Rexón (opcional pa OpenStack Object Storage)", +"API Key (required for Rackspace Cloud Files)" => "Clave API (necesaria pa Rackspace Cloud Files)", +"Tenantname (required for OpenStack Object Storage)" => "Nome d'inquilín (necesariu pa OpenStack Object Storage)", +"Password (required for OpenStack Object Storage)" => "Contraseña (necesaria pa OpenStack Object Storage)", +"Service Name (required for OpenStack Object Storage)" => "Nome de Serviciu (necesariu pa OpenStack Object Storage)", +"URL of identity endpoint (required for OpenStack Object Storage)" => "URL d'identidá de puntu final (necesariu pa OpenStack Object Storage)", +"Timeout of HTTP requests in seconds (optional)" => "Tiempu d'espera de peticiones HTTP en segundos (opcional)", "Share" => "Compartir", +"SMB / CIFS using OC login" => "SMB / CIFS usando accesu OC", +"Username as share" => "Nome d'usuariu como Compartición", +"URL" => "URL", +"Secure https://" => "Secure https://", +"Remote subfolder" => "Subcarpeta remota", +"Access granted" => "Accesu concedíu", +"Error configuring Dropbox storage" => "Fallu configurando l'almacenamientu de Dropbox", +"Grant access" => "Conceder accesu", +"Please provide a valid Dropbox app key and secret." => "Por favor, proporciona una clave válida de l'app Dropbox y una clave secreta.", +"Error configuring Google Drive storage" => "Fallu configurando l'almacenamientu de Google Drive", "Saved" => "Guardáu", +"Note: " => "Nota: ", +" and " => "y", +"Note: The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." => "Nota: El soporte de cURL en PHP nun ta activáu o instaláu. Nun pue montase %s. Pídi-y al alministrador de sistema que lu instale.", +"Note: The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." => "Nota: El soporte de FTP en PHP nun ta activáu o instaláu. Nun pue montase %s. Pídi-y al alministrador de sistema que lu instale.", +"Note: \"%s\" is not installed. Mounting of %s is not possible. Please ask your system administrator to install it." => "Nota: \"%s\" nun ta instaláu. Nun pue montase %s. Pídi-y al alministrador de sistema que lu instale.", +"External Storage" => "Almacenamientu esternu", "Folder name" => "Nome de la carpeta", +"External storage" => "Almacenamientu esternu", "Configuration" => "Configuración", "Options" => "Opciones", +"Available for" => "Disponible pa", +"Add storage" => "Amestar almacenamientu", +"No user or group" => "Nengún usuariu o grupu", +"All Users" => "Tolos usuarios", "Groups" => "Grupos", "Users" => "Usuarios", -"Delete" => "Desaniciar" +"Delete" => "Desaniciar", +"Enable User External Storage" => "Habilitar almacenamientu esterno d'usuariu", +"Allow users to mount the following external storage" => "Permitir a los usuarios montar el siguiente almacenamientu esternu", +"SSL root certificates" => "Certificaos raíz SSL", +"Import Root Certificate" => "Importar certificáu raíz" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_external/l10n/bg_BG.php b/apps/files_external/l10n/bg_BG.php index 0969184383e1800c710e33437e258d2ac3327007..13e43314bda18ba584d5ad0d781f7f9a1f8df78c 100644 --- a/apps/files_external/l10n/bg_BG.php +++ b/apps/files_external/l10n/bg_BG.php @@ -1,10 +1,10 @@ "Място", -"URL" => "Уеб адрес", "Username" => "Потребител", "Password" => "Парола", "Share" => "Споделяне", +"URL" => "Уеб адрес", "Access granted" => "Достъпът е даден", "Grant access" => "Даване на достъп", "External Storage" => "Външно хранилище", diff --git a/apps/files_external/l10n/bn_BD.php b/apps/files_external/l10n/bn_BD.php index 3b1978a568c32cbea34ff25e363d73961b32db96..f1ada4b476d29753493f14347015915c371e277f 100644 --- a/apps/files_external/l10n/bn_BD.php +++ b/apps/files_external/l10n/bn_BD.php @@ -1,10 +1,11 @@ "াবস্থান", -"URL" => "URL", +"Host" => "হোস্ট", "Username" => "ব্যবহারকারী", "Password" => "কূটশব্দ", "Share" => "ভাগাভাগি কর", +"URL" => "URL", "Access granted" => "অধিগমনের অনুমতি প্রদান করা হলো", "Error configuring Dropbox storage" => "Dropbox সংরক্ষণাগার নির্ধারণ করতে সমস্যা ", "Grant access" => "অধিগমনের অনুমতি প্রদান কর", diff --git a/apps/files_external/l10n/ca.php b/apps/files_external/l10n/ca.php index e49f26c353cdf745d123919cd5ed7165638ddf72..e349dfe45ef71da1839a990474171590831068f4 100644 --- a/apps/files_external/l10n/ca.php +++ b/apps/files_external/l10n/ca.php @@ -2,10 +2,11 @@ $TRANSLATIONS = array( "Local" => "Local", "Location" => "Ubicació", -"URL" => "URL", +"Host" => "Equip remot", "Username" => "Nom d'usuari", "Password" => "Contrasenya", "Share" => "Comparteix", +"URL" => "URL", "Access granted" => "S'ha concedit l'accés", "Error configuring Dropbox storage" => "Error en configurar l'emmagatzemament Dropbox", "Grant access" => "Concedeix accés", diff --git a/apps/files_external/l10n/cs_CZ.php b/apps/files_external/l10n/cs_CZ.php index e953e19a9dd98f42540ed86f56fa33c248e0595c..2d1116ed0f66fbd3949049be2cc8545ddacd73fe 100644 --- a/apps/files_external/l10n/cs_CZ.php +++ b/apps/files_external/l10n/cs_CZ.php @@ -13,7 +13,7 @@ $TRANSLATIONS = array( "Enable SSL" => "Povolit SSL", "App key" => "Klíč aplikace", "App secret" => "Tajemství aplikace", -"URL" => "URL", +"Host" => "Počítač", "Username" => "Uživatelské jméno", "Password" => "Heslo", "Root" => "Root", @@ -25,6 +25,7 @@ $TRANSLATIONS = array( "Share" => "Sdílet", "SMB / CIFS using OC login" => "SMB / CIFS za použití OC loginu", "Username as share" => "Uživatelské jméno jako sdílený adresář", +"URL" => "URL", "Secure https://" => "Zabezpečené https://", "Remote subfolder" => "Vzdálený podadresář", "Access granted" => "Přístup povolen", diff --git a/apps/files_external/l10n/cy_GB.php b/apps/files_external/l10n/cy_GB.php index 9b5d97a48a7c15be8b98891841d15b4732e4eb56..39822fcd3834062f638f928fdc49f50d07d0cea2 100644 --- a/apps/files_external/l10n/cy_GB.php +++ b/apps/files_external/l10n/cy_GB.php @@ -1,10 +1,10 @@ "Lleoliad", -"URL" => "URL", "Username" => "Enw defnyddiwr", "Password" => "Cyfrinair", "Share" => "Rhannu", +"URL" => "URL", "Groups" => "Grwpiau", "Users" => "Defnyddwyr", "Delete" => "Dileu" diff --git a/apps/files_external/l10n/da.php b/apps/files_external/l10n/da.php index a0e8510789eb3b1eaffca3639e6b4f5c485175a3..2d235747ad9584d2a2ccfdc96dc7c0cbdd8ab77f 100644 --- a/apps/files_external/l10n/da.php +++ b/apps/files_external/l10n/da.php @@ -6,7 +6,7 @@ $TRANSLATIONS = array( "Key" => "Nøgle", "Secret" => "Hemmelighed", "Secret Key" => "Hemmelig Nøgle ", -"URL" => "URL", +"Host" => "Host", "Username" => "Brugernavn", "Password" => "Kodeord", "Root" => "Root", @@ -15,6 +15,7 @@ $TRANSLATIONS = array( "Client secret" => "Klient hemmelighed", "OpenStack Object Storage" => "OpenStack Object Storage", "Share" => "Del", +"URL" => "URL", "Secure https://" => "Sikker https://", "Access granted" => "Adgang godkendt", "Error configuring Dropbox storage" => "Fejl ved konfiguration af Dropbox plads", diff --git a/apps/files_external/l10n/de.php b/apps/files_external/l10n/de.php index c41cef968f0700205bbec3022e37804e701671af..03f6f05abb98ab71cc78892fbee99179e2360d7e 100644 --- a/apps/files_external/l10n/de.php +++ b/apps/files_external/l10n/de.php @@ -16,7 +16,7 @@ $TRANSLATIONS = array( "Enable Path Style" => "Pfad-Stil aktivieren", "App key" => "App-Schlüssel", "App secret" => "Geheime Zeichenkette der App", -"URL" => "URL", +"Host" => "Host", "Username" => "Benutzername", "Password" => "Passwort", "Root" => "Root", @@ -36,6 +36,7 @@ $TRANSLATIONS = array( "Share" => "Teilen", "SMB / CIFS using OC login" => "´", "Username as share" => "Benutzername als Freigabe", +"URL" => "URL", "Secure https://" => "Sicherer HTTPS://", "Remote subfolder" => "Remote-Unterordner:", "Access granted" => "Zugriff gestattet", diff --git a/apps/files_external/l10n/de_CH.php b/apps/files_external/l10n/de_CH.php index 6d7366fe28443ff37f0aa2348f29639960455acc..4e0ac1f3a090795d2b16a69dd0a3e67b5f4666a6 100644 --- a/apps/files_external/l10n/de_CH.php +++ b/apps/files_external/l10n/de_CH.php @@ -1,10 +1,11 @@ "Ort", -"URL" => "URL", +"Host" => "Host", "Username" => "Benutzername", "Password" => "Passwort", "Share" => "Freigeben", +"URL" => "URL", "Access granted" => "Zugriff gestattet", "Error configuring Dropbox storage" => "Fehler beim Einrichten von Dropbox", "Grant access" => "Zugriff gestatten", diff --git a/apps/files_external/l10n/de_DE.php b/apps/files_external/l10n/de_DE.php index 1119a0f8755881d33c39debbfaab4d3a39479e9c..286250f86899a5bf47a48029e75ef1b4010a4077 100644 --- a/apps/files_external/l10n/de_DE.php +++ b/apps/files_external/l10n/de_DE.php @@ -16,7 +16,7 @@ $TRANSLATIONS = array( "Enable Path Style" => "Pfad-Stil aktivieren", "App key" => "App-Schlüssel", "App secret" => "Geheime Zeichenkette der App", -"URL" => "URL", +"Host" => "Host", "Username" => "Benutzername", "Password" => "Passwort", "Root" => "Root", @@ -36,6 +36,7 @@ $TRANSLATIONS = array( "Share" => "Teilen", "SMB / CIFS using OC login" => "Zeitüberschreitung von HTTP-Anfragen in Sekunden (Optional)", "Username as share" => "Benutzername als Freigabe", +"URL" => "URL", "Secure https://" => "Sicherer HTTPS://", "Remote subfolder" => "Remote-Unterordner:", "Access granted" => "Zugriff gestattet", diff --git a/apps/files_external/l10n/el.php b/apps/files_external/l10n/el.php index 351468a36dc975232e9d5b0eaae13835ba9ac008..09d39a9e3cd902a415acdf3bc9d25d2014795877 100644 --- a/apps/files_external/l10n/el.php +++ b/apps/files_external/l10n/el.php @@ -2,23 +2,53 @@ $TRANSLATIONS = array( "Local" => "Τοπικός", "Location" => "Τοποθεσία", -"URL" => "URL", +"Key" => "Κλειδί", +"Secret" => "Μυστικό", +"Access Key" => "Κλειδί πρόσβασης", +"Secret Key" => "Μυστικό κλειδί", +"Hostname (optional)" => "Όνομα μηχανήματος (προαιρετικά)", +"Port (optional)" => "Πόρτα (προαιρετικά)", +"Region (optional)" => "Περιοχή (προαιρετικά)", +"Enable SSL" => "Ενεργοποίηση SSL", +"Enable Path Style" => "Ενεργοποίηση μορφής διαδρομής", +"App key" => "Κλειδί εφαρμογής", +"Host" => "Διακομιστής", "Username" => "Όνομα χρήστη", "Password" => "Κωδικός πρόσβασης", +"Root" => "Root", +"Secure ftps://" => "Ασφαλής ftps://", +"Client ID" => "ID πελάτη", +"Client secret" => "Μυστικό πελάτη", +"OpenStack Object Storage" => "Αποθήκη αντικειμένων OpenStack", "Username (required)" => "Όνομα χρήστη (απαιτείται)", +"Region (optional for OpenStack Object Storage)" => "Περιοχή (προαιρετικά για την αποθήκευση αντικειμένων OpenStack)", +"API Key (required for Rackspace Cloud Files)" => "Κλειδί API (απαιτείται για αρχεία Rackspace Cloud)", +"Password (required for OpenStack Object Storage)" => "Μυστικός κωδικός (απαιτείται για την αποθήκευση αντικειμένων OpenStack)", +"Service Name (required for OpenStack Object Storage)" => "Όνομα υπηρεσίας (απαιτείται για την αποθήκευση αντικειμένων OpenStack)", +"URL of identity endpoint (required for OpenStack Object Storage)" => "Διεύθυνση URL της ταυτότητας τελικού σημείου (απαιτείται για την αποθήκευση αντικειμένων OpenStack)", +"Timeout of HTTP requests in seconds (optional)" => "Χρονικό όριο των αιτήσεων HTTP σε δευτερόλεπτα (προαιρετικά)", "Share" => "Διαμοιράστε", +"SMB / CIFS using OC login" => "SMB / CIFS χρησιμοποιώντας λογαριασμό OC", +"URL" => "URL", +"Secure https://" => "Ασφαλής σύνδεση https://", +"Remote subfolder" => "Απομακρυσμένος υποφάκελος", "Access granted" => "Προσβαση παρασχέθηκε", "Error configuring Dropbox storage" => "Σφάλμα ρυθμίζωντας αποθήκευση Dropbox ", "Grant access" => "Παροχή πρόσβασης", "Please provide a valid Dropbox app key and secret." => "Παρακαλούμε δώστε έγκυρο κλειδί Dropbox και μυστικό.", "Error configuring Google Drive storage" => "Σφάλμα ρυθμίζωντας αποθήκευση Google Drive ", "Saved" => "Αποθηκεύτηκαν", +"Note: " => "Σημείωση: ", " and " => "και", +"Note: The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." => "Σημείωση: Η υποστήριξη cURL στην PHP δεν είναι ενεργοποιημένη ή εγκατεστημένη. Η προσάρτηση του %s δεν είναι δυνατή. Παρακαλώ ζητήστε από τον διαχειριστή συστημάτων σας να την εγκαταστήσει.", +"Note: The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." => "Σημείωση: Η υποστήριξη FTP στην PHP δεν είναι ενεργοποιημένη ή εγκατεστημένη. Δεν είναι δυνατή η προσάρτηση του %s. Παρακαλώ ζητήστε από τον διαχειριστή συστημάτων σας να την εγκαταστήσει.", +"Note: \"%s\" is not installed. Mounting of %s is not possible. Please ask your system administrator to install it." => "Σημείωση: Η επέκταση \"%s\" δεν είναι εγκατεστημένη. Δεν είναι δυνατή η προσάρτηση %s. Παρακαλώ ζητήστε από τον διαχειριστή συστημάτων σας να την εγκαταστήσει.", "External Storage" => "Εξωτερικό Αποθηκευτικό Μέσο", "Folder name" => "Όνομα φακέλου", "External storage" => "Εξωτερική αποθήκευση", "Configuration" => "Ρυθμίσεις", "Options" => "Επιλογές", +"Available for" => "Διαθέσιμο για", "Add storage" => "Προσθηκη αποθηκευσης", "No user or group" => "Μη διαθέσιμος χρήστης ή ομάδα", "All Users" => "Όλοι οι Χρήστες", diff --git a/apps/files_external/l10n/en_GB.php b/apps/files_external/l10n/en_GB.php index 5a0e2456ac09fb8bdaf493fb8854d251a7742180..d4229c607ef895008b6f3c0642df42e487867b16 100644 --- a/apps/files_external/l10n/en_GB.php +++ b/apps/files_external/l10n/en_GB.php @@ -16,7 +16,7 @@ $TRANSLATIONS = array( "Enable Path Style" => "Enable Path Style", "App key" => "App key", "App secret" => "App secret", -"URL" => "URL", +"Host" => "Host", "Username" => "Username", "Password" => "Password", "Root" => "Root", @@ -36,6 +36,7 @@ $TRANSLATIONS = array( "Share" => "Share", "SMB / CIFS using OC login" => "SMB / CIFS using OC login", "Username as share" => "Username as share", +"URL" => "URL", "Secure https://" => "Secure https://", "Remote subfolder" => "Remote subfolder", "Access granted" => "Access granted", diff --git a/apps/files_external/l10n/eo.php b/apps/files_external/l10n/eo.php index d8915b49b025b107a4265967f80c83009de10bca..d3ca5a5addf18e342335f05393ddabafec07c1d4 100644 --- a/apps/files_external/l10n/eo.php +++ b/apps/files_external/l10n/eo.php @@ -1,10 +1,11 @@ "Loko", -"URL" => "URL", +"Host" => "Gastigo", "Username" => "Uzantonomo", "Password" => "Pasvorto", "Share" => "Kunhavigi", +"URL" => "URL", "Access granted" => "Alirpermeso donita", "Error configuring Dropbox storage" => "Eraro dum agordado de la memorservo Dropbox", "Grant access" => "Doni alirpermeson", diff --git a/apps/files_external/l10n/es.php b/apps/files_external/l10n/es.php index 3c18b18057e8e7ee72beaa1816c39321c20543ee..bbbe0a8c6130e5925bb785678ded2f2064d0df22 100644 --- a/apps/files_external/l10n/es.php +++ b/apps/files_external/l10n/es.php @@ -16,7 +16,7 @@ $TRANSLATIONS = array( "Enable Path Style" => "Habilitar Estilo de Ruta", "App key" => "App principal", "App secret" => "App secreta", -"URL" => "URL", +"Host" => "Servidor", "Username" => "Nombre de usuario", "Password" => "Contraseña", "Root" => "Raíz", @@ -36,6 +36,7 @@ $TRANSLATIONS = array( "Share" => "Compartir", "SMB / CIFS using OC login" => "SMB / CIFS usando acceso OC", "Username as share" => "Nombre de Usuario como compartir", +"URL" => "URL", "Secure https://" => "Secure https://", "Remote subfolder" => "Subcarpeta remota", "Access granted" => "Acceso concedido", diff --git a/apps/files_external/l10n/es_AR.php b/apps/files_external/l10n/es_AR.php index c380c6d0d91e93110e5bd0e2e0015f079ba8657e..dfb53d9a78485dba9add5506ec5ba4e7fad447a0 100644 --- a/apps/files_external/l10n/es_AR.php +++ b/apps/files_external/l10n/es_AR.php @@ -1,10 +1,11 @@ "Ubicación", -"URL" => "URL", +"Host" => "Servidor", "Username" => "Nombre de usuario", "Password" => "Contraseña", "Share" => "Compartir", +"URL" => "URL", "Access granted" => "Acceso permitido", "Error configuring Dropbox storage" => "Error al configurar el almacenamiento de Dropbox", "Grant access" => "Permitir acceso", diff --git a/apps/files_external/l10n/es_MX.php b/apps/files_external/l10n/es_MX.php index 73ce83591047769facf64411b4bebeb951c2ca0d..7e28798f58ad85ae7f2be8fafa35975aa86fcf07 100644 --- a/apps/files_external/l10n/es_MX.php +++ b/apps/files_external/l10n/es_MX.php @@ -1,10 +1,11 @@ "Ubicación", -"URL" => "URL", +"Host" => "Servidor", "Username" => "Nombre de usuario", "Password" => "Contraseña", "Share" => "Compartir", +"URL" => "URL", "Access granted" => "Acceso concedido", "Error configuring Dropbox storage" => "Error configurando el almacenamiento de Dropbox", "Grant access" => "Conceder acceso", diff --git a/apps/files_external/l10n/et_EE.php b/apps/files_external/l10n/et_EE.php index e5fc7c6937e4f60aa993751f9041e4e357b2a2cd..73444411979b61c18c14d4d142103befd74c89fc 100644 --- a/apps/files_external/l10n/et_EE.php +++ b/apps/files_external/l10n/et_EE.php @@ -2,10 +2,11 @@ $TRANSLATIONS = array( "Local" => "Kohalik", "Location" => "Asukoht", -"URL" => "URL", +"Host" => "Host", "Username" => "Kasutajanimi", "Password" => "Parool", "Share" => "Jaga", +"URL" => "URL", "Access granted" => "Ligipääs on antud", "Error configuring Dropbox storage" => "Viga Dropboxi salvestusruumi seadistamisel", "Grant access" => "Anna ligipääs", diff --git a/apps/files_external/l10n/eu.php b/apps/files_external/l10n/eu.php index 28376b56b65a88d30e9f5d52f5eeb5bdccbb23fe..ef29ba0484835ca9536f63b27d3af816badee6ef 100644 --- a/apps/files_external/l10n/eu.php +++ b/apps/files_external/l10n/eu.php @@ -5,10 +5,11 @@ $TRANSLATIONS = array( "Amazon S3" => "Amazon S3", "Port (optional)" => "Portua (hautazkoa)", "Enable SSL" => "Gaitu SSL", -"URL" => "URL", +"Host" => "Hostalaria", "Username" => "Erabiltzaile izena", "Password" => "Pasahitza", "Share" => "Partekatu", +"URL" => "URL", "Access granted" => "Sarrera baimendua", "Error configuring Dropbox storage" => "Errore bat egon da Dropbox biltegiratzea konfiguratzean", "Grant access" => "Baimendu sarrera", diff --git a/apps/files_external/l10n/fa.php b/apps/files_external/l10n/fa.php index 6bf8ce8af58080b474ffd80006eb7ef5e65e4c93..674a72873323ec636dd04ee02683b831bfe7797b 100644 --- a/apps/files_external/l10n/fa.php +++ b/apps/files_external/l10n/fa.php @@ -1,10 +1,11 @@ "محل", -"URL" => "آدرس", +"Host" => "میزبانی", "Username" => "نام کاربری", "Password" => "گذرواژه", "Share" => "اشتراک‌گذاری", +"URL" => "آدرس", "Access granted" => "مجوز دسترسی صادر شد", "Error configuring Dropbox storage" => "خطا به هنگام تنظیم فضای دراپ باکس", "Grant access" => " مجوز اعطا دسترسی", diff --git a/apps/files_external/l10n/fi_FI.php b/apps/files_external/l10n/fi_FI.php index 9efc8e09cb712360a47cc871bc771ed60a5a2ea9..aa7fb394d4ed1c89c67c1395b88e589a3b23d5b5 100644 --- a/apps/files_external/l10n/fi_FI.php +++ b/apps/files_external/l10n/fi_FI.php @@ -6,11 +6,13 @@ $TRANSLATIONS = array( "Port (optional)" => "Portti (valinnainen)", "Region (optional)" => "Alue (valinnainen)", "Enable SSL" => "Käytä SSL:ää", -"URL" => "Verkko-osoite", +"Host" => "Isäntä", "Username" => "Käyttäjätunnus", "Password" => "Salasana", "Username (required)" => "Käyttäjätunnus (vaaditaan)", "Share" => "Jaa", +"URL" => "Verkko-osoite", +"Secure https://" => "Salattu https://", "Access granted" => "Pääsy sallittu", "Error configuring Dropbox storage" => "Virhe Dropbox levyn asetuksia tehtäessä", "Grant access" => "Salli pääsy", diff --git a/apps/files_external/l10n/fr.php b/apps/files_external/l10n/fr.php index c03a2f49e0a9739805a6d1cc1e4d43cdb00ca418..df2f63ec2e7bda293f973aca59ee75ae74f7b764 100644 --- a/apps/files_external/l10n/fr.php +++ b/apps/files_external/l10n/fr.php @@ -4,11 +4,23 @@ $TRANSLATIONS = array( "Location" => "Emplacement", "Amazon S3" => "Amazon S3", "Key" => "Clé", +"Secret" => "Secret", "Access Key" => "Clé d'accès", -"URL" => "URL", +"Secret Key" => "Clé secrète", +"Hostname (optional)" => "Nom machine (optionnel)", +"Port (optional)" => "Port (optionnel)", +"Enable SSL" => "Activer SSL", +"App key" => "Clé App", +"Host" => "Hôte", "Username" => "Nom d'utilisateur", "Password" => "Mot de passe", +"Root" => "Root", +"Client ID" => "ID Client", +"Username (required)" => "Nom d'utilisation (requis)", +"API Key (required for Rackspace Cloud Files)" => "Clé API (requis pour Rackspace Cloud Files)", +"Password (required for OpenStack Object Storage)" => "Mot de passe (requis pour OpenStack Object Storage)", "Share" => "Partager", +"URL" => "URL", "Access granted" => "Accès autorisé", "Error configuring Dropbox storage" => "Erreur lors de la configuration du support de stockage Dropbox", "Grant access" => "Autoriser l'accès", diff --git a/apps/files_external/l10n/gl.php b/apps/files_external/l10n/gl.php index ccbdcce7f3482b30b9dae20cac532aeaa616e11d..248afb5f6a7a8723629ecfe1bee5929160be25ff 100644 --- a/apps/files_external/l10n/gl.php +++ b/apps/files_external/l10n/gl.php @@ -16,7 +16,7 @@ $TRANSLATIONS = array( "Enable Path Style" => "Activar o estilo de ruta", "App key" => "Clave da API", "App secret" => "Secreto do aplicativo", -"URL" => "URL", +"Host" => "Servidor", "Username" => "Nome de usuario", "Password" => "Contrasinal", "Root" => "Root (raíz)", @@ -36,6 +36,7 @@ $TRANSLATIONS = array( "Share" => "Compartir", "SMB / CIFS using OC login" => "SMB / CIFS usando acceso OC", "Username as share" => "Nome de usuario como compartición", +"URL" => "URL", "Secure https://" => "https:// seguro", "Remote subfolder" => "Subcartafol remoto", "Access granted" => "Concedeuse acceso", diff --git a/apps/files_external/l10n/he.php b/apps/files_external/l10n/he.php index 67cbb0cba2a80df3e03f173c920591381a253f99..f55a35fcadecf2857692f7d5a986073efc6be56f 100644 --- a/apps/files_external/l10n/he.php +++ b/apps/files_external/l10n/he.php @@ -1,10 +1,11 @@ "מיקום", -"URL" => "כתובת", +"Host" => "מארח", "Username" => "שם משתמש", "Password" => "סיסמא", "Share" => "שיתוף", +"URL" => "כתובת", "Access granted" => "הוענקה גישה", "Error configuring Dropbox storage" => "אירעה שגיאה בעת הגדרת אחסון ב־Dropbox", "Grant access" => "הענקת גישה", diff --git a/apps/files_external/l10n/hu_HU.php b/apps/files_external/l10n/hu_HU.php index 831bd69c231b2c3ae20d8f29f9e3132f217e55a2..d9c570d68c9354847b221a608eb1a1742e330c9a 100644 --- a/apps/files_external/l10n/hu_HU.php +++ b/apps/files_external/l10n/hu_HU.php @@ -1,10 +1,11 @@ "Hely", -"URL" => "URL", +"Host" => "Kiszolgáló", "Username" => "Felhasználónév", "Password" => "Jelszó", "Share" => "Megosztás", +"URL" => "URL", "Access granted" => "Érvényes hozzáférés", "Error configuring Dropbox storage" => "A Dropbox tárolót nem sikerült beállítani", "Grant access" => "Megadom a hozzáférést", diff --git a/apps/files_external/l10n/ia.php b/apps/files_external/l10n/ia.php index 844af213d8bf19bf23c499b86b6ede10f2e73bd7..978003e20cb1aa98ebd1f2c2dbf3d08e84439fed 100644 --- a/apps/files_external/l10n/ia.php +++ b/apps/files_external/l10n/ia.php @@ -1,10 +1,10 @@ "Loco", -"URL" => "URL", "Username" => "Nomine de usator", "Password" => "Contrasigno", "Share" => "Compartir", +"URL" => "URL", "Folder name" => "Nomine de dossier", "Groups" => "Gruppos", "Users" => "Usatores", diff --git a/apps/files_external/l10n/id.php b/apps/files_external/l10n/id.php index dd383c4636b72242f94fb2397655aa66b60be42a..a21ea7aef7b84ffb6b72477e8df46be22c031d61 100644 --- a/apps/files_external/l10n/id.php +++ b/apps/files_external/l10n/id.php @@ -7,12 +7,13 @@ $TRANSLATIONS = array( "Port (optional)" => "Port (tambahan)", "Region (optional)" => "Wilayah (tambahan)", "Enable SSL" => "Aktifkan SSL", -"URL" => "tautan", +"Host" => "Host", "Username" => "Nama Pengguna", "Password" => "Sandi", "Root" => "Root", "Username (required)" => "Nama pengguna (dibutuhkan)", "Share" => "Bagikan", +"URL" => "tautan", "Access granted" => "Akses diberikan", "Error configuring Dropbox storage" => "Kesalahan dalam mengonfigurasi penyimpanan Dropbox", "Grant access" => "Berikan hak akses", diff --git a/apps/files_external/l10n/is.php b/apps/files_external/l10n/is.php index 39b750189dcfb84a916f64bf11245ff3f204ca02..daf9c4cb4417742e0af73cf1ef8effc5afa42ecd 100644 --- a/apps/files_external/l10n/is.php +++ b/apps/files_external/l10n/is.php @@ -1,10 +1,11 @@ "Staðsetning", -"URL" => "URL", +"Host" => "Netþjónn", "Username" => "Notendanafn", "Password" => "Lykilorð", "Share" => "Deila", +"URL" => "URL", "Access granted" => "Aðgengi veitt", "Error configuring Dropbox storage" => "Villa við að setja upp Dropbox gagnasvæði", "Grant access" => "Veita aðgengi", diff --git a/apps/files_external/l10n/it.php b/apps/files_external/l10n/it.php index bc5b9d6dcee0392012a0fa270e9a9174a708c890..c6428a27ba196821b915cd239792805424521213 100644 --- a/apps/files_external/l10n/it.php +++ b/apps/files_external/l10n/it.php @@ -16,7 +16,7 @@ $TRANSLATIONS = array( "Enable Path Style" => "Abilita stile percorsi", "App key" => "Chiave applicazione", "App secret" => "Segreto applicazione", -"URL" => "URL", +"Host" => "Host", "Username" => "Nome utente", "Password" => "Password", "Root" => "Radice", @@ -36,6 +36,7 @@ $TRANSLATIONS = array( "Share" => "Condividi", "SMB / CIFS using OC login" => "SMB / CIFS utilizzando le credenziali di OC", "Username as share" => "Nome utente come condivisione", +"URL" => "URL", "Secure https://" => "Sicuro https://", "Remote subfolder" => "Sottocartella remota", "Access granted" => "Accesso consentito", diff --git a/apps/files_external/l10n/ja.php b/apps/files_external/l10n/ja.php index 4ac746caa00c5e8af5b67f6e4ce59b39335d9241..b70dd2a09a45678ad49260caeab20ab87fa79a2e 100644 --- a/apps/files_external/l10n/ja.php +++ b/apps/files_external/l10n/ja.php @@ -2,21 +2,60 @@ $TRANSLATIONS = array( "Local" => "ローカル", "Location" => "位置", -"URL" => "URL", +"Amazon S3" => "Amazon S3", +"Key" => "キー", +"Secret" => "シークレットキー", +"Bucket" => "バケット名", +"Amazon S3 and compliant" => "Amazon S3 と互換ストレージ", +"Access Key" => "アクセスキー", +"Secret Key" => "シークレットキー", +"Hostname (optional)" => "ホスト名 (オプション)", +"Port (optional)" => "ポート (オプション)", +"Region (optional)" => "リージョン (オプション)", +"Enable SSL" => "SSLを有効", +"Enable Path Style" => "パス形式を有効", +"App key" => "アプリキー", +"App secret" => "アプリシークレット", +"Host" => "ホスト", "Username" => "ユーザー名", "Password" => "パスワード", +"Root" => "ルート", +"Secure ftps://" => "Secure ftps://", +"Client ID" => "クライアントID", +"Client secret" => "クライアント秘密キー", +"OpenStack Object Storage" => "OpenStack Object Storage", +"Username (required)" => "ユーザー名 (必須)", +"Bucket (required)" => "バケット (必須)", +"Region (optional for OpenStack Object Storage)" => "リージョン (OpenStack Object Storage用のオプション)", +"API Key (required for Rackspace Cloud Files)" => "APIキー (Rackspace Cloud Filesに必須)", +"Tenantname (required for OpenStack Object Storage)" => "テナント名 (OpenStack Object Storage用に必要)", +"Password (required for OpenStack Object Storage)" => "パスワード (OpenStack Object Storage用に必要)", +"Service Name (required for OpenStack Object Storage)" => "サービス名 (OpenStack Object Storage用に必要)", +"URL of identity endpoint (required for OpenStack Object Storage)" => "識別用エンドポイントURL (OpenStack Object Storage用に必要)", +"Timeout of HTTP requests in seconds (optional)" => "HTTPリクエストのタイムアウト秒数 (オプション)", "Share" => "共有", +"SMB / CIFS using OC login" => "owncloudログインで SMB/CIFSを使用", +"Username as share" => "共有名", +"URL" => "URL", +"Secure https://" => "セキュア https://", +"Remote subfolder" => "リモートサブフォルダ", "Access granted" => "アクセスは許可されました", "Error configuring Dropbox storage" => "Dropboxストレージの設定エラー", "Grant access" => "アクセスを許可", "Please provide a valid Dropbox app key and secret." => "有効なDropboxアプリのキーとパスワードを入力してください。", "Error configuring Google Drive storage" => "Googleドライブストレージの設定エラー", "Saved" => "保存されました", +"Note: " => "注意: ", +" and " => "と", +"Note: The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." => "注意: PHPにcURLのエクステンションが入っていないか、有効ではありません。%s をマウントすることができません。このシステムの管理者にインストールをお願いしてください。", +"Note: The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." => "注意: PHPにFTPのエクステンションが入っていないか、有効ではありません。%s をマウントすることができません。このシステムの管理者にインストールをお願いしてください。", +"Note: \"%s\" is not installed. Mounting of %s is not possible. Please ask your system administrator to install it." => "注意: \"%s\" がインストールされていません。%sをマウントできません。このシステムの管理者にインストールをお願いしてください。", "External Storage" => "外部ストレージ", "Folder name" => "フォルダー名", "External storage" => "外部ストレージ", "Configuration" => "設定", "Options" => "オプション", +"Available for" => "以下が利用可能", "Add storage" => "ストレージを追加", "No user or group" => "ユーザーもしくはグループがありません", "All Users" => "すべてのユーザー", diff --git a/apps/files_external/l10n/ka_GE.php b/apps/files_external/l10n/ka_GE.php index f7eb01ba94a81e8f2c52606d255dd169512bdbda..a87c8b4879ad9a8d07b3646bbb84e37ca2905d9c 100644 --- a/apps/files_external/l10n/ka_GE.php +++ b/apps/files_external/l10n/ka_GE.php @@ -1,10 +1,11 @@ "ადგილმდებარეობა", -"URL" => "URL", +"Host" => "ჰოსტი", "Username" => "მომხმარებლის სახელი", "Password" => "პაროლი", "Share" => "გაზიარება", +"URL" => "URL", "Access granted" => "დაშვება მინიჭებულია", "Error configuring Dropbox storage" => "შეცდომა Dropbox საცავის კონფიგურირების დროს", "Grant access" => "დაშვების მინიჭება", diff --git a/apps/files_external/l10n/km.php b/apps/files_external/l10n/km.php index aac6337024573a2b8ae0fbf7b13564419ea52406..da17fac1bffdf4dd55a303920ceb3ea7a3226688 100644 --- a/apps/files_external/l10n/km.php +++ b/apps/files_external/l10n/km.php @@ -1,12 +1,22 @@ "ទីតាំង", -"URL" => "URL", +"Host" => "ម៉ាស៊ីន​ផ្ទុក", "Username" => "ឈ្មោះ​អ្នកប្រើ", "Password" => "ពាក្យសម្ងាត់", "Share" => "ចែក​រំលែក", +"URL" => "URL", +"Access granted" => "បាន​ទទួល​សិទ្ធិ​ចូល", +"Error configuring Dropbox storage" => "កំហុស​ការ​កំណត់​សណ្ឋាន​នៃ​ឃ្លាំងផ្ទុក Dropbox", +"Grant access" => "ទទួល​សិទ្ធិ​ចូល", +"Saved" => "បាន​រក្សាទុក", +"External Storage" => "ឃ្លាំងផ្ទុក​ខាងក្រៅ", "Folder name" => "ឈ្មោះ​ថត", +"External storage" => "ឃ្លាំងផ្ទុក​ខាងក្រៅ", +"Configuration" => "ការ​កំណត់​សណ្ឋាន", "Options" => "ជម្រើស", +"Add storage" => "បន្ថែម​ឃ្លាំងផ្ទុក", +"All Users" => "អ្នក​ប្រើ​ទាំងអស់", "Groups" => "ក្រុ", "Users" => "អ្នកប្រើ", "Delete" => "លុប" diff --git a/apps/files_external/l10n/ko.php b/apps/files_external/l10n/ko.php index 6ae8ffdeb8fb26be9096b9ce9b5d70ce983a9003..631f95bc7b956cbfb4ae1687e71b572f1606f64c 100644 --- a/apps/files_external/l10n/ko.php +++ b/apps/files_external/l10n/ko.php @@ -2,10 +2,11 @@ $TRANSLATIONS = array( "Location" => "장소", "Amazon S3" => "Amazon S3", -"URL" => "URL", +"Host" => "호스트", "Username" => "사용자 이름", "Password" => "암호", "Share" => "공유", +"URL" => "URL", "Access granted" => "접근 허가됨", "Error configuring Dropbox storage" => "Dropbox 저장소 설정 오류", "Grant access" => "접근 권한 부여", diff --git a/apps/files_external/l10n/ku_IQ.php b/apps/files_external/l10n/ku_IQ.php index 72cc813352e354cf76003741d2e39c5de3e789f5..3d5a3dd0d3263a0311f67c3d58b7f78819bb8507 100644 --- a/apps/files_external/l10n/ku_IQ.php +++ b/apps/files_external/l10n/ku_IQ.php @@ -1,10 +1,10 @@ "شوێن", -"URL" => "ناونیشانی به‌سته‌ر", "Username" => "ناوی به‌کارهێنه‌ر", "Password" => "وشەی تێپەربو", "Share" => "هاوبەشی کردن", +"URL" => "ناونیشانی به‌سته‌ر", "Folder name" => "ناوی بوخچه", "Users" => "به‌كارهێنه‌ر" ); diff --git a/apps/files_external/l10n/lb.php b/apps/files_external/l10n/lb.php index 49517e7af3ddf47d03f200c177c138e70ed04ee5..233b3f810511e3cdffcd340abab0c78011bffd57 100644 --- a/apps/files_external/l10n/lb.php +++ b/apps/files_external/l10n/lb.php @@ -1,10 +1,11 @@ "Uert", -"URL" => "URL", +"Host" => "Host", "Username" => "Benotzernumm", "Password" => "Passwuert", "Share" => "Deelen", +"URL" => "URL", "Folder name" => "Dossiers Numm:", "Groups" => "Gruppen", "Users" => "Benotzer", diff --git a/apps/files_external/l10n/lt_LT.php b/apps/files_external/l10n/lt_LT.php index 736becc58d5ab34854101c4bb7cb1f0e8d1bc20f..908abcc74885a5b9acda50200df029406009d3ca 100644 --- a/apps/files_external/l10n/lt_LT.php +++ b/apps/files_external/l10n/lt_LT.php @@ -1,10 +1,11 @@ "Vieta", -"URL" => "URL", +"Host" => "Mazgas", "Username" => "Prisijungimo vardas", "Password" => "Slaptažodis", "Share" => "Dalintis", +"URL" => "URL", "Access granted" => "Priėjimas suteiktas", "Error configuring Dropbox storage" => "Klaida nustatinėjant Dropbox talpyklą", "Grant access" => "Suteikti priėjimą", diff --git a/apps/files_external/l10n/lv.php b/apps/files_external/l10n/lv.php index 3506e55323a8622bb79113f68dbc8723dcf37ef8..5234bda7dce11d56a4f9d82674e0064c43531a2f 100644 --- a/apps/files_external/l10n/lv.php +++ b/apps/files_external/l10n/lv.php @@ -1,10 +1,11 @@ "Vieta", -"URL" => "URL", +"Host" => "Resursdators", "Username" => "Lietotājvārds", "Password" => "Parole", "Share" => "Dalīties", +"URL" => "URL", "Access granted" => "Piešķirta pieeja", "Error configuring Dropbox storage" => "Kļūda, konfigurējot Dropbox krātuvi", "Grant access" => "Piešķirt pieeju", diff --git a/apps/files_external/l10n/mk.php b/apps/files_external/l10n/mk.php index 0a72b65168acb72fd843512f1bda5f585b59db78..e1bf57d5b93f48711984d569c2b8447cc759dcdb 100644 --- a/apps/files_external/l10n/mk.php +++ b/apps/files_external/l10n/mk.php @@ -1,10 +1,11 @@ "Локација", -"URL" => "Адреса", +"Host" => "Домаќин", "Username" => "Корисничко име", "Password" => "Лозинка", "Share" => "Сподели", +"URL" => "Адреса", "Access granted" => "Пристапот е дозволен", "Error configuring Dropbox storage" => "Грешка при конфигурација на Dropbox", "Grant access" => "Дозволи пристап", diff --git a/apps/files_external/l10n/ms_MY.php b/apps/files_external/l10n/ms_MY.php index 789527e4a49171fba04dc0461c99b586d8a5ca46..e19ec499780ded8746877df7172bc0bdf7d5013b 100644 --- a/apps/files_external/l10n/ms_MY.php +++ b/apps/files_external/l10n/ms_MY.php @@ -1,10 +1,10 @@ "Lokasi", -"URL" => "URL", "Username" => "Nama pengguna", "Password" => "Kata laluan", "Share" => "Kongsi", +"URL" => "URL", "Groups" => "Kumpulan", "Users" => "Pengguna", "Delete" => "Padam" diff --git a/apps/files_external/l10n/nb_NO.php b/apps/files_external/l10n/nb_NO.php index f1f0a09fd533143f34a2d7107a98f471a9d18d85..7897f4b3f8d812026e059510757720818d26c5eb 100644 --- a/apps/files_external/l10n/nb_NO.php +++ b/apps/files_external/l10n/nb_NO.php @@ -3,10 +3,11 @@ $TRANSLATIONS = array( "Local" => "Lokal", "Location" => "Sted", "Amazon S3" => "Amazon S3", -"URL" => "URL", +"Host" => "Tjener", "Username" => "Brukernavn", "Password" => "Passord", "Share" => "Del", +"URL" => "URL", "Access granted" => "Tilgang innvilget", "Error configuring Dropbox storage" => "Feil ved konfigurering av Dropbox-lagring", "Grant access" => "Gi tilgang", diff --git a/apps/files_external/l10n/nl.php b/apps/files_external/l10n/nl.php index 2e88c1874048fc9b4a845b7f4cb97c0bb9eba8ce..2bdc047e96d8c936a16fa9654c7996d84e47a67a 100644 --- a/apps/files_external/l10n/nl.php +++ b/apps/files_external/l10n/nl.php @@ -16,7 +16,7 @@ $TRANSLATIONS = array( "Enable Path Style" => "Activeren pad stijl", "App key" => "App key", "App secret" => "App secret", -"URL" => "URL", +"Host" => "Host", "Username" => "Gebruikersnaam", "Password" => "Wachtwoord", "Root" => "Root", @@ -36,6 +36,7 @@ $TRANSLATIONS = array( "Share" => "Share", "SMB / CIFS using OC login" => "SMB / CIFS via OC inlog", "Username as share" => "Gebruikersnaam als share", +"URL" => "URL", "Secure https://" => "Secure https://", "Remote subfolder" => "Externe submap", "Access granted" => "Toegang toegestaan", diff --git a/apps/files_external/l10n/nn_NO.php b/apps/files_external/l10n/nn_NO.php index 542d3ec0421aefcf60a30bfe884b4d6384464d47..0ee80369eec4417ae7ffd3ab791c5f280a667f52 100644 --- a/apps/files_external/l10n/nn_NO.php +++ b/apps/files_external/l10n/nn_NO.php @@ -1,10 +1,11 @@ "Stad", -"URL" => "Nettstad", +"Host" => "Tenar", "Username" => "Brukarnamn", "Password" => "Passord", "Share" => "Del", +"URL" => "Nettstad", "Folder name" => "Mappenamn", "Configuration" => "Innstillingar", "Groups" => "Grupper", diff --git a/apps/files_external/l10n/oc.php b/apps/files_external/l10n/oc.php index e854c9f25ae5b48927b1d783c8d252e6a46def3a..bd5c98ca0513858026a9705d16abab385707654c 100644 --- a/apps/files_external/l10n/oc.php +++ b/apps/files_external/l10n/oc.php @@ -1,10 +1,10 @@ "Plaça", -"URL" => "URL", "Username" => "Non d'usancièr", "Password" => "Senhal", "Share" => "Parteja", +"URL" => "URL", "Groups" => "Grops", "Users" => "Usancièrs", "Delete" => "Escafa" diff --git a/apps/files_external/l10n/pl.php b/apps/files_external/l10n/pl.php index 9c13371b166ff7f1ae78be91b0204ef64ace6e79..74d9347b606717aa837a1e0ad936f9113fb42c07 100644 --- a/apps/files_external/l10n/pl.php +++ b/apps/files_external/l10n/pl.php @@ -16,7 +16,7 @@ $TRANSLATIONS = array( "Enable Path Style" => "Włącz styl ścieżki", "App key" => "Klucz aplikacji", "App secret" => "Hasło aplikacji", -"URL" => "URL", +"Host" => "Host", "Username" => "Nazwa użytkownika", "Password" => "Hasło", "Root" => "Root", @@ -36,6 +36,7 @@ $TRANSLATIONS = array( "Share" => "Udostępnij", "SMB / CIFS using OC login" => "SMB / CIFS przy użyciu loginu OC", "Username as share" => "Użytkownik jako zasób", +"URL" => "URL", "Secure https://" => "Bezpieczny https://", "Remote subfolder" => "Zdalny podfolder", "Access granted" => "Dostęp do", diff --git a/apps/files_external/l10n/pt_BR.php b/apps/files_external/l10n/pt_BR.php index d9544ae159775828555e192fc5af83172cc6f147..b027a92e50e3e170b122d566e0918f04a91eb21c 100644 --- a/apps/files_external/l10n/pt_BR.php +++ b/apps/files_external/l10n/pt_BR.php @@ -16,7 +16,7 @@ $TRANSLATIONS = array( "Enable Path Style" => "Habilitar Estilo do Caminho", "App key" => "Chave do Aplicativo", "App secret" => "Segredo da Aplicação", -"URL" => "URL", +"Host" => "Servidor", "Username" => "Nome de Usuário", "Password" => "Senha", "Root" => "Raiz", @@ -36,6 +36,7 @@ $TRANSLATIONS = array( "Share" => "Compartilhar", "SMB / CIFS using OC login" => "SMB / CIFS usando OC logon", "Username as share" => "Nome de usuário como compartilhado", +"URL" => "URL", "Secure https://" => "https:// segura", "Remote subfolder" => "Subpasta remota", "Access granted" => "Acesso concedido", diff --git a/apps/files_external/l10n/pt_PT.php b/apps/files_external/l10n/pt_PT.php index 767ddeec8a661420385227b9f3ba933a3c7d7d3b..2daa72715bad405d5fcbb2983ee607bc61dd0a01 100644 --- a/apps/files_external/l10n/pt_PT.php +++ b/apps/files_external/l10n/pt_PT.php @@ -12,7 +12,7 @@ $TRANSLATIONS = array( "Enable SSL" => "Activar SSL", "App key" => "Chave da aplicação", "App secret" => "Chave secreta da aplicação", -"URL" => "URL", +"Host" => "Endereço", "Username" => "Nome de utilizador", "Password" => "Palavra-passe", "Root" => "Raiz", @@ -20,6 +20,7 @@ $TRANSLATIONS = array( "Client secret" => "Segredo do cliente", "Username (required)" => "Utilizador (requerido)", "Share" => "Partilhar", +"URL" => "URL", "Remote subfolder" => "Sub-pasta remota ", "Access granted" => "Acesso autorizado", "Error configuring Dropbox storage" => "Erro ao configurar o armazenamento do Dropbox", diff --git a/apps/files_external/l10n/ro.php b/apps/files_external/l10n/ro.php index cc48e20ab08cd4f2057676027a963318634562f9..d5e1e90c54aeb1c9d829ce31e21c3d9030d1e2aa 100644 --- a/apps/files_external/l10n/ro.php +++ b/apps/files_external/l10n/ro.php @@ -1,10 +1,11 @@ "Locație", -"URL" => "URL", +"Host" => "Gazdă", "Username" => "Nume utilizator", "Password" => "Parolă", "Share" => "Partajează", +"URL" => "URL", "Access granted" => "Acces permis", "Error configuring Dropbox storage" => "Eroare la configurarea mediului de stocare Dropbox", "Grant access" => "Permite accesul", diff --git a/apps/files_external/l10n/ru.php b/apps/files_external/l10n/ru.php index be1307a9e6b3d3d39f2823ad9e789412ce458463..6aded8e9a31d2ac1c57cbcf67cc6e7c086d4a1f0 100644 --- a/apps/files_external/l10n/ru.php +++ b/apps/files_external/l10n/ru.php @@ -1,10 +1,12 @@ "Локально", "Location" => "Местоположение", -"URL" => "Ссылка", +"Host" => "Сервер", "Username" => "Имя пользователя", "Password" => "Пароль", "Share" => "Открыть доступ", +"URL" => "Ссылка", "Access granted" => "Доступ предоставлен", "Error configuring Dropbox storage" => "Ошибка при настройке хранилища Dropbox", "Grant access" => "Предоставление доступа", diff --git a/apps/files_external/l10n/si_LK.php b/apps/files_external/l10n/si_LK.php index 908f82d8ee931fc9dcde94fb7c13ca12e53ac0a6..960ededaa6378032c2dbd3c4772c321590658a73 100644 --- a/apps/files_external/l10n/si_LK.php +++ b/apps/files_external/l10n/si_LK.php @@ -1,10 +1,11 @@ "ස්ථානය", -"URL" => "URL", +"Host" => "සත්කාරකය", "Username" => "පරිශීලක නම", "Password" => "මුර පදය", "Share" => "බෙදා හදා ගන්න", +"URL" => "URL", "Access granted" => "පිවිසීමට හැක", "Error configuring Dropbox storage" => "Dropbox ගබඩාව වින්‍යාස කිරීමේ දෝශයක් ඇත", "Grant access" => "පිවිසුම ලබාදෙන්න", diff --git a/apps/files_external/l10n/sk_SK.php b/apps/files_external/l10n/sk_SK.php index e30b007c3cb8422f4f08df896192f9149e8183b0..f576d92cdac60b2d00d5dd94eaf079e1f738f627 100644 --- a/apps/files_external/l10n/sk_SK.php +++ b/apps/files_external/l10n/sk_SK.php @@ -2,10 +2,11 @@ $TRANSLATIONS = array( "Local" => "Lokálny", "Location" => "Umiestnenie", -"URL" => "URL", +"Host" => "Hostiteľ", "Username" => "Používateľské meno", "Password" => "Heslo", "Share" => "Zdieľať", +"URL" => "URL", "Access granted" => "Prístup povolený", "Error configuring Dropbox storage" => "Chyba pri konfigurácii úložiska Dropbox", "Grant access" => "Povoliť prístup", diff --git a/apps/files_external/l10n/sl.php b/apps/files_external/l10n/sl.php index eceffdfc6230c28fc4a6078d56b18b835461767e..c47e962b6e864c33771f62e4d0854caea94a0ba5 100644 --- a/apps/files_external/l10n/sl.php +++ b/apps/files_external/l10n/sl.php @@ -15,7 +15,7 @@ $TRANSLATIONS = array( "Enable Path Style" => "Omogoči slog poti", "App key" => "Programski ključ", "App secret" => "Skrivni programski ključ", -"URL" => "Naslov URL", +"Host" => "Gostitelj", "Username" => "Uporabniško ime", "Password" => "Geslo", "Root" => "Koren", @@ -26,6 +26,7 @@ $TRANSLATIONS = array( "Share" => "Souporaba", "SMB / CIFS using OC login" => "SMB / CIFS z uporabo prijave OC", "Username as share" => "Uporabniško ime za souporabo", +"URL" => "Naslov URL", "Secure https://" => "Varni način https://", "Remote subfolder" => "Oddaljena podrejena mapa", "Access granted" => "Dostop je odobren", diff --git a/apps/files_external/l10n/sq.php b/apps/files_external/l10n/sq.php index 563a1b7dd926ba8aa732f23b4bdf5743914e8afa..1904514fdc4791e70bef38a1e834ec200f6198c2 100644 --- a/apps/files_external/l10n/sq.php +++ b/apps/files_external/l10n/sq.php @@ -1,10 +1,11 @@ "Vendndodhja", -"URL" => "URL-i", +"Host" => "Pritësi", "Username" => "Përdoruesi", "Password" => "fjalëkalim", "Share" => "Ndaj", +"URL" => "URL-i", "Groups" => "Grupet", "Users" => "Përdoruesit", "Delete" => "Elimino" diff --git a/apps/files_external/l10n/sr.php b/apps/files_external/l10n/sr.php index b0276764a8dc296f52dd8716e50093a07beb19c9..bf150f5b5b0fb4472a9e9c67ed5bbae1f833f4ee 100644 --- a/apps/files_external/l10n/sr.php +++ b/apps/files_external/l10n/sr.php @@ -1,6 +1,7 @@ "Локација", +"Host" => "Домаћин", "Username" => "Корисничко име", "Password" => "Лозинка", "Share" => "Дели", diff --git a/apps/files_external/l10n/sv.php b/apps/files_external/l10n/sv.php index a15ea0ed164473ad545bc9330a8aaf56374119e3..a1c2a7cabead9ed168b9b8516be4905323f1ef69 100644 --- a/apps/files_external/l10n/sv.php +++ b/apps/files_external/l10n/sv.php @@ -2,10 +2,18 @@ $TRANSLATIONS = array( "Local" => "Lokal", "Location" => "Plats", -"URL" => "URL", +"Amazon S3" => "Amazon S3", +"Key" => "Nyckel", +"Secret" => "Hemlig", +"Enable SSL" => "Aktivera SSL", +"Host" => "Server", "Username" => "Användarnamn", "Password" => "Lösenord", +"Root" => "Root", +"Secure ftps://" => "Säker ftps://", "Share" => "Dela", +"URL" => "URL", +"Secure https://" => "Säker https://", "Access granted" => "Åtkomst beviljad", "Error configuring Dropbox storage" => "Fel vid konfigurering av Dropbox", "Grant access" => "Bevilja åtkomst", diff --git a/apps/files_external/l10n/ta_LK.php b/apps/files_external/l10n/ta_LK.php index 066cf411dd612cc981dc59d2af956571faad099e..a94b7417ff5ea1cff26aa138edc6a1a930622a57 100644 --- a/apps/files_external/l10n/ta_LK.php +++ b/apps/files_external/l10n/ta_LK.php @@ -1,10 +1,11 @@ "இடம்", -"URL" => "URL", +"Host" => "ஓம்புனர்", "Username" => "பயனாளர் பெயர்", "Password" => "கடவுச்சொல்", "Share" => "பகிர்வு", +"URL" => "URL", "Access granted" => "அனுமதி வழங்கப்பட்டது", "Error configuring Dropbox storage" => "Dropbox சேமிப்பை தகவமைப்பதில் வழு", "Grant access" => "அனுமதியை வழங்கல்", diff --git a/apps/files_external/l10n/th_TH.php b/apps/files_external/l10n/th_TH.php index 3edf8c6382427236ecbee258f17c2d30f1e81a70..9f393a2546f46dd9878d1fe55433a9c9f4801735 100644 --- a/apps/files_external/l10n/th_TH.php +++ b/apps/files_external/l10n/th_TH.php @@ -1,10 +1,11 @@ "ตำแหน่งที่อยู่", -"URL" => "URL", +"Host" => "โฮสต์", "Username" => "ชื่อผู้ใช้งาน", "Password" => "รหัสผ่าน", "Share" => "แชร์", +"URL" => "URL", "Access granted" => "การเข้าถึงได้รับอนุญาตแล้ว", "Error configuring Dropbox storage" => "เกิดข้อผิดพลาดในการกำหนดค่าพื้นที่จัดเก็บข้อมูล Dropbox", "Grant access" => "อนุญาตให้เข้าถึงได้", diff --git a/apps/files_external/l10n/tr.php b/apps/files_external/l10n/tr.php index aa3290bd4bca936a4a63cca5ec0cf5abd32f6102..5af8813e675ddd432a73e48bc0133c97a99d1385 100644 --- a/apps/files_external/l10n/tr.php +++ b/apps/files_external/l10n/tr.php @@ -16,7 +16,7 @@ $TRANSLATIONS = array( "Enable Path Style" => "Yol Biçemini Etkinleştir", "App key" => "Uyg. anahtarı", "App secret" => "Uyg. parolası", -"URL" => "URL", +"Host" => "Sunucu", "Username" => "Kullanıcı Adı:", "Password" => "Parola:", "Root" => "Kök", @@ -36,6 +36,7 @@ $TRANSLATIONS = array( "Share" => "Paylaş", "SMB / CIFS using OC login" => "OC oturumu kullanarak SMB / CIFS", "Username as share" => "Paylaşım olarak kullanıcı adı", +"URL" => "URL", "Secure https://" => "Güvenli https://", "Remote subfolder" => "Uzak alt klasör", "Access granted" => "Giriş kabul edildi", diff --git a/apps/files_external/l10n/ug.php b/apps/files_external/l10n/ug.php index bd7dc4298650328383a787a7605d70af0f8c6154..701a5457ae2e762cfcd946841903f63dcbd2e755 100644 --- a/apps/files_external/l10n/ug.php +++ b/apps/files_external/l10n/ug.php @@ -1,10 +1,11 @@ "ئورنى", -"URL" => "URL", +"Host" => "باش ئاپپارات", "Username" => "ئىشلەتكۈچى ئاتى", "Password" => "ئىم", "Share" => "ھەمبەھىر", +"URL" => "URL", "Folder name" => "قىسقۇچ ئاتى", "External storage" => "سىرتقى ساقلىغۇچ", "Configuration" => "سەپلىمە", diff --git a/apps/files_external/l10n/uk.php b/apps/files_external/l10n/uk.php index f644fe8606329d86f5b67141e7fbb310ec987f84..aea352a6863ee2f9df79a1c9bff96bc834b77393 100644 --- a/apps/files_external/l10n/uk.php +++ b/apps/files_external/l10n/uk.php @@ -1,10 +1,11 @@ "Місце", -"URL" => "URL", +"Host" => "Хост", "Username" => "Ім'я користувача", "Password" => "Пароль", "Share" => "Поділитися", +"URL" => "URL", "Access granted" => "Доступ дозволено", "Error configuring Dropbox storage" => "Помилка при налаштуванні сховища Dropbox", "Grant access" => "Дозволити доступ", diff --git a/apps/files_external/l10n/ur_PK.php b/apps/files_external/l10n/ur_PK.php index e2138b9046b15f4822ebddfe89411c7869f2cd2e..5d4695b5115839d356d3c4d51d123b6abeb5a098 100644 --- a/apps/files_external/l10n/ur_PK.php +++ b/apps/files_external/l10n/ur_PK.php @@ -1,7 +1,11 @@ "مقام", "Username" => "یوزر نیم", "Password" => "پاسورڈ", -"Users" => "یوزرز" +"Share" => "تقسیم", +"URL" => "یو ار ایل", +"Users" => "یوزرز", +"Delete" => "حذف کریں" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_external/l10n/vi.php b/apps/files_external/l10n/vi.php index 86d1236f665fab00fb66fa921d2af31637eb5533..03d50bc1433c740fff815b158be6abdc9cb0104b 100644 --- a/apps/files_external/l10n/vi.php +++ b/apps/files_external/l10n/vi.php @@ -1,10 +1,11 @@ "Vị trí", -"URL" => "URL", +"Host" => "Máy chủ", "Username" => "Tên đăng nhập", "Password" => "Mật khẩu", "Share" => "Chia sẻ", +"URL" => "URL", "Access granted" => "Đã cấp quyền truy cập", "Error configuring Dropbox storage" => "Lỗi cấu hình lưu trữ Dropbox ", "Grant access" => "Cấp quyền truy cập", diff --git a/apps/files_external/l10n/zh_CN.php b/apps/files_external/l10n/zh_CN.php index 53e76d1dd7bac472cb8e7f41b06109e9f521398a..95e9c0e643eb6885bf81ced9f8063825154fe57d 100644 --- a/apps/files_external/l10n/zh_CN.php +++ b/apps/files_external/l10n/zh_CN.php @@ -8,13 +8,14 @@ $TRANSLATIONS = array( "Port (optional)" => "端口 (可选)", "Region (optional)" => "区域 (optional)", "Enable SSL" => "启用 SSL", -"URL" => "URL", +"Host" => "主机", "Username" => "用户名", "Password" => "密码", "Root" => "根路径", "Secure ftps://" => "安全 ftps://", "Share" => "共享", "SMB / CIFS using OC login" => "SMB / CIFS 使用 OC 登录信息", +"URL" => "URL", "Secure https://" => "安全 https://", "Remote subfolder" => "远程子文件夹", "Access granted" => "权限已授予。", diff --git a/apps/files_external/l10n/zh_HK.php b/apps/files_external/l10n/zh_HK.php index b3a22c91bb2836bf8c2fd76761f7fb6cf4f02a23..5a1544694872fd48c9006289b4b47a7910acf7fe 100644 --- a/apps/files_external/l10n/zh_HK.php +++ b/apps/files_external/l10n/zh_HK.php @@ -1,9 +1,9 @@ "網址", "Username" => "用戶名稱", "Password" => "密碼", "Share" => "分享", +"URL" => "網址", "Folder name" => "資料夾名稱", "Groups" => "群組", "Users" => "用戶", diff --git a/apps/files_external/l10n/zh_TW.php b/apps/files_external/l10n/zh_TW.php index a4b0ebe4dd53918397df85353356a29e2e32b120..154009f7a18306c4ab6fa65baa975898364c86ad 100644 --- a/apps/files_external/l10n/zh_TW.php +++ b/apps/files_external/l10n/zh_TW.php @@ -2,10 +2,11 @@ $TRANSLATIONS = array( "Local" => "本地", "Location" => "地點", -"URL" => "URL", +"Host" => "主機", "Username" => "使用者名稱:", "Password" => "密碼", "Share" => "分享", +"URL" => "URL", "Access granted" => "允許存取", "Error configuring Dropbox storage" => "設定 Dropbox 儲存時發生錯誤", "Grant access" => "允許存取", diff --git a/apps/files_external/lib/amazons3.php b/apps/files_external/lib/amazons3.php index 2093fb7e58cf7aadf249db84cc9614fb904d4cb8..7ff17f0e98a3f371d7a0d823f931966fe54af6bb 100644 --- a/apps/files_external/lib/amazons3.php +++ b/apps/files_external/lib/amazons3.php @@ -25,7 +25,7 @@ namespace OC\Files\Storage; set_include_path(get_include_path() . PATH_SEPARATOR . - \OC_App::getAppPath('files_external') . '/3rdparty/aws-sdk-php'); + \OC_App::getAppPath('files_external') . '/3rdparty/aws-sdk-php'); require 'aws-autoloader.php'; use Aws\S3\S3Client; diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index 15fbda927e0fde8e1040974ff02875d690d1f7d5..7a651239cb48ae2609dba0b72b4a0718bdd50800 100755 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -359,10 +359,10 @@ class OC_Mount_Config { * Add a mount point to the filesystem * @param string $mountPoint Mount point * @param string $class Backend class - * @param array Backend parameters for the class + * @param array $classOptions Backend parameters for the class * @param string $mountType MOUNT_TYPE_GROUP | MOUNT_TYPE_USER * @param string $applicable User or group to apply mount to - * @param bool Personal or system mount point i.e. is this being called from the personal or admin page + * @param bool $isPersonal Personal or system mount point i.e. is this being called from the personal or admin page * @return boolean */ public static function addMountPoint($mountPoint, @@ -400,28 +400,20 @@ class OC_Mount_Config { 'options' => self::encryptPasswords($classOptions)) ) ); + $mountPoints = self::readData($isPersonal ? OCP\User::getUser() : NULL); - // Merge the new mount point into the current mount points - if (isset($mountPoints[$mountType])) { - if (isset($mountPoints[$mountType][$applicable])) { - $mountPoints[$mountType][$applicable] - = array_merge($mountPoints[$mountType][$applicable], $mount[$applicable]); - } else { - $mountPoints[$mountType] = array_merge($mountPoints[$mountType], $mount); - } - } else { - $mountPoints[$mountType] = $mount; - } + $mountPoints = self::mergeMountPoints($mountPoints, $mount, $mountType); self::writeData($isPersonal ? OCP\User::getUser() : NULL, $mountPoints); + return self::getBackendStatus($class, $classOptions, $isPersonal); } /** * - * @param string Mount point - * @param string MOUNT_TYPE_GROUP | MOUNT_TYPE_USER - * @param string User or group to remove mount from - * @param bool Personal or system mount point + * @param string $mountPoint Mount point + * @param string $mountType MOUNT_TYPE_GROUP | MOUNT_TYPE_USER + * @param string $applicable User or group to remove mount from + * @param bool $isPersonal Personal or system mount point * @return bool */ public static function removeMountPoint($mountPoint, $mountType, $applicable, $isPersonal = false) { @@ -618,9 +610,9 @@ class OC_Mount_Config { /** * Returns a dependency missing message - * @param $l OC_L10N - * @param $module string - * @param $backend string + * @param OC_L10N $l + * @param string $module + * @param string $backend * @return string */ private static function getSingleDependencyMessage($l, $module, $backend) { @@ -666,7 +658,7 @@ class OC_Mount_Config { /** * Encrypt a single password * @param string $password plain text password - * @return encrypted password + * @return string encrypted password */ private static function encryptPassword($password) { $cipher = self::getCipher(); @@ -678,7 +670,7 @@ class OC_Mount_Config { /** * Decrypts a single password * @param string $encryptedPassword encrypted password - * @return plain text password + * @return string plain text password */ private static function decryptPassword($encryptedPassword) { $cipher = self::getCipher(); @@ -689,6 +681,28 @@ class OC_Mount_Config { return $cipher->decrypt($binaryPassword); } + /** + * Merges mount points + * @param array $data Existing mount points + * @param array $mountPoint New mount point + * @param string $mountType + * @return array + */ + private static function mergeMountPoints($data, $mountPoint, $mountType) { + $applicable = key($mountPoint); + if (isset($data[$mountType])) { + if (isset($data[$mountType][$applicable])) { + $data[$mountType][$applicable] + = array_merge($data[$mountType][$applicable], $mountPoint[$applicable]); + } else { + $data[$mountType] = array_merge($data[$mountType], $mountPoint); + } + } else { + $data[$mountType] = $mountPoint; + } + return $data; + } + /** * Returns the encryption cipher */ diff --git a/apps/files_external/lib/dropbox.php b/apps/files_external/lib/dropbox.php index 38de3360f2b40c348427e5c15a04774ebd67a33f..0b624b27176959937d5b6023ca453ecdc71118fe 100755 --- a/apps/files_external/lib/dropbox.php +++ b/apps/files_external/lib/dropbox.php @@ -63,10 +63,10 @@ class Dropbox extends \OC\Files\Storage\Common { } /** - * @brief Returns the path's metadata + * Returns the path's metadata * @param string $path path for which to return the metadata - * @param $list if true, also return the directory's contents - * @return directory contents if $list is true, file metadata if $list is + * @param bool $list if true, also return the directory's contents + * @return mixed directory contents if $list is true, file metadata if $list is * false, null if the file doesn't exist or "false" if the operation failed */ private function getMetaData($path, $list = false) { diff --git a/apps/files_external/lib/ftp.php b/apps/files_external/lib/ftp.php index b3f8b1444ae5d599de0ba504f8d2689adde0ca81..2650a94f85ef33656f7ae68f59a9609ff65954b9 100644 --- a/apps/files_external/lib/ftp.php +++ b/apps/files_external/lib/ftp.php @@ -64,7 +64,7 @@ class FTP extends \OC\Files\Storage\StreamWrapper{ /** * Unlinks file or directory - * @param string @path + * @param string $path */ public function unlink($path) { if ($this->is_dir($path)) { diff --git a/apps/files_external/lib/smb.php b/apps/files_external/lib/smb.php index b1d355323d9a078df9948f94367c0dc91ad6abb0..6e53c4a99310c9805ac8b5e76b886cb3a91bf4a8 100644 --- a/apps/files_external/lib/smb.php +++ b/apps/files_external/lib/smb.php @@ -83,7 +83,7 @@ class SMB extends \OC\Files\Storage\StreamWrapper{ /** * Unlinks file or directory - * @param string @path + * @param string $path */ public function unlink($path) { if ($this->is_dir($path)) { diff --git a/apps/files_external/lib/swift.php b/apps/files_external/lib/swift.php index a202d3843cb212925b5ba82b5cea18064b653857..03364867b0c69829d4980d6270fbe5dcb425ca05 100644 --- a/apps/files_external/lib/swift.php +++ b/apps/files_external/lib/swift.php @@ -23,7 +23,7 @@ namespace OC\Files\Storage; set_include_path(get_include_path() . PATH_SEPARATOR . - \OC_App::getAppPath('files_external') . '/3rdparty/php-opencloud/lib'); + \OC_App::getAppPath('files_external') . '/3rdparty/php-opencloud/lib'); require_once 'openstack.php'; use \OpenCloud; @@ -31,25 +31,25 @@ use \OpenCloud\Common\Exceptions; class Swift extends \OC\Files\Storage\Common { - /** - * @var \OpenCloud\ObjectStore - */ + /** + * @var \OpenCloud\ObjectStore + */ private $connection; - /** - * @var \OpenCloud\ObjectStore\Container - */ + /** + * @var \OpenCloud\ObjectStore\Container + */ private $container; - /** - * @var \OpenCloud\OpenStack - */ + /** + * @var \OpenCloud\OpenStack + */ private $anchor; - /** - * @var string - */ + /** + * @var string + */ private $bucket; - /** - * @var array - */ + /** + * @var array + */ private static $tmpFiles = array(); /** diff --git a/apps/files_sharing/ajax/list.php b/apps/files_sharing/ajax/list.php index 4b645496253f704567b31e5895289e82dac105b0..82bacb3d38de4a41f141fbf8d62d2992097a757e 100644 --- a/apps/files_sharing/ajax/list.php +++ b/apps/files_sharing/ajax/list.php @@ -20,11 +20,6 @@ * */ -// only need filesystem apps -$RUNTIME_APPTYPES=array('filesystem'); - -// Init owncloud - if(!\OC_App::isEnabled('files_sharing')){ exit; } @@ -47,6 +42,9 @@ if (isset($_GET['dir'])) { $relativePath = $_GET['dir']; } +$sortAttribute = isset( $_GET['sort'] ) ? $_GET['sort'] : 'name'; +$sortDirection = isset( $_GET['sortdirection'] ) ? ($_GET['sortdirection'] === 'desc') : false; + $data = \OCA\Files_Sharing\Helper::setupFromToken($token, $relativePath, $password); $linkItem = $data['linkItem']; @@ -64,7 +62,7 @@ $data = array(); $baseUrl = OCP\Util::linkTo('files_sharing', 'index.php') . '?t=' . urlencode($token) . '&dir='; // make filelist -$files = \OCA\Files\Helper::getFiles($dir); +$files = \OCA\Files\Helper::getFiles($dir, $sortAttribute, $sortDirection); $formattedFiles = array(); foreach ($files as $file) { diff --git a/apps/files_sharing/css/public.css b/apps/files_sharing/css/public.css index 67d847019462d77f6ed4a7e1544d11eb38b8c39a..70897af9eb9785991c202e7d179ed8e82afbaa07 100644 --- a/apps/files_sharing/css/public.css +++ b/apps/files_sharing/css/public.css @@ -1,7 +1,3 @@ -#controls { - left: 0; -} - #preview { background: #fff; text-align: center; diff --git a/apps/files_sharing/js/public.js b/apps/files_sharing/js/public.js index 0b4dec817643ae7f5d03732ba9365f4ad64c5047..d3d4479215efa77e93c2726a7f9e34d7142b1cf1 100644 --- a/apps/files_sharing/js/public.js +++ b/apps/files_sharing/js/public.js @@ -8,95 +8,164 @@ * */ -/* global OC, FileActions, FileList, Files */ +/* global FileActions, Files */ +/* global dragOptions, folderDropOptions */ +OCA.Sharing = {}; +if (!OCA.Files) { + OCA.Files = {}; +} +OCA.Sharing.PublicApp = { + _initialized: false, -$(document).ready(function() { + initialize: function($el) { + if (this._initialized) { + return; + } + this._initialized = true; + // file list mode ? + if ($el.find('#filestable')) { + this.fileList = new OCA.Files.FileList( + $el, + { + scrollContainer: $(window), + dragOptions: dragOptions, + folderDropOptions: folderDropOptions + } + ); + this.files = OCA.Files.Files; + this.files.initialize(); + } - var mimetype = $('#mimetype').val(); + var mimetype = $('#mimetype').val(); - if (typeof FileActions !== 'undefined') { - // Show file preview if previewer is available, images are already handled by the template - if (mimetype.substr(0, mimetype.indexOf('/')) !== 'image' && $('.publicpreview').length === 0) { - // Trigger default action if not download TODO - var action = FileActions.getDefault(mimetype, 'file', OC.PERMISSION_READ); - if (typeof action !== 'undefined') { - action($('#filename').val()); + if (typeof FileActions !== 'undefined') { + // Show file preview if previewer is available, images are already handled by the template + if (mimetype.substr(0, mimetype.indexOf('/')) !== 'image' && $('.publicpreview').length === 0) { + // Trigger default action if not download TODO + var action = FileActions.getDefault(mimetype, 'file', OC.PERMISSION_READ); + if (typeof action !== 'undefined') { + action($('#filename').val()); + } } } - } - // dynamically load image previews - if (mimetype.substr(0, mimetype.indexOf('/')) === 'image' ) { + // dynamically load image previews + if (mimetype.substr(0, mimetype.indexOf('/')) === 'image' ) { - var params = { - x: $(document).width() * window.devicePixelRatio, - a: 'true', - file: encodeURIComponent($('#dir').val() + $('#filename').val()), - t: $('#sharingToken').val() - }; + var params = { + x: $(document).width() * window.devicePixelRatio, + a: 'true', + file: encodeURIComponent($('#dir').val() + $('#filename').val()), + t: $('#sharingToken').val() + }; - var img = $(''); - img.attr('src', OC.filePath('files_sharing', 'ajax', 'publicpreview.php') + '?' + OC.buildQueryString(params)); - img.appendTo('#imgframe'); - } + var img = $(''); + img.attr('src', OC.filePath('files_sharing', 'ajax', 'publicpreview.php') + '?' + OC.buildQueryString(params)); + img.appendTo('#imgframe'); + } - // override since the format is different - if (typeof Files !== 'undefined') { - Files.getDownloadUrl = function(filename, dir) { - if ($.isArray(filename)) { - filename = JSON.stringify(filename); - } - var path = dir || FileList.getCurrentDirectory(); - var params = { - service: 'files', - t: $('#sharingToken').val(), - path: path, - files: filename, - download: null + if (this.fileList) { + // TODO: move this to a separate PublicFileList class that extends OCA.Files.FileList (+ unit tests) + this.fileList.getDownloadUrl = function(filename, dir) { + if ($.isArray(filename)) { + filename = JSON.stringify(filename); + } + var path = dir || FileList.getCurrentDirectory(); + var params = { + service: 'files', + t: $('#sharingToken').val(), + path: path, + files: filename, + download: null + }; + return OC.filePath('', '', 'public.php') + '?' + OC.buildQueryString(params); }; - return OC.filePath('', '', 'public.php') + '?' + OC.buildQueryString(params); - }; - Files.getAjaxUrl = function(action, params) { - params = params || {}; - params.t = $('#sharingToken').val(); - return OC.filePath('files_sharing', 'ajax', action + '.php') + '?' + OC.buildQueryString(params); - }; + this.fileList.getAjaxUrl = function(action, params) { + params = params || {}; + params.t = $('#sharingToken').val(); + return OC.filePath('files_sharing', 'ajax', action + '.php') + '?' + OC.buildQueryString(params); + }; - FileList.linkTo = function(dir) { - var params = { - service: 'files', - t: $('#sharingToken').val(), - dir: dir + this.fileList.linkTo = function(dir) { + var params = { + service: 'files', + t: $('#sharingToken').val(), + dir: dir + }; + return OC.filePath('', '', 'public.php') + '?' + OC.buildQueryString(params); }; - return OC.filePath('', '', 'public.php') + '?' + OC.buildQueryString(params); - }; - - Files.generatePreviewUrl = function(urlSpec) { - urlSpec.t = $('#dirToken').val(); - return OC.generateUrl('/apps/files_sharing/ajax/publicpreview.php?') + $.param(urlSpec); - }; - - var file_upload_start = $('#file_upload_start'); - file_upload_start.on('fileuploadadd', function(e, data) { - var fileDirectory = ''; - if(typeof data.files[0].relativePath !== 'undefined') { - fileDirectory = data.files[0].relativePath; - } - // Add custom data to the upload handler - data.formData = { - requesttoken: $('#publicUploadRequestToken').val(), - dirToken: $('#dirToken').val(), - subdir: $('input#dir').val(), - file_directory: fileDirectory + this.fileList.generatePreviewUrl = function(urlSpec) { + urlSpec.t = $('#dirToken').val(); + return OC.generateUrl('/apps/files_sharing/ajax/publicpreview.php?') + $.param(urlSpec); }; + + var file_upload_start = $('#file_upload_start'); + file_upload_start.on('fileuploadadd', function(e, data) { + var fileDirectory = ''; + if(typeof data.files[0].relativePath !== 'undefined') { + fileDirectory = data.files[0].relativePath; + } + + // Add custom data to the upload handler + data.formData = { + requesttoken: $('#publicUploadRequestToken').val(), + dirToken: $('#dirToken').val(), + subdir: $('input#dir').val(), + file_directory: fileDirectory + }; + }); + + this.fileActions = _.extend({}, OCA.Files.FileActions); + this.fileActions.registerDefaultActions(this.fileList); + delete this.fileActions.actions.all.Share; + this.fileList.setFileActions(this.fileActions); + + this.fileList.changeDirectory($('#dir').val() || '/', false, true); + + // URL history handling + this.fileList.$el.on('changeDirectory', _.bind(this._onDirectoryChanged, this)); + OC.Util.History.addOnPopStateHandler(_.bind(this._onUrlChanged, this)); + } + + $(document).on('click', '#directLink', function() { + $(this).focus(); + $(this).select(); }); + + // legacy + window.FileList = this.fileList; + }, + + _onDirectoryChanged: function(e) { + OC.Util.History.pushState({ + service: 'files', + t: $('#sharingToken').val(), + // arghhhh, why is this not called "dir" !? + path: e.dir + }); + }, + + _onUrlChanged: function(params) { + this.fileList.changeDirectory(params.path || params.dir, false, true); } +}; - $(document).on('click', '#directLink', function() { - $(this).focus(); - $(this).select(); - }); +$(document).ready(function() { + var App = OCA.Sharing.PublicApp; + App.initialize($('#preview')); + // HACK: for oc-dialogs previews that depends on Files: + Files.lazyLoadPreview = function(path, mime, ready, width, height, etag) { + return App.fileList.lazyLoadPreview({ + path: path, + mime: mime, + callback: ready, + width: width, + height: height, + etag: etag + }); + }; }); + diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js index 3c7c9239a6cbf3f870a3a253936ffeb27983210d..973c63c5d7e332e1c13559f7402111ddb7a29476 100644 --- a/apps/files_sharing/js/share.js +++ b/apps/files_sharing/js/share.js @@ -8,15 +8,15 @@ * */ -/* global OC, t, FileList, FileActions */ +/* global FileList, FileActions */ $(document).ready(function() { - var disableSharing = $('#disableSharing').data('status'), - sharesLoaded = false; + var sharesLoaded = false; - if (typeof OC.Share !== 'undefined' && typeof FileActions !== 'undefined' && !disableSharing) { - var oldCreateRow = FileList._createRow; - FileList._createRow = function(fileData) { + if (typeof OC.Share !== 'undefined' && typeof FileActions !== 'undefined') { + // TODO: make a separate class for this or a hook or jQuery event ? + var oldCreateRow = OCA.Files.FileList.prototype._createRow; + OCA.Files.FileList.prototype._createRow = function(fileData) { var tr = oldCreateRow.apply(this, arguments); if (fileData.shareOwner) { tr.attr('data-share-owner', fileData.shareOwner); @@ -25,14 +25,16 @@ $(document).ready(function() { }; $('#fileList').on('fileActionsReady',function(){ - - var allShared = $('#fileList').find('[data-share-owner] [data-Action="Share"]'); + var $fileList = $(this); + var allShared = $fileList.find('[data-share-owner] [data-Action="Share"]'); allShared.addClass('permanent'); allShared.find('span').text(function(){ var $owner = $(this).closest('tr').attr('data-share-owner'); return ' ' + t('files_sharing', 'Shared by {owner}', {owner: $owner}); }); + // FIXME: these calls are also working on hard-coded + // list selectors... if (!sharesLoaded){ OC.Share.loadIcons('file'); // assume that we got all shares, so switching directories diff --git a/apps/files_sharing/l10n/ast.php b/apps/files_sharing/l10n/ast.php index 2dd8b0e1f64fec686b15a124f6408b364542de77..fa3704ea6ba952ee11c55a72fd1e19f66d9237a2 100644 --- a/apps/files_sharing/l10n/ast.php +++ b/apps/files_sharing/l10n/ast.php @@ -4,12 +4,12 @@ $TRANSLATIONS = array( "This share is password-protected" => "Esta compartición tien contraseña protexida", "The password is wrong. Try again." => "La contraseña ye incorreuta. Inténtalo otra vegada.", "Password" => "Contraseña", -"Sorry, this link doesn’t seem to work anymore." => "Sentímoslo, esti enllaz paez que ya nun furrula.", +"Sorry, this link doesn’t seem to work anymore." => "Sentímoslo, esti enllaz paez que yá nun furrula.", "Reasons might be:" => "Les razones pueden ser: ", -"the item was removed" => "esti elementu ta desaniciáu", -"the link expired" => "l'enllaz finó", +"the item was removed" => "desanicióse l'elementu", +"the link expired" => "l'enllaz caducó", "sharing is disabled" => "compartir ta desactiváu", -"For more info, please ask the person who sent this link." => "Para más información, entruga-y a la persona qu'unvió esti enllaz", +"For more info, please ask the person who sent this link." => "Pa más información, entrúga-y a la persona qu'unvió esti enllaz", "Download" => "Baxar", "Download %s" => "Descargar %s", "Direct link" => "Enllaz direutu" diff --git a/apps/files_sharing/l10n/fa.php b/apps/files_sharing/l10n/fa.php index 1176401f1a30023e1f5dde3d03d1897386c7c495..fb6a4bc87098af7d1306b5e36ee1cfa366dfffb2 100644 --- a/apps/files_sharing/l10n/fa.php +++ b/apps/files_sharing/l10n/fa.php @@ -1,8 +1,17 @@ "اشتراک گذارنده {owner}", +"This share is password-protected" => "این اشتراک توسط رمز عبور محافظت می شود", "The password is wrong. Try again." => "رمزعبور اشتباه می باشد. دوباره امتحان کنید.", "Password" => "گذرواژه", -"Download" => "دانلود" +"Sorry, this link doesn’t seem to work anymore." => "متاسفانه این پیوند دیگر کار نمی کند", +"Reasons might be:" => "ممکن است به این دلایل باشد:", +"the item was removed" => "این مورد حذف شده است", +"the link expired" => "این پیوند منقضی شده است", +"sharing is disabled" => "قابلیت اشتراک گذاری غیرفعال است", +"For more info, please ask the person who sent this link." => "برای اطلاعات بیشتر، لطفا از شخصی که این پیوند را ارسال کرده سوال بفرمایید.", +"Download" => "دانلود", +"Download %s" => "دانلود %s", +"Direct link" => "پیوند مستقیم" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files_sharing/l10n/km.php b/apps/files_sharing/l10n/km.php index db353c9cb7486bab848fa80fc8854ee27ad1b0cf..75f5679d97a37016b9ecd20212a7ad05a83393e8 100644 --- a/apps/files_sharing/l10n/km.php +++ b/apps/files_sharing/l10n/km.php @@ -1,6 +1,17 @@ "{owner} បាន​ចែក​រំលែក", +"This share is password-protected" => "ការ​ចែករំលែក​នេះ​ត្រូវ​បាន​ការពារ​ដោយ​ពាក្យ​សម្ងាត់", +"The password is wrong. Try again." => "ពាក្យ​សម្ងាត់​ខុស​ហើយ។ ព្យាយាម​ម្ដង​ទៀត។", "Password" => "ពាក្យសម្ងាត់", -"Download" => "ទាញយក" +"Sorry, this link doesn’t seem to work anymore." => "សូម​ទោស តំណ​នេះ​ហាក់​ដូច​ជា​លែង​ដើរ​ហើយ។", +"Reasons might be:" => "មូលហេតុ​អាច​ជា៖", +"the item was removed" => "របស់​ត្រូវ​បាន​ដក​ចេញ", +"the link expired" => "តំណ​ផុត​ពេល​កំណត់", +"sharing is disabled" => "មិន​អនុញ្ញាត​ការ​ចែករំលែក", +"For more info, please ask the person who sent this link." => "សម្រាប់​ព័ត៌មាន​បន្ថែម សូម​សួរ​អ្នក​ដែល​ផ្ញើ​តំណ​នេះ។", +"Download" => "ទាញយក", +"Download %s" => "ទាញយក %s", +"Direct link" => "តំណ​ផ្ទាល់" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files_sharing/lib/api.php b/apps/files_sharing/lib/api.php index 438d3cc4ba3702e23cc698b201b2a64275ff2866..21fd5d00a4ce227c1c79f2093323e1824d610e6a 100644 --- a/apps/files_sharing/lib/api.php +++ b/apps/files_sharing/lib/api.php @@ -25,7 +25,7 @@ namespace OCA\Files\Share; class Api { /** - * @brief get all shares + * get all shares * * @param array $params option 'file' to limit the result to a specific file/folder * @return \OC_OCS_Result share information @@ -60,7 +60,7 @@ class Api { } /** - * @brief get share information for a given share + * get share information for a given share * * @param array $params which contains a 'id' * @return \OC_OCS_Result share information @@ -76,7 +76,7 @@ class Api { } /** - * @brief collect all share information, either of a specific share or all + * collect all share information, either of a specific share or all * shares for a given path * @param array $params * @return \OC_OCS_Result @@ -130,7 +130,7 @@ class Api { } /** - * @brief add reshares to a array of shares + * add reshares to a array of shares * @param array $shares array of shares * @param int $itemSource item source ID * @return array new shares array which includes reshares @@ -161,7 +161,7 @@ class Api { } /** - * @brief get share from all files in a given folder (non-recursive) + * get share from all files in a given folder (non-recursive) * @param array $params contains 'path' to the folder * @return \OC_OCS_Result */ @@ -196,7 +196,7 @@ class Api { } /** - * @breif create a new share + * create a new share * @param array $params * @return \OC_OCS_Result */ @@ -313,7 +313,7 @@ class Api { } /** - * @brief update permissions for a share + * update permissions for a share * @param array $share information about the share * @param array $params contains 'permissions' * @return \OC_OCS_Result @@ -358,7 +358,7 @@ class Api { } /** - * @brief enable/disable public upload + * enable/disable public upload * @param array $share information about the share * @param array $params contains 'publicUpload' which can be 'yes' or 'no' * @return \OC_OCS_Result @@ -384,9 +384,9 @@ class Api { } /** - * @brief update password for public link share + * update password for public link share * @param array $share information about the share - * @param type $params 'password' + * @param array $params 'password' * @return \OC_OCS_Result */ private static function updatePassword($share, $params) { @@ -418,13 +418,18 @@ class Api { return new \OC_OCS_Result(null, 404, "share doesn't exists, can't change password"); } - $result = \OCP\Share::shareItem( - $itemType, - $itemSource, - \OCP\Share::SHARE_TYPE_LINK, - $shareWith, - $permissions - ); + try { + $result = \OCP\Share::shareItem( + $itemType, + $itemSource, + \OCP\Share::SHARE_TYPE_LINK, + $shareWith, + $permissions + ); + } catch (\Exception $e) { + return new \OC_OCS_Result(null, 403, $e->getMessage()); + } + if($result) { return new \OC_OCS_Result(); } @@ -433,7 +438,7 @@ class Api { } /** - * @brief unshare a file/folder + * unshare a file/folder * @param array $params contains the shareID 'id' which should be unshared * @return \OC_OCS_Result */ @@ -473,7 +478,7 @@ class Api { } /** - * @brief get file ID from a given path + * get file ID from a given path * @param string $path * @return string fileID or null */ @@ -490,7 +495,7 @@ class Api { } /** - * @brief get itemType + * get itemType * @param string $path * @return string type 'file', 'folder' or null of file/folder doesn't exists */ @@ -508,7 +513,7 @@ class Api { } /** - * @brief get some information from a given share + * get some information from a given share * @param int $shareID * @return array with: item_source, share_type, share_with, item_type, permissions */ diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index f74315c85f9990bd1a9ca61201a7c391d55bf98c..9d83ed13b87a2be161611303e97a1a918d68ac4d 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -42,7 +42,7 @@ class Shared_Cache extends Cache { } /** - * @brief Get the source cache of a shared file or folder + * Get the source cache of a shared file or folder * @param string $target Shared target file path * @return \OC\Files\Cache\Cache */ @@ -80,7 +80,7 @@ class Shared_Cache extends Cache { /** * get the stored metadata of a file or folder * - * @param string /int $file + * @param string|int $file * @return array */ public function get($file) { @@ -424,7 +424,7 @@ class Shared_Cache extends Cache { * * @param int $id * @param string $pathEnd (optional) used internally for recursive calls - * @return string | null + * @return string|null */ public function getPathById($id, $pathEnd = '') { // direct shares are easy diff --git a/apps/files_sharing/lib/helper.php b/apps/files_sharing/lib/helper.php index dd4056b48f1ed0095a3825bf303177df4164d3c0..71b496ab944dd069aaa101a52426aa435b45bdb1 100644 --- a/apps/files_sharing/lib/helper.php +++ b/apps/files_sharing/lib/helper.php @@ -162,7 +162,7 @@ class Helper { } /** - * @brief Format a path to be relative to the /user/files/ directory + * Format a path to be relative to the /user/files/ directory * @param string $path the absolute path * @return string e.g. turns '/admin/files/test.txt' into 'test.txt' */ diff --git a/apps/files_sharing/lib/maintainer.php b/apps/files_sharing/lib/maintainer.php index bbb3268410e641a9309edf7e0f828b2ceb530976..f07c09e5aee48b85f1b079623d785f07d3d6cd6e 100644 --- a/apps/files_sharing/lib/maintainer.php +++ b/apps/files_sharing/lib/maintainer.php @@ -33,7 +33,7 @@ class Maintainer { * Keeps track of the "allow links" config setting * and removes all link shares if the config option is set to "no" * - * @param array with app, key, value as named values + * @param array $params array with app, key, value as named values */ static public function configChangeHook($params) { if($params['app'] === 'core' && $params['key'] === 'shareapi_allow_links' && $params['value'] === 'no') { diff --git a/apps/files_sharing/lib/share/file.php b/apps/files_sharing/lib/share/file.php index 9950b4d61fde712098c268d58df3015aeb20ddca..af71786b10466538cf91a91b8f556519f8a0ef1e 100644 --- a/apps/files_sharing/lib/share/file.php +++ b/apps/files_sharing/lib/share/file.php @@ -54,7 +54,7 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent { } /** - * @brief create unique target + * create unique target * @param string $filePath * @param string $shareWith * @param string $exclude @@ -154,7 +154,7 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent { } /** - * @brief resolve reshares to return the correct source item + * resolve reshares to return the correct source item * @param array $source * @return array source item */ diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index d4a817fca3461c462fffe005593c5226b918a149..4b69276d05a2e9daf45fabda71ee4b369d301567 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -36,7 +36,7 @@ class Shared extends \OC\Files\Storage\Common { } /** - * @breif get id of the mount point + * get id of the mount point * @return string */ public function getId() { @@ -44,7 +44,7 @@ class Shared extends \OC\Files\Storage\Common { } /** - * @breif get file cache of the shared item source + * get file cache of the shared item source * @return string */ public function getSourceId() { @@ -52,9 +52,8 @@ class Shared extends \OC\Files\Storage\Common { } /** - * @brief Get the source file path, permissions, and owner for a shared file - * @param string Shared target file path - * @param string $target + * Get the source file path, permissions, and owner for a shared file + * @param string $target Shared target file path * @return Returns array with the keys path, permissions, and owner or false if not found */ public function getFile($target) { @@ -76,9 +75,8 @@ class Shared extends \OC\Files\Storage\Common { } /** - * @brief Get the source file path for a shared file - * @param string Shared target file path - * @param string $target + * Get the source file path for a shared file + * @param string $target Shared target file path * @return string source file path or false if not found */ public function getSourcePath($target) { @@ -100,8 +98,8 @@ class Shared extends \OC\Files\Storage\Common { } /** - * @brief Get the permissions granted for a shared file - * @param string Shared target file path + * Get the permissions granted for a shared file + * @param string $target Shared target file path * @return int CRUDS permissions granted */ public function getPermissions($target) { @@ -265,7 +263,7 @@ class Shared extends \OC\Files\Storage\Common { } /** - * @brief Format a path to be relative to the /user/files/ directory + * Format a path to be relative to the /user/files/ directory * @param string $path the absolute path * @return string e.g. turns '/admin/files/test.txt' into '/test.txt' */ @@ -289,7 +287,7 @@ class Shared extends \OC\Files\Storage\Common { } /** - * @brief rename a shared folder/file + * rename a shared folder/file * @param string $sourcePath * @param string $targetPath * @return bool @@ -483,7 +481,7 @@ class Shared extends \OC\Files\Storage\Common { } /** - * @brief return mount point of share, relative to data/user/files + * return mount point of share, relative to data/user/files * @return string */ public function getMountPoint() { @@ -491,7 +489,7 @@ class Shared extends \OC\Files\Storage\Common { } /** - * @brief get share type + * get share type * @return integer can be single user share (0) group share (1), unique group share name (2) */ private function getShareType() { @@ -503,7 +501,7 @@ class Shared extends \OC\Files\Storage\Common { } /** - * @brief does the group share already has a user specific unique name + * does the group share already has a user specific unique name * @return bool */ private function uniqueNameSet() { @@ -511,14 +509,14 @@ class Shared extends \OC\Files\Storage\Common { } /** - * @brief the share now uses a unique name of this user + * the share now uses a unique name of this user */ private function setUniqueName() { $this->share['unique_name'] = true; } /** - * @brief get share ID + * get share ID * @return integer unique share ID */ private function getShareId() { @@ -526,7 +524,7 @@ class Shared extends \OC\Files\Storage\Common { } /** - * @brief get the user who shared the file + * get the user who shared the file * @return string */ public function getSharedFrom() { @@ -534,7 +532,7 @@ class Shared extends \OC\Files\Storage\Common { } /** - * @brief return share type, can be "file" or "folder" + * return share type, can be "file" or "folder" * @return string */ public function getItemType() { diff --git a/apps/files_sharing/lib/updater.php b/apps/files_sharing/lib/updater.php index 49044383df571d52bbb840c075d5929b48593db9..21d67caad9d016838f82346f88f9430624623c8a 100644 --- a/apps/files_sharing/lib/updater.php +++ b/apps/files_sharing/lib/updater.php @@ -27,7 +27,7 @@ class Shared_Updater { static private $toRemove = array(); /** - * @brief walk up the users file tree and update the etags + * walk up the users file tree and update the etags * @param string $user * @param string $path */ @@ -78,7 +78,7 @@ class Shared_Updater { } /** - * @brief remove all shares for a given file if the file was deleted + * remove all shares for a given file if the file was deleted * * @param string $path */ diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php index e17ffc48036d79d42bdd260fecd8f75c215235f5..8a86cb3806a6f2c29ca3017ca93ae9fc6e621bea 100644 --- a/apps/files_sharing/public.php +++ b/apps/files_sharing/public.php @@ -149,11 +149,11 @@ if (isset($path)) { $freeSpace=OCP\Util::freeSpace($path); $uploadLimit=OCP\Util::uploadLimit(); - $folder = new OCP\Template('files', 'index', ''); + $folder = new OCP\Template('files', 'list', ''); $folder->assign('dir', $getPath); $folder->assign('dirToken', $linkItem['token']); $folder->assign('permissions', OCP\PERMISSION_READ); - $folder->assign('isPublic',true); + $folder->assign('isPublic', true); $folder->assign('publicUploadEnabled', 'no'); $folder->assign('files', $files); $folder->assign('uploadMaxFilesize', $maxUploadFilesize); @@ -162,7 +162,6 @@ if (isset($path)) { $folder->assign('uploadLimit', $uploadLimit); // PHP upload limit $folder->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true))); $folder->assign('usedSpacePercent', 0); - $folder->assign('disableSharing', true); $folder->assign('trash', false); $tmpl->assign('folder', $folder->fetchPage()); $allowZip = OCP\Config::getSystemValue('allowZipDownload', true); diff --git a/apps/files_sharing/tests/api.php b/apps/files_sharing/tests/api.php index 2193717f4b4ccaecb94d3c04b3bc574f5b133411..dc07c6fc6201a7b0b825ec235c6152d637199b15 100644 --- a/apps/files_sharing/tests/api.php +++ b/apps/files_sharing/tests/api.php @@ -113,11 +113,65 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { $fileinfo = $this->view->getFileInfo($this->folder); \OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_LINK, null); + } + + function testEnfoceLinkPassword() { + + $appConfig = \OC::$server->getAppConfig(); + $appConfig->setValue('core', 'shareapi_enforce_links_password', 'yes'); + + // don't allow to share link without a password + $_POST['path'] = $this->folder; + $_POST['shareType'] = \OCP\Share::SHARE_TYPE_LINK; + + + $result = Share\Api::createShare(array()); + $this->assertFalse($result->succeeded()); + + + // don't allow to share link without a empty password + $_POST['path'] = $this->folder; + $_POST['shareType'] = \OCP\Share::SHARE_TYPE_LINK; + $_POST['password'] = ''; + + $result = Share\Api::createShare(array()); + $this->assertFalse($result->succeeded()); + + // share with password should succeed + $_POST['path'] = $this->folder; + $_POST['shareType'] = \OCP\Share::SHARE_TYPE_LINK; + $_POST['password'] = 'foo'; + + $result = Share\Api::createShare(array()); + $this->assertTrue($result->succeeded()); + + $data = $result->getData(); + + // setting new password should succeed + $params = array(); + $params['id'] = $data['id']; + $params['_put'] = array(); + $params['_put']['password'] = 'bar'; + $result = Share\Api::updateShare($params); + $this->assertTrue($result->succeeded()); + // removing password should fail + $params = array(); + $params['id'] = $data['id']; + $params['_put'] = array(); + $params['_put']['password'] = ''; + $result = Share\Api::updateShare($params); + $this->assertFalse($result->succeeded()); + + // cleanup + $fileinfo = $this->view->getFileInfo($this->folder); + \OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_LINK, null); + $appConfig->setValue('core', 'shareapi_enforce_links_password', 'no'); } + /** * @medium * @depends testCreateShare @@ -133,7 +187,7 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { $this->assertTrue($result->succeeded()); - // test should return two shares created from testCreateShare() + // test should return two shares created from testCreateShare() $this->assertTrue(count($result->getData()) === 1); \OCP\Share::unshare('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, @@ -160,7 +214,7 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { $this->assertTrue($result->succeeded()); - // test should return one share created from testCreateShare() + // test should return one share created from testCreateShare() $this->assertTrue(count($result->getData()) === 2); \OCP\Share::unshare('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, @@ -287,7 +341,7 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { $this->assertTrue($result->succeeded()); - // test should return one share within $this->folder + // test should return one share within $this->folder $this->assertTrue(count($result->getData()) === 1); \OCP\Share::unshare('file', $fileInfo1['fileid'], \OCP\Share::SHARE_TYPE_USER, @@ -298,7 +352,7 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { } /** - * @brief share a folder, than reshare a file within the shared folder and check if we construct the correct path + * share a folder, than reshare a file within the shared folder and check if we construct the correct path * @medium */ function testGetShareFromFolderReshares() { @@ -363,7 +417,7 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { } /** - * @brief reshare a sub folder and check if we get the correct path + * reshare a sub folder and check if we get the correct path * @medium */ function testGetShareFromSubFolderReShares() { @@ -416,7 +470,7 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { } /** - * @brief test re-re-share of folder if the path gets constructed correctly + * test re-re-share of folder if the path gets constructed correctly * @medium */ function testGetShareFromFolderReReShares() { @@ -484,7 +538,7 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { } /** - * @brief test multiple shared folder if the path gets constructed correctly + * test multiple shared folder if the path gets constructed correctly * @medium */ function testGetShareMultipleSharedFolder() { @@ -567,7 +621,7 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { } /** - * @brief test re-re-share of folder if the path gets constructed correctly + * test re-re-share of folder if the path gets constructed correctly * @medium */ function testGetShareFromFileReReShares() { @@ -644,7 +698,7 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { $result = Share\Api::getShare($params); $this->assertEquals(404, $result->getStatusCode()); - $meta = $result->getMeta(); + $meta = $result->getMeta(); $this->assertEquals('share doesn\'t exist', $meta['message']); } @@ -701,7 +755,7 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { $result = Share\Api::updateShare($params); - $meta = $result->getMeta(); + $meta = $result->getMeta(); $this->assertTrue($result->succeeded(), $meta['message']); $items = \OCP\Share::getItemShared('file', $userShare['file_source']); @@ -841,7 +895,7 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { } /** - * @brief test unshare of a reshared file + * test unshare of a reshared file */ function testDeleteReshare() { @@ -885,7 +939,7 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { } /** - * @brief share a folder which contains a share mount point, should be forbidden + * share a folder which contains a share mount point, should be forbidden */ public function testShareFolderWithAMountPoint() { // user 1 shares a folder with user2 @@ -1004,4 +1058,58 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { \OCP\Share::shareItem('file', $info->getId(), \OCP\Share::SHARE_TYPE_LINK, \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2, 31); } + + public function testDefaultExpireDate() { + \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1); + \OC_Appconfig::setValue('core', 'shareapi_default_expire_date', 'yes'); + \OC_Appconfig::setValue('core', 'shareapi_enforce_expire_date', 'yes'); + \OC_Appconfig::setValue('core', 'shareapi_expire_after_n_days', '2'); + + // default expire date is set to 2 days + // the time when the share was created is set to 3 days in the past + // user defined expire date is set to +2 days from now on + // -> link should be already expired by the default expire date but the user + // share should still exists. + $now = time(); + $dateFormat = 'Y-m-d H:i:s'; + $shareCreated = $now - 3 * 24 * 60 * 60; + $expireDate = date($dateFormat, $now + 2 * 24 * 60 * 60); + + $info = OC\Files\Filesystem::getFileInfo($this->filename); + $this->assertTrue($info instanceof \OC\Files\FileInfo); + + $result = \OCP\Share::shareItem('file', $info->getId(), \OCP\Share::SHARE_TYPE_LINK, null, \OCP\PERMISSION_READ); + $this->assertTrue(is_string($result)); + + $result = \OCP\Share::shareItem('file', $info->getId(), \OCP\Share::SHARE_TYPE_USER, \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2, 31); + $this->assertTrue($result); + + $result = \OCP\Share::setExpirationDate('file', $info->getId() , $expireDate); + $this->assertTrue($result); + + //manipulate stime so that both shares are older then the default expire date + $statement = "UPDATE `*PREFIX*share` SET `stime` = ? WHERE `share_type` = ?"; + $query = \OCP\DB::prepare($statement); + $result = $query->execute(array($shareCreated, \OCP\Share::SHARE_TYPE_LINK)); + $this->assertSame(1, $result); + $statement = "UPDATE `*PREFIX*share` SET `stime` = ? WHERE `share_type` = ?"; + $query = \OCP\DB::prepare($statement); + $result = $query->execute(array($shareCreated, \OCP\Share::SHARE_TYPE_USER)); + $this->assertSame(1, $result); + + // now the link share should expire because of enforced default expire date + // the user share should still exist + $result = \OCP\Share::getItemShared('file', $info->getId()); + $this->assertTrue(is_array($result)); + $this->assertSame(1, count($result)); + $share = reset($result); + $this->assertSame(\OCP\Share::SHARE_TYPE_USER, $share['share_type']); + + //cleanup + $result = \OCP\Share::unshare('file', $info->getId(), \OCP\Share::SHARE_TYPE_USER, \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2); + $this->assertTrue($result); + \OC_Appconfig::setValue('core', 'shareapi_default_expire_date', 'no'); + \OC_Appconfig::setValue('core', 'shareapi_enforce_expire_date', 'no'); + + } } diff --git a/apps/files_sharing/tests/base.php b/apps/files_sharing/tests/base.php index 495dca072c72759af0ce50a5a5630065031e4366..7cd36b9d419833cef23c36719a63c09019b3c9dc 100644 --- a/apps/files_sharing/tests/base.php +++ b/apps/files_sharing/tests/base.php @@ -39,7 +39,7 @@ abstract class Test_Files_Sharing_Base extends \PHPUnit_Framework_TestCase { public $filename; public $data; /** - * @var OC_FilesystemView + * @var OC\Files\View */ public $view; public $folder; @@ -68,7 +68,7 @@ abstract class Test_Files_Sharing_Base extends \PHPUnit_Framework_TestCase { self::loginHelper(self::TEST_FILES_SHARING_API_USER1); $this->data = 'foobar'; - $this->view = new \OC_FilesystemView('/' . self::TEST_FILES_SHARING_API_USER1 . '/files'); + $this->view = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER1 . '/files'); // remember files_encryption state $this->stateFilesEncryption = \OC_App::isEnabled('files_encryption'); @@ -97,7 +97,7 @@ abstract class Test_Files_Sharing_Base extends \PHPUnit_Framework_TestCase { } /** - * @param $user + * @param string $user * @param bool $create * @param bool $password */ @@ -119,7 +119,7 @@ abstract class Test_Files_Sharing_Base extends \PHPUnit_Framework_TestCase { } /** - * @brief get some information from a given share + * get some information from a given share * @param int $shareID * @return array with: item_source, share_type, share_with, item_type, permissions */ diff --git a/apps/files_sharing/tests/cache.php b/apps/files_sharing/tests/cache.php index 1af73c558d553c476f0386a536c5b18ee244141b..c5408ba55e7ceccb13fbd40505c960587cf71d1b 100644 --- a/apps/files_sharing/tests/cache.php +++ b/apps/files_sharing/tests/cache.php @@ -25,7 +25,7 @@ require_once __DIR__ . '/base.php'; class Test_Files_Sharing_Cache extends Test_Files_Sharing_Base { /** - * @var OC_FilesystemView + * @var OC\Files\View */ public $user2View; @@ -230,7 +230,7 @@ class Test_Files_Sharing_Cache extends Test_Files_Sharing_Base { } /** - * @brief verify if each value from the result matches the expected result + * verify if each value from the result matches the expected result * @param array $example array with the expected results * @param array $result array with the results */ diff --git a/apps/files_trashbin/ajax/list.php b/apps/files_trashbin/ajax/list.php index 89a5511452449ccb416cbac15ca2952c723c19a7..e1f52e814bb2f206299721e0bf8eac591ce1eee4 100644 --- a/apps/files_trashbin/ajax/list.php +++ b/apps/files_trashbin/ajax/list.php @@ -4,11 +4,13 @@ OCP\JSON::checkLoggedIn(); // Load the files $dir = isset( $_GET['dir'] ) ? $_GET['dir'] : ''; +$sortAttribute = isset( $_GET['sort'] ) ? $_GET['sort'] : 'name'; +$sortDirection = isset( $_GET['sortdirection'] ) ? ($_GET['sortdirection'] === 'desc') : false; $data = array(); // make filelist try { - $files = \OCA\Files_Trashbin\Helper::getTrashFiles($dir); + $files = \OCA\Files_Trashbin\Helper::getTrashFiles($dir, $sortAttribute, $sortDirection); } catch (Exception $e) { header("HTTP/1.0 404 Not Found"); exit(); diff --git a/apps/files_trashbin/appinfo/app.php b/apps/files_trashbin/appinfo/app.php index d30a601ef564c0282fdbed5715cf62f394cd114d..b8900ee0de3a48cb781ae5dd4e630dcb57f04316 100644 --- a/apps/files_trashbin/appinfo/app.php +++ b/apps/files_trashbin/appinfo/app.php @@ -1,7 +1,15 @@ add( +array( + "id" => 'trashbin', + "appname" => 'files_trashbin', + "script" => 'list.php', + "order" => 1, + "name" => $l->t('Deleted files') +) +); diff --git a/apps/files_trashbin/css/trash.css b/apps/files_trashbin/css/trash.css index 7ca3e355fc211bf02aabb20bb036710279d52a6e..04b4a175c83354dfcbc0507f6d0156ee0c819066 100644 --- a/apps/files_trashbin/css/trash.css +++ b/apps/files_trashbin/css/trash.css @@ -1,4 +1,13 @@ -#fileList tr[data-type="file"] td a.name, -#fileList tr[data-type="file"] td a.name span { +/* + * Copyright (c) 2014 + * + * This file is licensed under the Affero General Public License version 3 + * or later. + * + * See the COPYING-README file. + * + */ +#app-content-trashbin tbody tr[data-type="file"] td a.name, +#app-content-trashbin tbody tr[data-type="file"] td a.name span { cursor: default; } diff --git a/apps/files_trashbin/index.php b/apps/files_trashbin/index.php deleted file mode 100644 index 6e6a8a38307faa5dc7ce5da6df14b0e32267697b..0000000000000000000000000000000000000000 --- a/apps/files_trashbin/index.php +++ /dev/null @@ -1,42 +0,0 @@ - 0 && $matches[1] <= 8){ - $isIE8 = true; -} - -// if IE8 and "?dir=path" was specified, reformat the URL to use a hash like "#?dir=path" -if ($isIE8 && isset($_GET['dir'])){ - if ($dir === ''){ - $dir = '/'; - } - header('Location: ' . OCP\Util::linkTo('files_trashbin', 'index.php') . '#?dir=' . \OCP\Util::encodePath($dir)); - exit(); -} - -$tmpl->assign('dir', $dir); -$tmpl->assign('disableSharing', true); - -$tmpl->printPage(); diff --git a/apps/files_trashbin/js/app.js b/apps/files_trashbin/js/app.js new file mode 100644 index 0000000000000000000000000000000000000000..aa499ae1791b61660b4ea36b272bf419b5b9d830 --- /dev/null +++ b/apps/files_trashbin/js/app.js @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2014 + * + * This file is licensed under the Affero General Public License version 3 + * or later. + * + * See the COPYING-README file. + * + */ + +OCA.Trashbin = {}; +OCA.Trashbin.App = { + _initialized: false, + + initialize: function($el) { + if (this._initialized) { + return; + } + this._initialized = true; + this.fileList = new OCA.Trashbin.FileList( + $('#app-content-trashbin'), { + scrollContainer: $('#app-content') + } + ); + this.registerFileActions(this.fileList); + }, + + registerFileActions: function(fileList) { + var self = this; + var fileActions = _.extend({}, OCA.Files.FileActions); + fileActions.clear(); + fileActions.register('dir', 'Open', OC.PERMISSION_READ, '', function (filename) { + var dir = fileList.getCurrentDirectory(); + if (dir !== '/') { + dir = dir + '/'; + } + fileList.changeDirectory(dir + filename); + }); + + fileActions.setDefault('dir', 'Open'); + + fileActions.register('all', 'Restore', OC.PERMISSION_READ, OC.imagePath('core', 'actions/history'), function(filename) { + var tr = fileList.findFileEl(filename); + var deleteAction = tr.children("td.date").children(".action.delete"); + deleteAction.removeClass('delete-icon').addClass('progress-icon'); + fileList.disableActions(); + $.post(OC.filePath('files_trashbin', 'ajax', 'undelete.php'), { + files: JSON.stringify([filename]), + dir: fileList.getCurrentDirectory() + }, + _.bind(fileList._removeCallback, fileList) + ); + }, t('files_trashbin', 'Restore')); + + fileActions.register('all', 'Delete', OC.PERMISSION_READ, function() { + return OC.imagePath('core', 'actions/delete'); + }, function(filename) { + $('.tipsy').remove(); + var tr = fileList.findFileEl(filename); + var deleteAction = tr.children("td.date").children(".action.delete"); + deleteAction.removeClass('delete-icon').addClass('progress-icon'); + fileList.disableActions(); + $.post(OC.filePath('files_trashbin', 'ajax', 'delete.php'), { + files: JSON.stringify([filename]), + dir: fileList.getCurrentDirectory() + }, + _.bind(fileList._removeCallback, fileList) + ); + }); + fileList.setFileActions(fileActions); + } +}; + +$(document).ready(function() { + $('#app-content-trashbin').one('show', function() { + var App = OCA.Trashbin.App; + App.initialize($('#app-content-trashbin')); + // force breadcrumb init + // App.fileList.changeDirectory(App.fileList.getCurrentDirectory(), false, true); + }); +}); + diff --git a/apps/files_trashbin/js/disableDefaultActions.js b/apps/files_trashbin/js/disableDefaultActions.js deleted file mode 100644 index 50ceaf4696fe1aa041dfea3c29d02b8e513dc6da..0000000000000000000000000000000000000000 --- a/apps/files_trashbin/js/disableDefaultActions.js +++ /dev/null @@ -1,3 +0,0 @@ -/* disable download and sharing actions */ -var disableDownloadActions = true; -var trashBinApp = true; diff --git a/apps/files_trashbin/js/filelist.js b/apps/files_trashbin/js/filelist.js index 3bb3a92b60ddd43ca46541b3cb4ce4e221ee2a3c..205f879f335f944631013b10bb272f3fc6e972f9 100644 --- a/apps/files_trashbin/js/filelist.js +++ b/apps/files_trashbin/js/filelist.js @@ -1,8 +1,14 @@ -/* global OC, t, FileList */ +/* + * Copyright (c) 2014 + * + * This file is licensed under the Affero General Public License version 3 + * or later. + * + * See the COPYING-README file. + * + */ (function() { - FileList.appName = t('files_trashbin', 'Deleted files'); - - FileList._deletedRegExp = new RegExp(/^(.+)\.d[0-9]+$/); + var DELETED_REGEXP = new RegExp(/^(.+)\.d[0-9]+$/); /** * Convert a file name in the format filename.d12345 to the real file name. @@ -11,194 +17,248 @@ * @param name file name * @return converted file name */ - FileList.getDeletedFileName = function(name) { + function getDeletedFileName(name) { name = OC.basename(name); - var match = FileList._deletedRegExp.exec(name); + var match = DELETED_REGEXP.exec(name); if (match && match.length > 1) { name = match[1]; } return name; - }; - - var oldSetCurrentDir = FileList._setCurrentDir; - FileList._setCurrentDir = function(targetDir) { - oldSetCurrentDir.apply(this, arguments); - - var baseDir = OC.basename(targetDir); - if (baseDir !== '') { - FileList.setPageTitle(FileList.getDeletedFileName(baseDir)); - } - }; + } - var oldCreateRow = FileList._createRow; - FileList._createRow = function() { - // FIXME: MEGAHACK until we find a better solution - var tr = oldCreateRow.apply(this, arguments); - tr.find('td.filesize').remove(); - return tr; + var FileList = function($el) { + this.initialize($el); }; + FileList.prototype = _.extend({}, OCA.Files.FileList.prototype, { + id: 'trashbin', + appName: t('files_trashbin', 'Deleted files'), - FileList._onClickBreadCrumb = function(e) { - var $el = $(e.target).closest('.crumb'), - index = $el.index(), - $targetDir = $el.data('dir'); - // first one is home, let the link makes it default action - if (index !== 0) { - e.preventDefault(); - FileList.changeDirectory($targetDir); - } - }; + initialize: function() { + var result = OCA.Files.FileList.prototype.initialize.apply(this, arguments); + this.$el.find('.undelete').click('click', _.bind(this._onClickRestoreSelected, this)); - var oldRenderRow = FileList._renderRow; - FileList._renderRow = function(fileData, options) { - options = options || {}; - var dir = FileList.getCurrentDirectory(); - var dirListing = dir !== '' && dir !== '/'; - // show deleted time as mtime - if (fileData.mtime) { - fileData.mtime = parseInt(fileData.mtime, 10); - } - if (!dirListing) { - fileData.displayName = fileData.name; - fileData.name = fileData.name + '.d' + Math.floor(fileData.mtime / 1000); - } - return oldRenderRow.call(this, fileData, options); - }; + this.setSort('mtime', 'desc'); + /** + * Override crumb making to add "Deleted Files" entry + * and convert files with ".d" extensions to a more + * user friendly name. + */ + this.breadcrumb._makeCrumbs = function() { + var parts = OCA.Files.BreadCrumb.prototype._makeCrumbs.apply(this, arguments); + for (var i = 1; i < parts.length; i++) { + parts[i].name = getDeletedFileName(parts[i].name); + } + return parts; + }; - FileList.linkTo = function(dir){ - return OC.linkTo('files_trashbin', 'index.php')+"?dir="+ encodeURIComponent(dir).replace(/%2F/g, '/'); - }; + return result; + }, - FileList.updateEmptyContent = function(){ - var $fileList = $('#fileList'); - var exists = $fileList.find('tr:first').exists(); - $('#emptycontent').toggleClass('hidden', exists); - $('#filestable th').toggleClass('hidden', !exists); - }; + /** + * Override to only return read permissions + */ + getDirectoryPermissions: function() { + return OC.PERMISSION_READ | OC.PERMISSION_DELETE; + }, - var oldInit = FileList.initialize; - FileList.initialize = function() { - var result = oldInit.apply(this, arguments); - $('.undelete').click('click', FileList._onClickRestoreSelected); - return result; - }; + _setCurrentDir: function(targetDir) { + OCA.Files.FileList.prototype._setCurrentDir.apply(this, arguments); - FileList._removeCallback = function(result) { - if (result.status !== 'success') { - OC.dialogs.alert(result.data.message, t('files_trashbin', 'Error')); - } + var baseDir = OC.basename(targetDir); + if (baseDir !== '') { + this.setPageTitle(getDeletedFileName(baseDir)); + } + }, - var files = result.data.success; - var $el; - for (var i = 0; i < files.length; i++) { - $el = FileList.remove(OC.basename(files[i].filename), {updateSummary: false}); - FileList.fileSummary.remove({type: $el.attr('data-type'), size: $el.attr('data-size')}); - } - FileList.fileSummary.update(); - FileList.updateEmptyContent(); - enableActions(); - } + _createRow: function() { + // FIXME: MEGAHACK until we find a better solution + var tr = OCA.Files.FileList.prototype._createRow.apply(this, arguments); + tr.find('td.filesize').remove(); + return tr; + }, - FileList._onClickRestoreSelected = function(event) { - event.preventDefault(); - var allFiles = $('#select_all').is(':checked'); - var files = []; - var params = {}; - disableActions(); - if (allFiles) { - FileList.showMask(); - params = { - allfiles: true, - dir: FileList.getCurrentDirectory() - }; - } - else { - files = _.pluck(FileList.getSelectedFiles(), 'name'); - for (var i = 0; i < files.length; i++) { - var deleteAction = FileList.findFileEl(files[i]).children("td.date").children(".action.delete"); - deleteAction.removeClass('delete-icon').addClass('progress-icon'); + _renderRow: function(fileData, options) { + options = options || {}; + var dir = this.getCurrentDirectory(); + var dirListing = dir !== '' && dir !== '/'; + // show deleted time as mtime + if (fileData.mtime) { + fileData.mtime = parseInt(fileData.mtime, 10); } - params = { - files: JSON.stringify(files), - dir: FileList.getCurrentDirectory() - }; - } + if (!dirListing) { + fileData.displayName = fileData.name; + fileData.name = fileData.name + '.d' + Math.floor(fileData.mtime / 1000); + } + return OCA.Files.FileList.prototype._renderRow.call(this, fileData, options); + }, - $.post(OC.filePath('files_trashbin', 'ajax', 'undelete.php'), - params, - function(result) { - if (allFiles) { - if (result.status !== 'success') { - OC.dialogs.alert(result.data.message, t('files_trashbin', 'Error')); - } - FileList.hideMask(); - // simply remove all files - FileList.setFiles([]); - enableActions(); - } - else { - FileList._removeCallback(result); - } + getAjaxUrl: function(action, params) { + var q = ''; + if (params) { + q = '?' + OC.buildQueryString(params); } - ); - }; + return OC.filePath('files_trashbin', 'ajax', action + '.php') + q; + }, - FileList._onClickDeleteSelected = function(event) { - event.preventDefault(); - var allFiles = $('#select_all').is(':checked'); - var files = []; - var params = {}; - if (allFiles) { - params = { - allfiles: true, - dir: FileList.getCurrentDirectory() - }; - } - else { - files = _.pluck(FileList.getSelectedFiles(), 'name'); - params = { - files: JSON.stringify(files), - dir: FileList.getCurrentDirectory() - }; - } + setupUploadEvents: function() { + // override and do nothing + }, - disableActions(); - if (allFiles) { - FileList.showMask(); - } - else { + linkTo: function(dir){ + return OC.linkTo('files', 'index.php')+"?view=trashbin&dir="+ encodeURIComponent(dir).replace(/%2F/g, '/'); + }, + + updateEmptyContent: function(){ + var exists = this.$fileList.find('tr:first').exists(); + this.$el.find('#emptycontent').toggleClass('hidden', exists); + this.$el.find('#filestable th').toggleClass('hidden', !exists); + }, + + _removeCallback: function(result) { + if (result.status !== 'success') { + OC.dialogs.alert(result.data.message, t('files_trashbin', 'Error')); + } + + var files = result.data.success; + var $el; for (var i = 0; i < files.length; i++) { - var deleteAction = FileList.findFileEl(files[i]).children("td.date").children(".action.delete"); - deleteAction.removeClass('delete-icon').addClass('progress-icon'); + $el = this.remove(OC.basename(files[i].filename), {updateSummary: false}); + this.fileSummary.remove({type: $el.attr('data-type'), size: $el.attr('data-size')}); } - } + this.fileSummary.update(); + this.updateEmptyContent(); + this.enableActions(); + }, - $.post(OC.filePath('files_trashbin', 'ajax', 'delete.php'), + _onClickRestoreSelected: function(event) { + event.preventDefault(); + var self = this; + var allFiles = this.$el.find('.select-all').is(':checked'); + var files = []; + var params = {}; + this.disableActions(); + if (allFiles) { + this.showMask(); + params = { + allfiles: true, + dir: this.getCurrentDirectory() + }; + } + else { + files = _.pluck(this.getSelectedFiles(), 'name'); + for (var i = 0; i < files.length; i++) { + var deleteAction = this.findFileEl(files[i]).children("td.date").children(".action.delete"); + deleteAction.removeClass('delete-icon').addClass('progress-icon'); + } + params = { + files: JSON.stringify(files), + dir: this.getCurrentDirectory() + }; + } + + $.post(OC.filePath('files_trashbin', 'ajax', 'undelete.php'), params, function(result) { if (allFiles) { if (result.status !== 'success') { OC.dialogs.alert(result.data.message, t('files_trashbin', 'Error')); } - FileList.hideMask(); + self.hideMask(); // simply remove all files - FileList.setFiles([]); - enableActions(); + self.setFiles([]); + self.enableActions(); } else { - FileList._removeCallback(result); + self._removeCallback(result); } } - ); - }; + ); + }, - var oldClickFile = FileList._onClickFile; - FileList._onClickFile = function(event) { - var mime = $(this).parent().parent().data('mime'); - if (mime !== 'httpd/unix-directory') { + _onClickDeleteSelected: function(event) { event.preventDefault(); + var self = this; + var allFiles = this.$el.find('.select-all').is(':checked'); + var files = []; + var params = {}; + if (allFiles) { + params = { + allfiles: true, + dir: this.getCurrentDirectory() + }; + } + else { + files = _.pluck(this.getSelectedFiles(), 'name'); + params = { + files: JSON.stringify(files), + dir: this.getCurrentDirectory() + }; + } + + this.disableActions(); + if (allFiles) { + this.showMask(); + } + else { + for (var i = 0; i < files.length; i++) { + var deleteAction = this.findFileEl(files[i]).children("td.date").children(".action.delete"); + deleteAction.removeClass('delete-icon').addClass('progress-icon'); + } + } + + $.post(OC.filePath('files_trashbin', 'ajax', 'delete.php'), + params, + function(result) { + if (allFiles) { + if (result.status !== 'success') { + OC.dialogs.alert(result.data.message, t('files_trashbin', 'Error')); + } + self.hideMask(); + // simply remove all files + self.setFiles([]); + self.enableActions(); + } + else { + self._removeCallback(result); + } + } + ); + }, + + _onClickFile: function(event) { + var mime = $(this).parent().parent().data('mime'); + if (mime !== 'httpd/unix-directory') { + event.preventDefault(); + } + return OCA.Files.FileList.prototype._onClickFile.apply(this, arguments); + }, + + generatePreviewUrl: function(urlSpec) { + return OC.generateUrl('/apps/files_trashbin/ajax/preview.php?') + $.param(urlSpec); + }, + + getDownloadUrl: function() { + // no downloads + return '#'; + }, + + enableActions: function() { + this.$el.find('.action').css('display', 'inline'); + this.$el.find(':input:checkbox').css('display', 'inline'); + }, + + disableActions: function() { + this.$el.find('.action').css('display', 'none'); + this.$el.find(':input:checkbox').css('display', 'none'); + }, + + updateStorageStatistics: function() { + // no op because the trashbin doesn't have + // storage info like free space / used space } - return oldClickFile.apply(this, arguments); - }; + }); + + OCA.Trashbin.FileList = FileList; })(); + diff --git a/apps/files_trashbin/js/trash.js b/apps/files_trashbin/js/trash.js deleted file mode 100644 index 5f2436de8096c78bb7eaffdc50c0dc29f9ee1713..0000000000000000000000000000000000000000 --- a/apps/files_trashbin/js/trash.js +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2014 - * - * This file is licensed under the Affero General Public License version 3 - * or later. - * - * See the COPYING-README file. - * - */ - -/* global OC, t, BreadCrumb, FileActions, FileList, Files */ -$(document).ready(function() { - var deletedRegExp = new RegExp(/^(.+)\.d[0-9]+$/); - - /** - * Convert a file name in the format filename.d12345 to the real file name. - * This will use basename. - * The name will not be changed if it has no ".d12345" suffix. - * @param name file name - * @return converted file name - */ - function getDeletedFileName(name) { - name = OC.basename(name); - var match = deletedRegExp.exec(name); - if (match && match.length > 1) { - name = match[1]; - } - return name; - } - - Files.updateStorageStatistics = function() { - // no op because the trashbin doesn't have - // storage info like free space / used space - }; - - if (typeof FileActions !== 'undefined') { - FileActions.register('all', 'Restore', OC.PERMISSION_READ, OC.imagePath('core', 'actions/history'), function(filename) { - var tr = FileList.findFileEl(filename); - var deleteAction = tr.children("td.date").children(".action.delete"); - deleteAction.removeClass('delete-icon').addClass('progress-icon'); - disableActions(); - $.post(OC.filePath('files_trashbin', 'ajax', 'undelete.php'), { - files: JSON.stringify([filename]), - dir: FileList.getCurrentDirectory() - }, - FileList._removeCallback - ); - }, t('files_trashbin', 'Restore')); - }; - - FileActions.register('all', 'Delete', OC.PERMISSION_READ, function() { - return OC.imagePath('core', 'actions/delete'); - }, function(filename) { - $('.tipsy').remove(); - var tr = FileList.findFileEl(filename); - var deleteAction = tr.children("td.date").children(".action.delete"); - deleteAction.removeClass('delete-icon').addClass('progress-icon'); - disableActions(); - $.post(OC.filePath('files_trashbin', 'ajax', 'delete.php'), { - files: JSON.stringify([filename]), - dir: FileList.getCurrentDirectory() - }, - FileList._removeCallback - ); - }); - - /** - * Override crumb URL maker (hacky!) - */ - FileList.breadcrumb.getCrumbUrl = function(part, index) { - if (index === 0) { - return OC.linkTo('files', 'index.php'); - } - return OC.linkTo('files_trashbin', 'index.php')+"?dir=" + encodeURIComponent(part.dir); - }; - - Files.generatePreviewUrl = function(urlSpec) { - return OC.generateUrl('/apps/files_trashbin/ajax/preview.php?') + $.param(urlSpec); - }; - - Files.getDownloadUrl = function(action, params) { - // no downloads - return '#'; - }; - - Files.getAjaxUrl = function(action, params) { - var q = ''; - if (params) { - q = '?' + OC.buildQueryString(params); - } - return OC.filePath('files_trashbin', 'ajax', action + '.php') + q; - }; - - - /** - * Override crumb making to add "Deleted Files" entry - * and convert files with ".d" extensions to a more - * user friendly name. - */ - var oldMakeCrumbs = BreadCrumb.prototype._makeCrumbs; - BreadCrumb.prototype._makeCrumbs = function() { - var parts = oldMakeCrumbs.apply(this, arguments); - // duplicate first part - parts.unshift(parts[0]); - parts[1] = { - dir: '/', - name: t('files_trashbin', 'Deleted Files') - }; - for (var i = 2; i < parts.length; i++) { - parts[i].name = getDeletedFileName(parts[i].name); - } - return parts; - }; - - FileActions.actions.dir = { - // only keep 'Open' action for navigation - 'Open': FileActions.actions.dir.Open - }; -}); - -function enableActions() { - $(".action").css("display", "inline"); - $(":input:checkbox").css("display", "inline"); -} - -function disableActions() { - $(".action").css("display", "none"); - $(":input:checkbox").css("display", "none"); -} - diff --git a/apps/files_trashbin/l10n/ar.php b/apps/files_trashbin/l10n/ar.php index b3abc7df86ef2aff85f4edd6f3f56d7e76701daf..5a6105bda6f7413d5797c98ec24c2c21bed58b34 100644 --- a/apps/files_trashbin/l10n/ar.php +++ b/apps/files_trashbin/l10n/ar.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "تعذّر حذف%s بشكل دائم", "Couldn't restore %s" => "تعذّر استرجاع %s ", "Deleted files" => "حذف الملفات", +"Restore" => "استعيد", "Error" => "خطأ", -"Deleted Files" => "الملفات المحذوفه", "restored" => "تمت الاستعادة", "Nothing in here. Your trash bin is empty!" => "لا يوجد شيء هنا. سلة المهملات خاليه.", "Name" => "اسم", -"Restore" => "استعيد", "Deleted" => "تم الحذف", "Delete" => "إلغاء" ); diff --git a/apps/files_trashbin/l10n/ast.php b/apps/files_trashbin/l10n/ast.php index 688e1ce3d8fa6735dfd93009d2bea9c1d2aeebd0..3240d6751c1101ce393b1c3d28cf4025d797ea5a 100644 --- a/apps/files_trashbin/l10n/ast.php +++ b/apps/files_trashbin/l10n/ast.php @@ -2,11 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Nun pudo desaniciase %s dafechu", "Couldn't restore %s" => "Nun pudo restaurase %s", +"Deleted files" => "Ficheros desaniciaos", +"Restore" => "Restaurar", "Error" => "Fallu", -"Deleted Files" => "Ficheros desaniciaos", +"restored" => "recuperóse", "Nothing in here. Your trash bin is empty!" => "Nun hai un res equí. La papelera ta balera!", "Name" => "Nome", -"Restore" => "Restaurar", "Deleted" => "Desaniciáu", "Delete" => "Desaniciar" ); diff --git a/apps/files_trashbin/l10n/bg_BG.php b/apps/files_trashbin/l10n/bg_BG.php index 8c9e658068c440a7e14880551e5d789dddb4c17a..62057538ce4312b451a23dd45e79fd4472fcaa81 100644 --- a/apps/files_trashbin/l10n/bg_BG.php +++ b/apps/files_trashbin/l10n/bg_BG.php @@ -2,11 +2,10 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Невъзможно перманентното изтриване на %s", "Couldn't restore %s" => "Невъзможно възтановяване на %s", +"Restore" => "Възтановяване", "Error" => "Грешка", -"Deleted Files" => "Изтрити файлове", "Nothing in here. Your trash bin is empty!" => "Няма нищо. Кофата е празна!", "Name" => "Име", -"Restore" => "Възтановяване", "Deleted" => "Изтрито", "Delete" => "Изтриване" ); diff --git a/apps/files_trashbin/l10n/ca.php b/apps/files_trashbin/l10n/ca.php index 196d6ac00a4a3a7ad7823846096e44f51f776fd8..59b42797cf90e164bd48813cd1f859980c753512 100644 --- a/apps/files_trashbin/l10n/ca.php +++ b/apps/files_trashbin/l10n/ca.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "No s'ha pogut esborrar permanentment %s", "Couldn't restore %s" => "No s'ha pogut restaurar %s", "Deleted files" => "Fitxers esborrats", +"Restore" => "Recupera", "Error" => "Error", -"Deleted Files" => "Fitxers eliminats", "restored" => "restaurat", "Nothing in here. Your trash bin is empty!" => "La paperera està buida!", "Name" => "Nom", -"Restore" => "Recupera", "Deleted" => "Eliminat", "Delete" => "Esborra" ); diff --git a/apps/files_trashbin/l10n/cs_CZ.php b/apps/files_trashbin/l10n/cs_CZ.php index ed795582e43012534173a7d411866bc8d57bde83..3e4f9e0e15a77516009f06ad77bf7c0a86c06797 100644 --- a/apps/files_trashbin/l10n/cs_CZ.php +++ b/apps/files_trashbin/l10n/cs_CZ.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Nelze trvale odstranit %s", "Couldn't restore %s" => "Nelze obnovit %s", "Deleted files" => "Odstraněné soubory", +"Restore" => "Obnovit", "Error" => "Chyba", -"Deleted Files" => "Smazané soubory", "restored" => "obnoveno", "Nothing in here. Your trash bin is empty!" => "Žádný obsah. Váš koš je prázdný.", "Name" => "Název", -"Restore" => "Obnovit", "Deleted" => "Smazáno", "Delete" => "Smazat" ); diff --git a/apps/files_trashbin/l10n/cy_GB.php b/apps/files_trashbin/l10n/cy_GB.php index 7b1405777dda4bc6e266d41e6e8166b07156894f..4e76a6d25ab9cbd631ea4a9b2fde29175abd9824 100644 --- a/apps/files_trashbin/l10n/cy_GB.php +++ b/apps/files_trashbin/l10n/cy_GB.php @@ -3,11 +3,10 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Methwyd dileu %s yn barhaol", "Couldn't restore %s" => "Methwyd adfer %s", "Deleted files" => "Ffeiliau ddilewyd", +"Restore" => "Adfer", "Error" => "Gwall", -"Deleted Files" => "Ffeiliau Ddilewyd", "Nothing in here. Your trash bin is empty!" => "Does dim byd yma. Mae eich bin sbwriel yn wag!", "Name" => "Enw", -"Restore" => "Adfer", "Deleted" => "Wedi dileu", "Delete" => "Dileu" ); diff --git a/apps/files_trashbin/l10n/da.php b/apps/files_trashbin/l10n/da.php index 7f7b65bca2ce764837bb547fe0886765b4645c05..b651d81d1bdf7fd0fa316e925b310165a60ccd34 100644 --- a/apps/files_trashbin/l10n/da.php +++ b/apps/files_trashbin/l10n/da.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Kunne ikke slette %s permanent", "Couldn't restore %s" => "Kunne ikke gendanne %s", "Deleted files" => "Slettede filer", +"Restore" => "Gendan", "Error" => "Fejl", -"Deleted Files" => "Slettede filer", "restored" => "Gendannet", "Nothing in here. Your trash bin is empty!" => "Intet at se her. Din papirkurv er tom!", "Name" => "Navn", -"Restore" => "Gendan", "Deleted" => "Slettet", "Delete" => "Slet" ); diff --git a/apps/files_trashbin/l10n/de.php b/apps/files_trashbin/l10n/de.php index 4778e159e1d9cae73a9143d7fdc41efb9bf7538b..56b7ccfc7bd6b7ae49cb87d35ee55cf09d42b52d 100644 --- a/apps/files_trashbin/l10n/de.php +++ b/apps/files_trashbin/l10n/de.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Konnte %s nicht dauerhaft löschen", "Couldn't restore %s" => "Konnte %s nicht wiederherstellen", "Deleted files" => "Gelöschte Dateien", +"Restore" => "Wiederherstellen", "Error" => "Fehler", -"Deleted Files" => "Gelöschte Dateien", "restored" => "Wiederhergestellt", "Nothing in here. Your trash bin is empty!" => "Nichts zu löschen, der Papierkorb ist leer!", "Name" => "Name", -"Restore" => "Wiederherstellen", "Deleted" => "gelöscht", "Delete" => "Löschen" ); diff --git a/apps/files_trashbin/l10n/de_CH.php b/apps/files_trashbin/l10n/de_CH.php index 603d82f5c7afbeb4de27624dd6d3456f876dbd23..be54e57d3f3a09851d51141a8e98b79bd7398dbe 100644 --- a/apps/files_trashbin/l10n/de_CH.php +++ b/apps/files_trashbin/l10n/de_CH.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Konnte %s nicht dauerhaft löschen", "Couldn't restore %s" => "Konnte %s nicht wiederherstellen", "Deleted files" => "Gelöschte Dateien", +"Restore" => "Wiederherstellen", "Error" => "Fehler", -"Deleted Files" => "Gelöschte Dateien", "restored" => "Wiederhergestellt", "Nothing in here. Your trash bin is empty!" => "Nichts zu löschen, Ihr Papierkorb ist leer!", "Name" => "Name", -"Restore" => "Wiederherstellen", "Deleted" => "Gelöscht", "Delete" => "Löschen" ); diff --git a/apps/files_trashbin/l10n/de_DE.php b/apps/files_trashbin/l10n/de_DE.php index 603d82f5c7afbeb4de27624dd6d3456f876dbd23..be54e57d3f3a09851d51141a8e98b79bd7398dbe 100644 --- a/apps/files_trashbin/l10n/de_DE.php +++ b/apps/files_trashbin/l10n/de_DE.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Konnte %s nicht dauerhaft löschen", "Couldn't restore %s" => "Konnte %s nicht wiederherstellen", "Deleted files" => "Gelöschte Dateien", +"Restore" => "Wiederherstellen", "Error" => "Fehler", -"Deleted Files" => "Gelöschte Dateien", "restored" => "Wiederhergestellt", "Nothing in here. Your trash bin is empty!" => "Nichts zu löschen, Ihr Papierkorb ist leer!", "Name" => "Name", -"Restore" => "Wiederherstellen", "Deleted" => "Gelöscht", "Delete" => "Löschen" ); diff --git a/apps/files_trashbin/l10n/el.php b/apps/files_trashbin/l10n/el.php index 23b23ed93a68e4d34e1c832a3981504bcfedb5be..c77bfb7fa16bfa3872ef271dd4da3f6542893607 100644 --- a/apps/files_trashbin/l10n/el.php +++ b/apps/files_trashbin/l10n/el.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Αδύνατη η μόνιμη διαγραφή του %s", "Couldn't restore %s" => "Αδυναμία επαναφοράς %s", "Deleted files" => "Διαγραμμένα αρχεία", +"Restore" => "Επαναφορά", "Error" => "Σφάλμα", -"Deleted Files" => "Διαγραμμένα Αρχεία", "restored" => "επαναφέρθηκαν", "Nothing in here. Your trash bin is empty!" => "Δεν υπάρχει τίποτα εδώ. Ο κάδος σας είναι άδειος!", "Name" => "Όνομα", -"Restore" => "Επαναφορά", "Deleted" => "Διαγραμμένα", "Delete" => "Διαγραφή" ); diff --git a/apps/files_trashbin/l10n/en_GB.php b/apps/files_trashbin/l10n/en_GB.php index a660b4b1ca1776a26ed70c1937ae486aaf1f3ff8..b2715dfceb77bac74e27b5d71a965e207c920447 100644 --- a/apps/files_trashbin/l10n/en_GB.php +++ b/apps/files_trashbin/l10n/en_GB.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Couldn't delete %s permanently", "Couldn't restore %s" => "Couldn't restore %s", "Deleted files" => "Deleted files", +"Restore" => "Restore", "Error" => "Error", -"Deleted Files" => "Deleted Files", "restored" => "restored", "Nothing in here. Your trash bin is empty!" => "Nothing in here. Your recycle bin is empty!", "Name" => "Name", -"Restore" => "Restore", "Deleted" => "Deleted", "Delete" => "Delete" ); diff --git a/apps/files_trashbin/l10n/eo.php b/apps/files_trashbin/l10n/eo.php index d644f0f6420b768e25e1387176220c9c6cc734fe..67617f448d09e69e1a0778a32eb50038a393284b 100644 --- a/apps/files_trashbin/l10n/eo.php +++ b/apps/files_trashbin/l10n/eo.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Ne povis foriĝi %s por ĉiam", "Couldn't restore %s" => "Ne povis restaŭriĝi %s", "Deleted files" => "Forigitaj dosieroj", +"Restore" => "Restaŭri", "Error" => "Eraro", -"Deleted Files" => "Forigitaj dosieroj", "restored" => "restaŭrita", "Nothing in here. Your trash bin is empty!" => "Nenio estas ĉi tie. Via rubujo malplenas!", "Name" => "Nomo", -"Restore" => "Restaŭri", "Deleted" => "Forigita", "Delete" => "Forigi" ); diff --git a/apps/files_trashbin/l10n/es.php b/apps/files_trashbin/l10n/es.php index c0dc6bb45c29e375dacf88b377b7efc611ba9a21..c3db7765154ae4b27f4c5451a7c4a132e33c0945 100644 --- a/apps/files_trashbin/l10n/es.php +++ b/apps/files_trashbin/l10n/es.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "No se puede eliminar %s permanentemente", "Couldn't restore %s" => "No se puede restaurar %s", "Deleted files" => "Archivos eliminados", +"Restore" => "Recuperar", "Error" => "Error", -"Deleted Files" => "Archivos Eliminados", "restored" => "recuperado", "Nothing in here. Your trash bin is empty!" => "No hay nada aquí. ¡Tu papelera esta vacía!", "Name" => "Nombre", -"Restore" => "Recuperar", "Deleted" => "Eliminado", "Delete" => "Eliminar" ); diff --git a/apps/files_trashbin/l10n/es_AR.php b/apps/files_trashbin/l10n/es_AR.php index b354dd656b1c287ac1a6fed572bcf8607a5fcf5e..2991ea507b00880aa9a049337ed5367108e110ee 100644 --- a/apps/files_trashbin/l10n/es_AR.php +++ b/apps/files_trashbin/l10n/es_AR.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "No fue posible borrar %s de manera permanente", "Couldn't restore %s" => "No se pudo restaurar %s", "Deleted files" => "Archivos borrados", +"Restore" => "Recuperar", "Error" => "Error", -"Deleted Files" => "Archivos eliminados", "restored" => "recuperado", "Nothing in here. Your trash bin is empty!" => "No hay nada acá. ¡La papelera está vacía!", "Name" => "Nombre", -"Restore" => "Recuperar", "Deleted" => "Borrado", "Delete" => "Borrar" ); diff --git a/apps/files_trashbin/l10n/es_MX.php b/apps/files_trashbin/l10n/es_MX.php index c0dc6bb45c29e375dacf88b377b7efc611ba9a21..c3db7765154ae4b27f4c5451a7c4a132e33c0945 100644 --- a/apps/files_trashbin/l10n/es_MX.php +++ b/apps/files_trashbin/l10n/es_MX.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "No se puede eliminar %s permanentemente", "Couldn't restore %s" => "No se puede restaurar %s", "Deleted files" => "Archivos eliminados", +"Restore" => "Recuperar", "Error" => "Error", -"Deleted Files" => "Archivos Eliminados", "restored" => "recuperado", "Nothing in here. Your trash bin is empty!" => "No hay nada aquí. ¡Tu papelera esta vacía!", "Name" => "Nombre", -"Restore" => "Recuperar", "Deleted" => "Eliminado", "Delete" => "Eliminar" ); diff --git a/apps/files_trashbin/l10n/et_EE.php b/apps/files_trashbin/l10n/et_EE.php index 69d20cb195ff7a35b1e40bf3d283288ff3d018ba..c1c9ea66c4f56a0e21ac900dc0617b7864102628 100644 --- a/apps/files_trashbin/l10n/et_EE.php +++ b/apps/files_trashbin/l10n/et_EE.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "%s jäädavalt kustutamine ebaõnnestus", "Couldn't restore %s" => "%s ei saa taastada", "Deleted files" => "Kustutatud failid", +"Restore" => "Taasta", "Error" => "Viga", -"Deleted Files" => "Kustutatud failid", "restored" => "taastatud", "Nothing in here. Your trash bin is empty!" => "Siin pole midagi. Sinu prügikast on tühi!", "Name" => "Nimi", -"Restore" => "Taasta", "Deleted" => "Kustutatud", "Delete" => "Kustuta" ); diff --git a/apps/files_trashbin/l10n/eu.php b/apps/files_trashbin/l10n/eu.php index 42476bccfe4d05388999124e2e4e6c63f3a25b90..63c1245da061fcc762edff372f0ddfdeb850f779 100644 --- a/apps/files_trashbin/l10n/eu.php +++ b/apps/files_trashbin/l10n/eu.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Ezin izan da %s betirako ezabatu", "Couldn't restore %s" => "Ezin izan da %s berreskuratu", "Deleted files" => "Ezabatutako fitxategiak", +"Restore" => "Berrezarri", "Error" => "Errorea", -"Deleted Files" => "Ezabatutako Fitxategiak", "restored" => "Berrezarrita", "Nothing in here. Your trash bin is empty!" => "Ez dago ezer ez. Zure zakarrontzia hutsik dago!", "Name" => "Izena", -"Restore" => "Berrezarri", "Deleted" => "Ezabatuta", "Delete" => "Ezabatu" ); diff --git a/apps/files_trashbin/l10n/fa.php b/apps/files_trashbin/l10n/fa.php index 407524eb62050960823df51fd14e65f5985e274f..0823e98ea1c758c0a54daa78e7e4472db5ca0573 100644 --- a/apps/files_trashbin/l10n/fa.php +++ b/apps/files_trashbin/l10n/fa.php @@ -3,11 +3,10 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "%s را نمی توان برای همیشه حذف کرد", "Couldn't restore %s" => "%s را نمی توان بازگرداند", "Deleted files" => "فایل های حذف شده", +"Restore" => "بازیابی", "Error" => "خطا", -"Deleted Files" => "فایلهای حذف شده", "Nothing in here. Your trash bin is empty!" => "هیچ چیزی اینجا نیست. سطل زباله ی شما خالی است.", "Name" => "نام", -"Restore" => "بازیابی", "Deleted" => "حذف شده", "Delete" => "حذف" ); diff --git a/apps/files_trashbin/l10n/fi_FI.php b/apps/files_trashbin/l10n/fi_FI.php index da56baf0bd7fa08b48f19bb2e37ddb830d456615..158fc7dac55c88ae772fdfbdea59298aa8bd03aa 100644 --- a/apps/files_trashbin/l10n/fi_FI.php +++ b/apps/files_trashbin/l10n/fi_FI.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Kohdetta %s ei voitu poistaa pysyvästi", "Couldn't restore %s" => "Kohteen %s palautus epäonnistui", "Deleted files" => "Poistetut tiedostot", +"Restore" => "Palauta", "Error" => "Virhe", -"Deleted Files" => "Poistetut tiedostot", "restored" => "palautettu", "Nothing in here. Your trash bin is empty!" => "Tyhjää täynnä! Roskakorissa ei ole mitään.", "Name" => "Nimi", -"Restore" => "Palauta", "Deleted" => "Poistettu", "Delete" => "Poista" ); diff --git a/apps/files_trashbin/l10n/fr.php b/apps/files_trashbin/l10n/fr.php index b71fbea96ad09bc657905a869ee1a9d5b773d31f..0e6330bb2d0f915b7a4560f315b712ae7f811afa 100644 --- a/apps/files_trashbin/l10n/fr.php +++ b/apps/files_trashbin/l10n/fr.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Impossible d'effacer %s de façon permanente", "Couldn't restore %s" => "Impossible de restaurer %s", "Deleted files" => "Fichiers supprimés", +"Restore" => "Restaurer", "Error" => "Erreur", -"Deleted Files" => "Fichiers effacés", "restored" => "restauré", "Nothing in here. Your trash bin is empty!" => "Il n'y a rien ici. Votre corbeille est vide !", "Name" => "Nom", -"Restore" => "Restaurer", "Deleted" => "Effacé", "Delete" => "Supprimer" ); diff --git a/apps/files_trashbin/l10n/gl.php b/apps/files_trashbin/l10n/gl.php index fe74ab34a02d5655ae03155958a787797dc4df5b..143cf0e6df564d3fff90c8d72124e38ffb53882e 100644 --- a/apps/files_trashbin/l10n/gl.php +++ b/apps/files_trashbin/l10n/gl.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Non foi posíbel eliminar %s permanente", "Couldn't restore %s" => "Non foi posíbel restaurar %s", "Deleted files" => "Ficheiros eliminados", +"Restore" => "Restablecer", "Error" => "Erro", -"Deleted Files" => "Ficheiros eliminados", "restored" => "restaurado", "Nothing in here. Your trash bin is empty!" => "Aquí non hai nada. O cesto do lixo está baleiro!", "Name" => "Nome", -"Restore" => "Restablecer", "Deleted" => "Eliminado", "Delete" => "Eliminar" ); diff --git a/apps/files_trashbin/l10n/he.php b/apps/files_trashbin/l10n/he.php index 6cdc5c05c9d0985fd52a13c0dcef7914c4cdaf90..90b3fd11ab52a65f39a6980fb226f2b92831e59c 100644 --- a/apps/files_trashbin/l10n/he.php +++ b/apps/files_trashbin/l10n/he.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "לא ניתן למחוק את %s לצמיתות", "Couldn't restore %s" => "לא ניתן לשחזר את %s", "Deleted files" => "קבצים שנמחקו", +"Restore" => "שחזור", "Error" => "שגיאה", -"Deleted Files" => "קבצים שנמחקו", "restored" => "שוחזר", "Nothing in here. Your trash bin is empty!" => "אין כאן שום דבר. סל המיחזור שלך ריק!", "Name" => "שם", -"Restore" => "שחזור", "Deleted" => "נמחק", "Delete" => "מחיקה" ); diff --git a/apps/files_trashbin/l10n/hu_HU.php b/apps/files_trashbin/l10n/hu_HU.php index 2912821d96f97c32c4f7d3af58589b0f7d92592f..60f3ebad8569938d6120dd16fc964affe1a2cb56 100644 --- a/apps/files_trashbin/l10n/hu_HU.php +++ b/apps/files_trashbin/l10n/hu_HU.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Nem sikerült %s végleges törlése", "Couldn't restore %s" => "Nem sikerült %s visszaállítása", "Deleted files" => "Törölt fájlok", +"Restore" => "Visszaállítás", "Error" => "Hiba", -"Deleted Files" => "Törölt fájlok", "restored" => "visszaállítva", "Nothing in here. Your trash bin is empty!" => "Itt nincs semmi. Az Ön szemetes mappája üres!", "Name" => "Név", -"Restore" => "Visszaállítás", "Deleted" => "Törölve", "Delete" => "Törlés" ); diff --git a/apps/files_trashbin/l10n/id.php b/apps/files_trashbin/l10n/id.php index 166b9aa811a2441f4099c091c1fbee3a4c6336dd..bba9e329eebcc0890ed7b63658c8da099fe74876 100644 --- a/apps/files_trashbin/l10n/id.php +++ b/apps/files_trashbin/l10n/id.php @@ -3,11 +3,10 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Tidak dapat menghapus permanen %s", "Couldn't restore %s" => "Tidak dapat memulihkan %s", "Deleted files" => "Berkas yang dihapus", +"Restore" => "Pulihkan", "Error" => "Galat", -"Deleted Files" => "Berkas yang Dihapus", "Nothing in here. Your trash bin is empty!" => "Tempat sampah anda kosong!", "Name" => "Nama", -"Restore" => "Pulihkan", "Deleted" => "Dihapus", "Delete" => "Hapus" ); diff --git a/apps/files_trashbin/l10n/it.php b/apps/files_trashbin/l10n/it.php index 057305ac517e6b09be9904d7890a0976d271ea54..905384b82bb96c72d99ca6cc01c82dbe1bb130fc 100644 --- a/apps/files_trashbin/l10n/it.php +++ b/apps/files_trashbin/l10n/it.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Impossibile eliminare %s definitivamente", "Couldn't restore %s" => "Impossibile ripristinare %s", "Deleted files" => "File eliminati", +"Restore" => "Ripristina", "Error" => "Errore", -"Deleted Files" => "File eliminati", "restored" => "ripristinati", "Nothing in here. Your trash bin is empty!" => "Qui non c'è niente. Il tuo cestino è vuoto.", "Name" => "Nome", -"Restore" => "Ripristina", "Deleted" => "Eliminati", "Delete" => "Elimina" ); diff --git a/apps/files_trashbin/l10n/ja.php b/apps/files_trashbin/l10n/ja.php index 13ca95e6fb4e38fa70d66d1259c59e2b02825faf..b24e40aa23d5b0e76e4c2ec8d31034e6703b7961 100644 --- a/apps/files_trashbin/l10n/ja.php +++ b/apps/files_trashbin/l10n/ja.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "%s を完全に削除できませんでした", "Couldn't restore %s" => "%s を復元できませんでした", "Deleted files" => "ゴミ箱", +"Restore" => "復元", "Error" => "エラー", -"Deleted Files" => "ゴミ箱", "restored" => "復元済", "Nothing in here. Your trash bin is empty!" => "ここには何もありません。ゴミ箱は空です!", "Name" => "名前", -"Restore" => "復元", "Deleted" => "削除済み", "Delete" => "削除" ); diff --git a/apps/files_trashbin/l10n/ka_GE.php b/apps/files_trashbin/l10n/ka_GE.php index 4e3ad4260e3ab9e15e520342dc960b7cd1275f11..16e147bd416f72648391987de5d744f536c73512 100644 --- a/apps/files_trashbin/l10n/ka_GE.php +++ b/apps/files_trashbin/l10n/ka_GE.php @@ -3,11 +3,10 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "ფაილი %s–ის სრულად წაშლა ვერ მოხერხდა", "Couldn't restore %s" => "%s–ის აღდგენა ვერ მოხერხდა", "Deleted files" => "წაშლილი ფაილები", +"Restore" => "აღდგენა", "Error" => "შეცდომა", -"Deleted Files" => "წაშლილი ფაილები", "Nothing in here. Your trash bin is empty!" => "აქ არაფერი არ არის. სანაგვე ყუთი ცარიელია!", "Name" => "სახელი", -"Restore" => "აღდგენა", "Deleted" => "წაშლილი", "Delete" => "წაშლა" ); diff --git a/apps/files_trashbin/l10n/km.php b/apps/files_trashbin/l10n/km.php index 1df805de2d607d18271e3561686eab3f08410362..40119afc8781a9a4d75ec68fd6c1b3545c75da2d 100644 --- a/apps/files_trashbin/l10n/km.php +++ b/apps/files_trashbin/l10n/km.php @@ -1,8 +1,14 @@ "មិន​អាច​លុប %s ចោល​ជា​អចិន្ត្រៃយ៍​ទេ", +"Couldn't restore %s" => "មិន​អាច​ស្ដារ %s ឡើង​វិញ​បាន​ទេ", +"Deleted files" => "ឯកសារ​ដែល​បាន​លុប", +"Restore" => "ស្ដារ​មក​វិញ", "Error" => "កំហុស", +"restored" => "បាន​ស្ដារ​វិញ", +"Nothing in here. Your trash bin is empty!" => "គ្មាន​អ្វី​នៅ​ទីនេះ​ទេ។ ធុង​សំរាម​របស់​អ្នក​គឺ​ទទេ!", "Name" => "ឈ្មោះ", -"Restore" => "ស្ដារ​មក​វិញ", +"Deleted" => "បាន​លុប", "Delete" => "លុប" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files_trashbin/l10n/ko.php b/apps/files_trashbin/l10n/ko.php index d9d870708047b562deee62c9e193e70f71d0e048..98800fd2e583911c42792d30271ef9f596bf6012 100644 --- a/apps/files_trashbin/l10n/ko.php +++ b/apps/files_trashbin/l10n/ko.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "%s을(를_ 영구적으로 삭제할 수 없습니다", "Couldn't restore %s" => "%s을(를) 복원할 수 없습니다", "Deleted files" => "삭제된 파일", +"Restore" => "복원", "Error" => "오류", -"Deleted Files" => "삭제된 파일", "restored" => "복원됨", "Nothing in here. Your trash bin is empty!" => "휴지통이 비어 있습니다!", "Name" => "이름", -"Restore" => "복원", "Deleted" => "삭제됨", "Delete" => "삭제" ); diff --git a/apps/files_trashbin/l10n/lt_LT.php b/apps/files_trashbin/l10n/lt_LT.php index 2bf545483f6ec1e30efdb95908b8288084cb31d3..fa65d7eabac0b32e756c3b9347ae764f0c1116af 100644 --- a/apps/files_trashbin/l10n/lt_LT.php +++ b/apps/files_trashbin/l10n/lt_LT.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Nepavyko negrįžtamai ištrinti %s", "Couldn't restore %s" => "Nepavyko atkurti %s", "Deleted files" => "Ištrinti failai", +"Restore" => "Atstatyti", "Error" => "Klaida", -"Deleted Files" => "Ištrinti failai", "restored" => "atstatyta", "Nothing in here. Your trash bin is empty!" => "Nieko nėra. Jūsų šiukšliadėžė tuščia!", "Name" => "Pavadinimas", -"Restore" => "Atstatyti", "Deleted" => "Ištrinti", "Delete" => "Ištrinti" ); diff --git a/apps/files_trashbin/l10n/lv.php b/apps/files_trashbin/l10n/lv.php index c173d0501477774111301adfd2f5d28dc21acc18..3432f9ac75eff98a8a347ee0c8d75e1f8d38f32f 100644 --- a/apps/files_trashbin/l10n/lv.php +++ b/apps/files_trashbin/l10n/lv.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Nevarēja pilnībā izdzēst %s", "Couldn't restore %s" => "Nevarēja atjaunot %s", "Deleted files" => "Dzēstās datnes", +"Restore" => "Atjaunot", "Error" => "Kļūda", -"Deleted Files" => "Dzēstās datnes", "restored" => "atjaunots", "Nothing in here. Your trash bin is empty!" => "Šeit nekā nav. Jūsu miskaste ir tukša!", "Name" => "Nosaukums", -"Restore" => "Atjaunot", "Deleted" => "Dzēsts", "Delete" => "Dzēst" ); diff --git a/apps/files_trashbin/l10n/mk.php b/apps/files_trashbin/l10n/mk.php index 910b11e21e603de847d78ea8742285a8e687940f..66c2d0a2961b6e83758c02426c7619749f8e8f87 100644 --- a/apps/files_trashbin/l10n/mk.php +++ b/apps/files_trashbin/l10n/mk.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Не можеше трајно да се избрише %s", "Couldn't restore %s" => "Не можеше да се поврати %s", "Deleted files" => "Избришани датотеки", +"Restore" => "Поврати", "Error" => "Грешка", -"Deleted Files" => "Избришани датотеки", "restored" => "повратени", "Nothing in here. Your trash bin is empty!" => "Тука нема ништо. Вашата корпа за отпадоци е празна!", "Name" => "Име", -"Restore" => "Поврати", "Deleted" => "Избришан", "Delete" => "Избриши" ); diff --git a/apps/files_trashbin/l10n/ms_MY.php b/apps/files_trashbin/l10n/ms_MY.php index f084f58465dca8e4afa59f44c3dca3e0a92db11f..fdfd922438c5105723ee6509969129111dac85a7 100644 --- a/apps/files_trashbin/l10n/ms_MY.php +++ b/apps/files_trashbin/l10n/ms_MY.php @@ -2,12 +2,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Tidak dapat menghapuskan %s secara kekal", "Couldn't restore %s" => "Tidak dapat memulihkan %s", +"Restore" => "Pulihkan", "Error" => "Ralat", -"Deleted Files" => "Fail Dihapus", "restored" => "dipulihkan", "Nothing in here. Your trash bin is empty!" => "Tiada apa disini. Tong sampah anda kosong!", "Name" => "Nama", -"Restore" => "Pulihkan", "Deleted" => "Dihapuskan", "Delete" => "Padam" ); diff --git a/apps/files_trashbin/l10n/nb_NO.php b/apps/files_trashbin/l10n/nb_NO.php index 2293e5a4e7b3265459fc282f34957fe06523a193..519b4e5aa24b2b142cfcb986944a9931ea14afc3 100644 --- a/apps/files_trashbin/l10n/nb_NO.php +++ b/apps/files_trashbin/l10n/nb_NO.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Kunne ikke slette %s fullstendig", "Couldn't restore %s" => "Kunne ikke gjenopprette %s", "Deleted files" => "Slettede filer", +"Restore" => "Gjenopprett", "Error" => "Feil", -"Deleted Files" => "Slettede filer", "restored" => "gjenopprettet", "Nothing in here. Your trash bin is empty!" => "Ingenting her. Søppelkassen din er tom!", "Name" => "Navn", -"Restore" => "Gjenopprett", "Deleted" => "Slettet", "Delete" => "Slett" ); diff --git a/apps/files_trashbin/l10n/nl.php b/apps/files_trashbin/l10n/nl.php index c8fb12885387f371d23cbf296e7cdc6f313bb99a..41dfa86b7a705d238c248d0473c635ff2121ecec 100644 --- a/apps/files_trashbin/l10n/nl.php +++ b/apps/files_trashbin/l10n/nl.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Kon %s niet permanent verwijderen", "Couldn't restore %s" => "Kon %s niet herstellen", "Deleted files" => "Verwijderde bestanden", +"Restore" => "Herstellen", "Error" => "Fout", -"Deleted Files" => "Verwijderde bestanden", "restored" => "hersteld", "Nothing in here. Your trash bin is empty!" => "Niets te vinden. Uw prullenbak is leeg!", "Name" => "Naam", -"Restore" => "Herstellen", "Deleted" => "Verwijderd", "Delete" => "Verwijder" ); diff --git a/apps/files_trashbin/l10n/nn_NO.php b/apps/files_trashbin/l10n/nn_NO.php index 38bc64e6ce505bcca607a141660fb2c0869ffd94..aa18927b1fd34eb516c11bd6aa3386d7fdc90777 100644 --- a/apps/files_trashbin/l10n/nn_NO.php +++ b/apps/files_trashbin/l10n/nn_NO.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Klarte ikkje sletta %s for godt", "Couldn't restore %s" => "Klarte ikkje gjenoppretta %s", "Deleted files" => "Sletta filer", +"Restore" => "Gjenopprett", "Error" => "Feil", -"Deleted Files" => "Sletta filer", "restored" => "gjenoppretta", "Nothing in here. Your trash bin is empty!" => "Ingenting her. Papirkorga di er tom!", "Name" => "Namn", -"Restore" => "Gjenopprett", "Deleted" => "Sletta", "Delete" => "Slett" ); diff --git a/apps/files_trashbin/l10n/pl.php b/apps/files_trashbin/l10n/pl.php index b961efd7daeee7dcbefb2d6d0ab3dfe0e032f5be..16bb9dbfa2fd8373219396c0ae254f8337ab1651 100644 --- a/apps/files_trashbin/l10n/pl.php +++ b/apps/files_trashbin/l10n/pl.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Nie można trwale usunąć %s", "Couldn't restore %s" => "Nie można przywrócić %s", "Deleted files" => "Pliki usunięte", +"Restore" => "Przywróć", "Error" => "Błąd", -"Deleted Files" => "Usunięte pliki", "restored" => "przywrócony", "Nothing in here. Your trash bin is empty!" => "Nic tu nie ma. Twój kosz jest pusty!", "Name" => "Nazwa", -"Restore" => "Przywróć", "Deleted" => "Usunięte", "Delete" => "Usuń" ); diff --git a/apps/files_trashbin/l10n/pt_BR.php b/apps/files_trashbin/l10n/pt_BR.php index d524d8879e23f3040215e6a1fc58dbf941fbe16c..b7dd346b40a061128e8caf014cbe9c393cd3eeb5 100644 --- a/apps/files_trashbin/l10n/pt_BR.php +++ b/apps/files_trashbin/l10n/pt_BR.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Não foi possível excluir %s permanentemente", "Couldn't restore %s" => "Não foi possível restaurar %s", "Deleted files" => "Arquivos apagados", +"Restore" => "Restaurar", "Error" => "Erro", -"Deleted Files" => "Arquivos Apagados", "restored" => "restaurado", "Nothing in here. Your trash bin is empty!" => "Nada aqui. Sua lixeira está vazia!", "Name" => "Nome", -"Restore" => "Restaurar", "Deleted" => "Excluído", "Delete" => "Excluir" ); diff --git a/apps/files_trashbin/l10n/pt_PT.php b/apps/files_trashbin/l10n/pt_PT.php index 94dd0eb707a99af065bdd2557b876b94a2a17a1e..8a18d842c937d2843a3e63ec17b28d08bbd816a0 100644 --- a/apps/files_trashbin/l10n/pt_PT.php +++ b/apps/files_trashbin/l10n/pt_PT.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Não foi possível eliminar %s de forma permanente", "Couldn't restore %s" => "Não foi possível restaurar %s", "Deleted files" => "Ficheiros eliminados", +"Restore" => "Restaurar", "Error" => "Erro", -"Deleted Files" => "Ficheiros Apagados", "restored" => "Restaurado", "Nothing in here. Your trash bin is empty!" => "Não hà ficheiros. O lixo está vazio!", "Name" => "Nome", -"Restore" => "Restaurar", "Deleted" => "Apagado", "Delete" => "Eliminar" ); diff --git a/apps/files_trashbin/l10n/ru.php b/apps/files_trashbin/l10n/ru.php index d10369b9ca1eee47448d45af38857729d8aa73ea..8d00e0824183e00b5c6094296f2fe8dac59e53f5 100644 --- a/apps/files_trashbin/l10n/ru.php +++ b/apps/files_trashbin/l10n/ru.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "%s не может быть удалён навсегда", "Couldn't restore %s" => "%s не может быть восстановлен", "Deleted files" => "Удалённые файлы", +"Restore" => "Восстановить", "Error" => "Ошибка", -"Deleted Files" => "Удаленные файлы", "restored" => "восстановлен", "Nothing in here. Your trash bin is empty!" => "Здесь ничего нет. Ваша корзина пуста!", "Name" => "Имя", -"Restore" => "Восстановить", "Deleted" => "Удалён", "Delete" => "Удалить" ); diff --git a/apps/files_trashbin/l10n/sk_SK.php b/apps/files_trashbin/l10n/sk_SK.php index 3badd3a423bd1798ff3f024ad424a8644265bdc8..7588b555d96f4d35281e42616df9c5e63d9a2a00 100644 --- a/apps/files_trashbin/l10n/sk_SK.php +++ b/apps/files_trashbin/l10n/sk_SK.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Nemožno zmazať %s navždy", "Couldn't restore %s" => "Nemožno obnoviť %s", "Deleted files" => "Zmazané súbory", +"Restore" => "Obnoviť", "Error" => "Chyba", -"Deleted Files" => "Zmazané súbory", "restored" => "obnovené", "Nothing in here. Your trash bin is empty!" => "Žiadny obsah. Kôš je prázdny!", "Name" => "Názov", -"Restore" => "Obnoviť", "Deleted" => "Zmazané", "Delete" => "Zmazať" ); diff --git a/apps/files_trashbin/l10n/sl.php b/apps/files_trashbin/l10n/sl.php index 08da9b1c6e90c8c4b78ca6ef2c16838559a1a66f..f9dc5112ac30850c8480ffcc3d6402a13ed0af4e 100644 --- a/apps/files_trashbin/l10n/sl.php +++ b/apps/files_trashbin/l10n/sl.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Datoteke %s ni mogoče trajno izbrisati.", "Couldn't restore %s" => "Ni mogoče obnoviti %s", "Deleted files" => "Izbrisane datoteke", +"Restore" => "Obnovi", "Error" => "Napaka", -"Deleted Files" => "Izbrisane datoteke", "restored" => "obnovljeno", "Nothing in here. Your trash bin is empty!" => "Mapa smeti je prazna.", "Name" => "Ime", -"Restore" => "Obnovi", "Deleted" => "Izbrisano", "Delete" => "Izbriši" ); diff --git a/apps/files_trashbin/l10n/sq.php b/apps/files_trashbin/l10n/sq.php index 60d16f9b913a397525b35c81a6c8071ff7b8ade0..9e16b7a7bfd97a499f4699dc3aa8bbb35817374e 100644 --- a/apps/files_trashbin/l10n/sq.php +++ b/apps/files_trashbin/l10n/sq.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Nuk munda ta eliminoj përfundimisht %s", "Couldn't restore %s" => "Nuk munda ta rivendos %s", "Deleted files" => "Skedarë të fshirë ", +"Restore" => "Rivendos", "Error" => "Veprim i gabuar", -"Deleted Files" => "Skedarë të eliminuar", "restored" => "rivendosur", "Nothing in here. Your trash bin is empty!" => "Këtu nuk ka asgjë. Koshi juaj është bosh!", "Name" => "Emri", -"Restore" => "Rivendos", "Deleted" => "Eliminuar", "Delete" => "Elimino" ); diff --git a/apps/files_trashbin/l10n/sr.php b/apps/files_trashbin/l10n/sr.php index 7fb4c85ab634ce64caa93d62813b49a7467b6948..d4abc908c911220bd0ee14f12238e5575fbdf3e5 100644 --- a/apps/files_trashbin/l10n/sr.php +++ b/apps/files_trashbin/l10n/sr.php @@ -1,10 +1,10 @@ "Обрисане датотеке", +"Restore" => "Врати", "Error" => "Грешка", "Nothing in here. Your trash bin is empty!" => "Овде нема ништа. Корпа за отпатке је празна.", "Name" => "Име", -"Restore" => "Врати", "Deleted" => "Обрисано", "Delete" => "Обриши" ); diff --git a/apps/files_trashbin/l10n/sv.php b/apps/files_trashbin/l10n/sv.php index fd9ca8653f3e58856f0058b315846756d7d2118f..330bcc3482174482ce88a9d3fd23aebd28d93203 100644 --- a/apps/files_trashbin/l10n/sv.php +++ b/apps/files_trashbin/l10n/sv.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Kunde inte radera %s permanent", "Couldn't restore %s" => "Kunde inte återställa %s", "Deleted files" => "Raderade filer", +"Restore" => "Återskapa", "Error" => "Fel", -"Deleted Files" => "Raderade filer", "restored" => "återställd", "Nothing in here. Your trash bin is empty!" => "Ingenting här. Din papperskorg är tom!", "Name" => "Namn", -"Restore" => "Återskapa", "Deleted" => "Raderad", "Delete" => "Radera" ); diff --git a/apps/files_trashbin/l10n/th_TH.php b/apps/files_trashbin/l10n/th_TH.php index 857737c59e86a873b3a88493b7e93887194f1848..47c3450d2eaa33455775000e404a64c34ee05898 100644 --- a/apps/files_trashbin/l10n/th_TH.php +++ b/apps/files_trashbin/l10n/th_TH.php @@ -1,10 +1,9 @@ "คืนค่า", "Error" => "ข้อผิดพลาด", -"Deleted Files" => "ไฟล์ที่ลบทิ้ง", "Nothing in here. Your trash bin is empty!" => "ไม่มีอะไรอยู่ในนี้ ถังขยะของคุณยังว่างอยู่", "Name" => "ชื่อ", -"Restore" => "คืนค่า", "Deleted" => "ลบแล้ว", "Delete" => "ลบ" ); diff --git a/apps/files_trashbin/l10n/tr.php b/apps/files_trashbin/l10n/tr.php index ff4227e38c74a8d2c99b423b7e63e760a0237209..ab7441b822907fc2fbcb23e2d78c4923e56f838b 100644 --- a/apps/files_trashbin/l10n/tr.php +++ b/apps/files_trashbin/l10n/tr.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "%s alıcı olarak silinemedi", "Couldn't restore %s" => "%s geri yüklenemedi", "Deleted files" => "Silinmiş dosyalar", +"Restore" => "Geri yükle", "Error" => "Hata", -"Deleted Files" => "Silinen Dosyalar", "restored" => "geri yüklendi", "Nothing in here. Your trash bin is empty!" => "Burada hiçbir şey yok. Çöp kutunuz tamamen boş!", "Name" => "İsim", -"Restore" => "Geri yükle", "Deleted" => "Silindi", "Delete" => "Sil" ); diff --git a/apps/files_trashbin/l10n/uk.php b/apps/files_trashbin/l10n/uk.php index fa523fa3218685fbff12f8678c441d5699f12a89..328e8da5e02cc0633f5c32420a9b93b413f96b86 100644 --- a/apps/files_trashbin/l10n/uk.php +++ b/apps/files_trashbin/l10n/uk.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Неможливо видалити %s назавжди", "Couldn't restore %s" => "Неможливо відновити %s", "Deleted files" => "Видалено файлів", +"Restore" => "Відновити", "Error" => "Помилка", -"Deleted Files" => "Видалено Файлів", "restored" => "відновлено", "Nothing in here. Your trash bin is empty!" => "Нічого немає. Ваший кошик для сміття пустий!", "Name" => "Ім'я", -"Restore" => "Відновити", "Deleted" => "Видалено", "Delete" => "Видалити" ); diff --git a/apps/files_trashbin/l10n/ur_PK.php b/apps/files_trashbin/l10n/ur_PK.php index 49c82f53872c84830aff3465f8f713e57363bded..fc71b528ced8dec79cecac7b2277b8b9f9fa1393 100644 --- a/apps/files_trashbin/l10n/ur_PK.php +++ b/apps/files_trashbin/l10n/ur_PK.php @@ -1,5 +1,14 @@ "ایرر" +"Couldn't delete %s permanently" => "حذف نہیں ہو سکتا %s مستقل طور پر", +"Couldn't restore %s" => "بحال نہيں کيا جا سکتا %s", +"Deleted files" => "حذف شدہ فائليں", +"Restore" => "بحال", +"Error" => "ایرر", +"restored" => "بحال شدہ", +"Nothing in here. Your trash bin is empty!" => " یہاں کچھ بھی نہیں .آپکی ردی کی ٹوکری خالی ہے.", +"Name" => "اسم", +"Deleted" => "حذف شدہ ", +"Delete" => "حذف کریں" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_trashbin/l10n/vi.php b/apps/files_trashbin/l10n/vi.php index 57c82cea5f75d99f206278464948e2c40d745b46..d374effcabb36165dd97c4bc45baac23740c0212 100644 --- a/apps/files_trashbin/l10n/vi.php +++ b/apps/files_trashbin/l10n/vi.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Không thể xóa %s vĩnh viễn", "Couldn't restore %s" => "Không thể khôi phục %s", "Deleted files" => "File đã bị xóa", +"Restore" => "Khôi phục", "Error" => "Lỗi", -"Deleted Files" => "File đã xóa", "restored" => "khôi phục", "Nothing in here. Your trash bin is empty!" => "Không có gì ở đây. Thùng rác của bạn rỗng!", "Name" => "Tên", -"Restore" => "Khôi phục", "Deleted" => "Đã xóa", "Delete" => "Xóa" ); diff --git a/apps/files_trashbin/l10n/zh_CN.php b/apps/files_trashbin/l10n/zh_CN.php index ef6a63b29593e72ddd96e05c06cdc842a607de08..49cd412299e7d85cff296e4d4268b371485af624 100644 --- a/apps/files_trashbin/l10n/zh_CN.php +++ b/apps/files_trashbin/l10n/zh_CN.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "无法彻底删除文件%s", "Couldn't restore %s" => "无法恢复%s", "Deleted files" => "已删除文件", +"Restore" => "恢复", "Error" => "错误", -"Deleted Files" => "已删除文件", "restored" => "已恢复", "Nothing in here. Your trash bin is empty!" => "这里没有东西. 你的回收站是空的!", "Name" => "名称", -"Restore" => "恢复", "Deleted" => "已删除", "Delete" => "删除" ); diff --git a/apps/files_trashbin/l10n/zh_TW.php b/apps/files_trashbin/l10n/zh_TW.php index c42d70790e92e3f2e5cf5a060288a668f00f0d7b..014527083e3d082c2eff0a9de96a18c022b48783 100644 --- a/apps/files_trashbin/l10n/zh_TW.php +++ b/apps/files_trashbin/l10n/zh_TW.php @@ -3,12 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "無法永久刪除 %s", "Couldn't restore %s" => "無法還原 %s", "Deleted files" => "回收桶", +"Restore" => "還原", "Error" => "錯誤", -"Deleted Files" => "已刪除的檔案", "restored" => "已還原", "Nothing in here. Your trash bin is empty!" => "您的回收桶是空的!", "Name" => "名稱", -"Restore" => "還原", "Deleted" => "已刪除", "Delete" => "刪除" ); diff --git a/apps/files_trashbin/lib/helper.php b/apps/files_trashbin/lib/helper.php index e6ca73520a6fe5bb747d7ff06e3c4ea5152e7afe..ebedce31abe107c6af6126d819a01c5fdc589b35 100644 --- a/apps/files_trashbin/lib/helper.php +++ b/apps/files_trashbin/lib/helper.php @@ -8,16 +8,19 @@ class Helper { /** * 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 $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){ + public static function getTrashFiles($dir, $sortAttribute = '', $sortDescending = false){ $result = array(); $timestamp = null; $user = \OCP\User::getUser(); - $view = new \OC_Filesystemview('/' . $user . '/files_trashbin/files'); + $view = new \OC\Files\View('/' . $user . '/files_trashbin/files'); if (ltrim($dir, '/') !== '' && !$view->is_dir($dir)) { throw new \Exception('Directory does not exists'); @@ -57,8 +60,9 @@ class Helper closedir($dirContent); } - usort($result, array('\OCA\Files\Helper', 'fileCmp')); - + if ($sortAttribute !== '') { + return \OCA\Files\Helper::sortFiles($result, $sortAttribute, $sortDescending); + } return $result; } diff --git a/apps/files_trashbin/lib/hooks.php b/apps/files_trashbin/lib/hooks.php index b2c6bc1df50988c960f5dfb54a96ab29f4aad8a2..b6f0fb7e547882bb2bccd80945b5298070a5b1e0 100644 --- a/apps/files_trashbin/lib/hooks.php +++ b/apps/files_trashbin/lib/hooks.php @@ -29,8 +29,8 @@ namespace OCA\Files_Trashbin; class Hooks { /** - * @brief Copy files to trash bin - * @param array + * Copy files to trash bin + * @param array $params * * This function is connected to the delete signal of OC_Filesystem * to copy the file to the trash bin @@ -44,8 +44,8 @@ class Hooks { } /** - * @brief clean up user specific settings if user gets deleted - * @param array with uid + * clean up user specific settings if user gets deleted + * @param array $params array with uid * * This function is connected to the pre_deleteUser signal of OC_Users * to remove the used space for the trash bin stored in the database @@ -56,7 +56,7 @@ class Hooks { Trashbin::deleteUser($uid); } } - + public static function post_write_hook($params) { Trashbin::resizeTrash(\OCP\User::getUser()); } diff --git a/apps/files_trashbin/lib/trashbin.php b/apps/files_trashbin/lib/trashbin.php index 173eb2164cf55713a9ca944629325a9090129924..e95f1b13c37fbfb98dc9226530188860740bb4f2 100644 --- a/apps/files_trashbin/lib/trashbin.php +++ b/apps/files_trashbin/lib/trashbin.php @@ -62,7 +62,7 @@ class Trashbin { /** - * @brief copy file to owners trash + * copy file to owners trash * @param string $sourcePath * @param string $owner * @param string $ownerPath @@ -96,7 +96,7 @@ class Trashbin { /** * move file to the trash bin * - * @param $file_path path to the deleted file/directory relative to the files root directory + * @param string $file_path path to the deleted file/directory relative to the files root directory */ public static function move2trash($file_path) { $user = \OCP\User::getUser(); @@ -155,11 +155,11 @@ class Trashbin { /** * Move file versions to trash so that they can be restored later * - * @param $file_path path to original file - * @param $filename of deleted file + * @param string $file_path path to original file + * @param string $filename of deleted file * @param integer $timestamp when the file was deleted * - * @return size of stored versions + * @return int size of stored versions */ private static function retainVersions($file_path, $filename, $timestamp) { $size = 0; @@ -200,11 +200,11 @@ class Trashbin { /** * Move encryption keys to trash so that they can be restored later * - * @param $file_path path to original file - * @param $filename of deleted file + * @param string $file_path path to original file + * @param string $filename of deleted file * @param integer $timestamp when the file was deleted * - * @return size of encryption keys + * @return int size of encryption keys */ private static function retainEncryptionKeys($file_path, $filename, $timestamp) { $size = 0; @@ -216,7 +216,7 @@ class Trashbin { list($owner, $ownerPath) = self::getUidAndFilename($file_path); - $util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), $user); + $util = new \OCA\Encryption\Util(new \OC\Files\View('/'), $user); // disable proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; @@ -299,9 +299,9 @@ 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 + * @param string $file path to the deleted file + * @param string $filename name of the file + * @param int $timestamp time when the file was deleted * * @return bool */ @@ -373,14 +373,14 @@ class Trashbin { } /** - * @brief restore versions from trash bin + * restore versions from trash bin * * @param \OC\Files\View $view file view - * @param $file complete path to file - * @param $filename name of file once it was deleted + * @param string $file complete path to file + * @param string $filename name of file once it was deleted * @param string $uniqueFilename new file name to restore the file without overwriting existing files - * @param $location location if file - * @param $timestamp deleteion time + * @param string $location location if file + * @param int $timestamp deleteion time * */ private static function restoreVersions($view, $file, $filename, $uniqueFilename, $location, $timestamp) { @@ -421,14 +421,14 @@ class Trashbin { } /** - * @brief restore encryption keys from trash bin + * restore encryption keys from trash bin * * @param \OC\Files\View $view - * @param $file complete path to file - * @param $filename name of file + * @param string $file complete path to file + * @param string $filename name of file * @param string $uniqueFilename new file name to restore the file without overwriting existing files - * @param $location location of file - * @param $timestamp deleteion time + * @param string $location location of file + * @param int $timestamp deleteion time * */ private static function restoreEncryptionKeys($view, $file, $filename, $uniqueFilename, $location, $timestamp) { @@ -441,7 +441,7 @@ class Trashbin { list($owner, $ownerPath) = self::getUidAndFilename($target); - $util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), $user); + $util = new \OCA\Encryption\Util(new \OC\Files\View('/'), $user); if ($util->isSystemWideMountPoint($ownerPath)) { $baseDir = '/files_encryption/'; @@ -498,7 +498,7 @@ class Trashbin { $rootView->rename($ownerShareKey, $baseDir . '/share-keys/' . $ownerPath . '.' . $user . '.shareKey'); // try to re-share if file is shared - $filesystemView = new \OC_FilesystemView('/'); + $filesystemView = new \OC\Files\View('/'); $session = new \OCA\Encryption\Session($filesystemView); $util = new \OCA\Encryption\Util($filesystemView, $user); @@ -523,7 +523,7 @@ class Trashbin { } /** - * @brief delete all files from the trash + * delete all files from the trash */ public static function deleteAll() { $user = \OCP\User::getUser(); @@ -537,12 +537,12 @@ class Trashbin { /** - * @brief delete file from trash bin permanently + * delete file from trash bin permanently * - * @param $filename path to the file - * @param $timestamp of deletion time + * @param string $filename path to the file + * @param int $timestamp of deletion time * - * @return size of deleted files + * @return int size of deleted files */ public static function delete($filename, $timestamp = null) { $user = \OCP\User::getUser(); @@ -634,9 +634,9 @@ class Trashbin { /** * check to see whether a file exists in trashbin * - * @param $filename path to the file - * @param $timestamp of deletion time - * @return true if file exists, otherwise false + * @param string $filename path to the file + * @param int $timestamp of deletion time + * @return bool true if file exists, otherwise false */ public static function file_exists($filename, $timestamp = null) { $user = \OCP\User::getUser(); @@ -653,10 +653,10 @@ class Trashbin { } /** - * @brief deletes used space for trash bin in db if user was deleted + * deletes used space for trash bin in db if user was deleted * * @param type $uid id of deleted user - * @return result of db delete operation + * @return bool result of db delete operation */ public static function deleteUser($uid) { $query = \OC_DB::prepare('DELETE FROM `*PREFIX*files_trash` WHERE `user`=?'); @@ -672,7 +672,7 @@ class Trashbin { * calculate remaining free space for trash bin * * @param integer $trashbinSize current size of the trash bin - * @return available free space for trash bin + * @return int available free space for trash bin */ private static function calculateFreeSpace($trashbinSize) { $softQuota = true; @@ -707,7 +707,7 @@ class Trashbin { } /** - * @brief resize trash bin if necessary after a new file was added to ownCloud + * resize trash bin if necessary after a new file was added to ownCloud * @param string $user user id */ public static function resizeTrash($user) { @@ -808,8 +808,8 @@ class Trashbin { /** * find all versions which belong to the file we want to restore * - * @param $filename name of the file which should be restored - * @param $timestamp timestamp when the file was deleted + * @param string $filename name of the file which should be restored + * @param int $timestamp timestamp when the file was deleted */ private static function getVersionsFromTrash($filename, $timestamp) { $view = new \OC\Files\View('/' . \OCP\User::getUser() . '/files_trashbin/versions'); @@ -841,8 +841,8 @@ class Trashbin { /** * find unique extension for restored file if a file with the same name already exists * - * @param $location where the file should be restored - * @param $filename name of the file + * @param string $location where the file should be restored + * @param string $filename name of the file * @param \OC\Files\View $view filesystem view relative to users root directory * @return string with unique extension */ @@ -871,7 +871,7 @@ class Trashbin { } /** - * @brief get the size from a given root folder + * get the size from a given root folder * @param \OC\Files\View $view file view on the root folder * @return integer size of the folder */ @@ -903,7 +903,7 @@ class Trashbin { /** * get current size of trash bin from a given user * - * @param $user user who owns the trash bin + * @param string $user user who owns the trash bin * @return mixed trash bin size or false if no trash bin size is stored */ private static function getTrashbinSize($user) { @@ -925,7 +925,7 @@ class Trashbin { } /** - * @brief check if trash bin is empty for a given user + * check if trash bin is empty for a given user * @param string $user */ public static function isEmpty($user) { diff --git a/apps/files_trashbin/list.php b/apps/files_trashbin/list.php new file mode 100644 index 0000000000000000000000000000000000000000..b4047b82ef9b6681c6ef59610dabac60ee4925ae --- /dev/null +++ b/apps/files_trashbin/list.php @@ -0,0 +1,11 @@ +printPage(); diff --git a/apps/files_trashbin/templates/index.php b/apps/files_trashbin/templates/index.php index 323e7495535ad08ba10b65aa95a43bb3e1e1a1e4..fc18e88c41e02d2c28746ec1b6cb3ed592e632e6 100644 --- a/apps/files_trashbin/templates/index.php +++ b/apps/files_trashbin/templates/index.php @@ -1,3 +1,4 @@ +
@@ -5,29 +6,27 @@ - - - + - - - - @@ -270,22 +287,6 @@ if (!$_['internetconnectionworking']) { - - - -
+ - t( 'Deleted' )); ?> +
> +
id="publicLinkSettings"> + /> +
/>
- t('Allow users to enable others to upload into their publicly shared folders')); ?> + + /> +
+
> + t( 'Expire after ' )); ?> + ' /> + t( 'days' )); ?> + /> +
+
+ +
+ t('Allow users to share items to the public with links')); ?> + + +
> - /> -
- t( 'Expire after ' )); ?> - ' /> - t( 'days' )); ?> - /> -
- t('Expire shares by default after N days')); ?> -
diff --git a/settings/templates/personal.php b/settings/templates/personal.php index cc1fce88c9f25ba67d0ac2902f7905aa03fde90e..1d1500743ad7206971d5ecafea307a500218ed84 100644 --- a/settings/templates/personal.php +++ b/settings/templates/personal.php @@ -133,21 +133,20 @@ if($_['passwordChangeSupported']) { -
-

t('WebDAV'));?>

-
- t('Use this address to access your Files via WebDAV', array(link_to_docs('user-webdav'))));?> -
- -
+
+

t( 'Encryption' ) ); ?>

+ + + +
t( "The encryption app is no longer enabled, please decrypt all your files" )); ?>


+
+ + + + + +
> + + t( "Your encryption keys are moved to a backup location. If something went wrong you can restore the keys. Only delete them permanently if you are sure that all files are decrypted correctly." )); ?> +

+ + + + +

+
+ +
+ +
- +

t('Version'));?>

diff --git a/tests/karma.config.js b/tests/karma.config.js index 338e3f868e98b744de299b94ddabd1731caa694b..08b49d854e0bb37b77f25b5bdeaf63cd963f9101 100644 --- a/tests/karma.config.js +++ b/tests/karma.config.js @@ -43,7 +43,7 @@ module.exports = function(config) { return apps; */ // other apps tests don't run yet... needs further research / clean up - return ['files']; + return ['files', 'files_trashbin']; } // respect NOCOVERAGE env variable diff --git a/tests/lib/app.php b/tests/lib/app.php index 49f40f089bb8e1b5c65d53451b5cbdc0d16aa49f..683820cabb6fdd76c1e374d87d06ebff8a0919ba 100644 --- a/tests/lib/app.php +++ b/tests/lib/app.php @@ -1,6 +1,6 @@ + * Copyright (c) 2012 Bernhard Posselt * This file is licensed under the Affero General Public License version 3 or * later. * See the COPYING-README file. diff --git a/tests/lib/appframework/AppTest.php b/tests/lib/appframework/AppTest.php index 3628e4ceab2023303fc72196539fb87baea74d64..92fa483834114d6d873c18cdfab8470ad2535c6f 100644 --- a/tests/lib/appframework/AppTest.php +++ b/tests/lib/appframework/AppTest.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/tests/lib/appframework/controller/ApiControllerTest.php b/tests/lib/appframework/controller/ApiControllerTest.php new file mode 100644 index 0000000000000000000000000000000000000000..b772f540ce85c6f74a6b5c52a96ae2c83f28441a --- /dev/null +++ b/tests/lib/appframework/controller/ApiControllerTest.php @@ -0,0 +1,55 @@ +. + * + */ + + +namespace OCP\AppFramework; + +use OC\AppFramework\Http\Request; +use OCP\AppFramework\Http\TemplateResponse; + + +class ChildApiController extends ApiController {}; + + +class ApiControllerTest extends \PHPUnit_Framework_TestCase { + + + public function testCors() { + $request = new Request( + array('server' => array('HTTP_ORIGIN' => 'test')) + ); + $this->controller = new ChildApiController('app', $request, 'verbs', + 'headers', 100); + + $response = $this->controller->preflightedCors(); + + $headers = $response->getHeaders(); + + $this->assertEquals('test', $headers['Access-Control-Allow-Origin']); + $this->assertEquals('verbs', $headers['Access-Control-Allow-Methods']); + $this->assertEquals('headers', $headers['Access-Control-Allow-Headers']); + $this->assertEquals('false', $headers['Access-Control-Allow-Credentials']); + $this->assertEquals(100, $headers['Access-Control-Max-Age']); + } + +} diff --git a/tests/lib/appframework/controller/ControllerTest.php b/tests/lib/appframework/controller/ControllerTest.php index f17d5f24aa523c0e4ee0a5309d9541f66e0d562d..3c1716a91d8ea6264e20dd28bdd75caf3128fd74 100644 --- a/tests/lib/appframework/controller/ControllerTest.php +++ b/tests/lib/appframework/controller/ControllerTest.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -22,14 +22,35 @@ */ -namespace Test\AppFramework\Controller; +namespace OCP\AppFramework; use OC\AppFramework\Http\Request; -use OCP\AppFramework\Controller; use OCP\AppFramework\Http\TemplateResponse; +use OCP\AppFramework\Http\JSONResponse; +use OCP\AppFramework\Http\IResponseSerializer; -class ChildController extends Controller {}; +class ToUpperCaseSerializer implements IResponseSerializer { + public function serialize($response) { + return array(strtoupper($response)); + } +} + +class ChildController extends Controller { + public function custom($in) { + $this->registerResponder('json', function ($response) { + return new JSONResponse(array(strlen($response))); + }); + + return $in; + } + + public function serializer($in) { + $this->registerSerializer(new ToUpperCaseSerializer()); + + return $in; + } +}; class ControllerTest extends \PHPUnit_Framework_TestCase { @@ -129,4 +150,36 @@ class ControllerTest extends \PHPUnit_Framework_TestCase { $this->assertEquals('daheim', $this->controller->env('PATH')); } + + /** + * @expectedException \DomainException + */ + public function testFormatResonseInvalidFormat() { + $this->controller->buildResponse(null, 'test'); + } + + + public function testFormat() { + $response = $this->controller->buildResponse(array('hi'), 'json'); + + $this->assertEquals(array('hi'), $response->getData()); + } + + + public function testCustomFormatter() { + $response = $this->controller->custom('hi'); + $response = $this->controller->buildResponse($response, 'json'); + + $this->assertEquals(array(2), $response->getData()); + } + + + public function testCustomSerializer() { + $response = $this->controller->serializer('hi'); + $response = $this->controller->buildResponse($response, 'json'); + + $this->assertEquals(array('HI'), $response->getData()); + } + + } diff --git a/tests/lib/appframework/db/EntityTest.php b/tests/lib/appframework/db/EntityTest.php new file mode 100644 index 0000000000000000000000000000000000000000..9de44b9b3ba83c334fdd015124e18e0737115c4f --- /dev/null +++ b/tests/lib/appframework/db/EntityTest.php @@ -0,0 +1,223 @@ +. +* +*/ + +namespace OCP\AppFramework\Db; + + +/** + * @method integer getId() + * @method void setId(integer $id) + * @method integer getTestId() + * @method void setTestId(integer $id) + * @method string getName() + * @method void setName(string $name) + * @method string getEmail() + * @method void setEmail(string $email) + * @method string getPreName() + * @method void setPreName(string $preName) + */ +class TestEntity extends Entity { + public $name; + public $email; + public $testId; + public $preName; + + public function __construct($name=null){ + $this->addType('testId', 'integer'); + $this->name = $name; + } +}; + + +class EntityTest extends \PHPUnit_Framework_TestCase { + + private $entity; + + protected function setUp(){ + $this->entity = new TestEntity(); + } + + + public function testResetUpdatedFields(){ + $entity = new TestEntity(); + $entity->setId(3); + $entity->resetUpdatedFields(); + + $this->assertEquals(array(), $entity->getUpdatedFields()); + } + + + public function testFromRow(){ + $row = array( + 'pre_name' => 'john', + 'email' => 'john@something.com' + ); + $this->entity = TestEntity::fromRow($row); + + $this->assertEquals($row['pre_name'], $this->entity->getPreName()); + $this->assertEquals($row['email'], $this->entity->getEmail()); + } + + + public function testGetSetId(){ + $id = 3; + $this->entity->setId(3); + + $this->assertEquals($id, $this->entity->getId()); + } + + + public function testColumnToPropertyNoReplacement(){ + $column = 'my'; + $this->assertEquals('my', + $this->entity->columnToProperty($column)); + } + + + public function testColumnToProperty(){ + $column = 'my_attribute'; + $this->assertEquals('myAttribute', + $this->entity->columnToProperty($column)); + } + + + public function testPropertyToColumnNoReplacement(){ + $property = 'my'; + $this->assertEquals('my', + $this->entity->propertyToColumn($property)); + } + + + public function testSetterMarksFieldUpdated(){ + $this->entity->setId(3); + + $this->assertContains('id', $this->entity->getUpdatedFields()); + } + + + public function testCallShouldOnlyWorkForGetterSetter(){ + $this->setExpectedException('\BadFunctionCallException'); + + $this->entity->something(); + } + + + public function testGetterShouldFailIfAttributeNotDefined(){ + $this->setExpectedException('\BadFunctionCallException'); + + $this->entity->getTest(); + } + + + public function testSetterShouldFailIfAttributeNotDefined(){ + $this->setExpectedException('\BadFunctionCallException'); + + $this->entity->setTest(); + } + + + public function testFromRowShouldNotAssignEmptyArray(){ + $row = array(); + $entity2 = new TestEntity(); + + $this->entity = TestEntity::fromRow($row); + $this->assertEquals($entity2, $this->entity); + } + + + public function testIdGetsConvertedToInt(){ + $row = array('id' => '4'); + + $this->entity = TestEntity::fromRow($row); + $this->assertSame(4, $this->entity->getId()); + } + + + public function testSetType(){ + $row = array('testId' => '4'); + + $this->entity = TestEntity::fromRow($row); + $this->assertSame(4, $this->entity->getTestId()); + } + + + public function testFromParams(){ + $params = array( + 'testId' => 4, + 'email' => 'john@doe' + ); + + $entity = TestEntity::fromParams($params); + + $this->assertEquals($params['testId'], $entity->getTestId()); + $this->assertEquals($params['email'], $entity->getEmail()); + $this->assertTrue($entity instanceof TestEntity); + } + + public function testSlugify(){ + $entity = new TestEntity(); + $entity->setName('Slugify this!'); + $this->assertEquals('slugify-this', $entity->slugify('name')); + $entity->setName('°!"§$%&/()=?`´ß\}][{³²#\'+~*-_.:,;<>|äöüÄÖÜSlugify this!'); + $this->assertEquals('slugify-this', $entity->slugify('name')); + } + + + public function testSetterCasts() { + $entity = new TestEntity(); + $entity->setId('3'); + $this->assertSame(3, $entity->getId()); + } + + + public function testSetterDoesNotCastOnNull() { + $entity = new TestEntity(); + $entity->setId(null); + $this->assertSame(null, $entity->getId()); + } + + + public function testGetFieldTypes() { + $entity = new TestEntity(); + $this->assertEquals(array( + 'id' => 'integer', + 'testId' => 'integer' + ), $entity->getFieldTypes()); + } + + + public function testGetItInt() { + $entity = new TestEntity(); + $entity->setId(3); + $this->assertEquals('integer', gettype($entity->getId())); + } + + + public function testFieldsNotMarkedUpdatedIfNothingChanges() { + $entity = new TestEntity('hey'); + $entity->setName('hey'); + $this->assertEquals(0, count($entity->getUpdatedFields())); + } + + +} \ No newline at end of file diff --git a/tests/lib/appframework/db/MapperTest.php b/tests/lib/appframework/db/MapperTest.php new file mode 100644 index 0000000000000000000000000000000000000000..4ddc4ef04224d411ac57ecf6a602438bc3335202 --- /dev/null +++ b/tests/lib/appframework/db/MapperTest.php @@ -0,0 +1,279 @@ +. + * + */ + + +namespace OCP\AppFramework\Db; + +use \OCP\IDb; + + +require_once __DIR__ . '/MapperTestUtility.php'; + +/** + * @method integer getId() + * @method void setId(integer $id) + * @method string getEmail() + * @method void setEmail(string $email) + * @method string getPreName() + * @method void setPreName(string $preName) + */ +class Example extends Entity { + public $preName; + public $email; +}; + + +class ExampleMapper extends Mapper { + public function __construct(IDb $db){ parent::__construct($db, 'table'); } + public function find($table, $id){ return $this->findOneQuery($table, $id); } + public function findOneEntity($table, $id){ return $this->findEntity($table, $id); } + public function findAllEntities($table){ return $this->findEntities($table); } + public function mapRow($row){ return $this->mapRowToEntity($row); } +} + + +class MapperTest extends MapperTestUtility { + + private $mapper; + + public function setUp(){ + parent::setUp(); + $this->mapper = new ExampleMapper($this->db); + } + + + public function testMapperShouldSetTableName(){ + $this->assertEquals('*PREFIX*table', $this->mapper->getTableName()); + } + + + public function testFindQuery(){ + $sql = 'hi'; + $params = array('jo'); + $rows = array( + array('hi') + ); + $this->setMapperResult($sql, $params, $rows); + $this->mapper->find($sql, $params); + } + + public function testFindEntity(){ + $sql = 'hi'; + $params = array('jo'); + $rows = array( + array('pre_name' => 'hi') + ); + $this->setMapperResult($sql, $params, $rows); + $this->mapper->findOneEntity($sql, $params); + } + + public function testFindNotFound(){ + $sql = 'hi'; + $params = array('jo'); + $rows = array(); + $this->setMapperResult($sql, $params, $rows); + $this->setExpectedException( + '\OCP\AppFramework\Db\DoesNotExistException'); + $this->mapper->find($sql, $params); + } + + public function testFindEntityNotFound(){ + $sql = 'hi'; + $params = array('jo'); + $rows = array(); + $this->setMapperResult($sql, $params, $rows); + $this->setExpectedException( + '\OCP\AppFramework\Db\DoesNotExistException'); + $this->mapper->findOneEntity($sql, $params); + } + + public function testFindMultiple(){ + $sql = 'hi'; + $params = array('jo'); + $rows = array( + array('jo'), array('ho') + ); + $this->setMapperResult($sql, $params, $rows); + $this->setExpectedException( + '\OCP\AppFramework\Db\MultipleObjectsReturnedException'); + $this->mapper->find($sql, $params); + } + + public function testFindEntityMultiple(){ + $sql = 'hi'; + $params = array('jo'); + $rows = array( + array('jo'), array('ho') + ); + $this->setMapperResult($sql, $params, $rows); + $this->setExpectedException( + '\OCP\AppFramework\Db\MultipleObjectsReturnedException'); + $this->mapper->findOneEntity($sql, $params); + } + + + public function testDelete(){ + $sql = 'DELETE FROM `*PREFIX*table` WHERE `id` = ?'; + $params = array(2); + + $this->setMapperResult($sql, $params); + $entity = new Example(); + $entity->setId($params[0]); + + $this->mapper->delete($entity); + } + + + public function testCreate(){ + $this->db->expects($this->once()) + ->method('getInsertId') + ->with($this->equalTo('*PREFIX*table')) + ->will($this->returnValue(3)); + $this->mapper = new ExampleMapper($this->db); + + $sql = 'INSERT INTO `*PREFIX*table`(`pre_name`,`email`) ' . + 'VALUES(?,?)'; + $params = array('john', 'my@email'); + $entity = new Example(); + $entity->setPreName($params[0]); + $entity->setEmail($params[1]); + + $this->setMapperResult($sql, $params); + + $this->mapper->insert($entity); + } + + + public function testCreateShouldReturnItemWithCorrectInsertId(){ + $this->db->expects($this->once()) + ->method('getInsertId') + ->with($this->equalTo('*PREFIX*table')) + ->will($this->returnValue(3)); + $this->mapper = new ExampleMapper($this->db); + + $sql = 'INSERT INTO `*PREFIX*table`(`pre_name`,`email`) ' . + 'VALUES(?,?)'; + $params = array('john', 'my@email'); + $entity = new Example(); + $entity->setPreName($params[0]); + $entity->setEmail($params[1]); + + $this->setMapperResult($sql, $params); + + $result = $this->mapper->insert($entity); + + $this->assertEquals(3, $result->getId()); + } + + + public function testUpdate(){ + $sql = 'UPDATE `*PREFIX*table` ' . + 'SET ' . + '`pre_name` = ?,'. + '`email` = ? ' . + 'WHERE `id` = ?'; + + $params = array('john', 'my@email', 1); + $entity = new Example(); + $entity->setPreName($params[0]); + $entity->setEmail($params[1]); + $entity->setId($params[2]); + + $this->setMapperResult($sql, $params); + + $this->mapper->update($entity); + } + + + public function testUpdateNoId(){ + $params = array('john', 'my@email'); + $entity = new Example(); + $entity->setPreName($params[0]); + $entity->setEmail($params[1]); + + $this->setExpectedException('InvalidArgumentException'); + + $this->mapper->update($entity); + } + + + public function testUpdateNothingChangedNoQuery(){ + $params = array('john', 'my@email'); + $entity = new Example(); + $entity->setId(3); + $entity->setEmail($params[1]); + $entity->resetUpdatedFields(); + + $this->db->expects($this->never()) + ->method('prepareQuery'); + + $this->mapper->update($entity); + } + + + public function testMapRowToEntity(){ + $entity1 = $this->mapper->mapRow(array('pre_name' => 'test1', 'email' => 'test2')); + $entity2 = new Example(); + $entity2->setPreName('test1'); + $entity2->setEmail('test2'); + $entity2->resetUpdatedFields(); + $this->assertEquals($entity2, $entity1); + } + + public function testFindEntities(){ + $sql = 'hi'; + $rows = array( + array('pre_name' => 'hi') + ); + $entity = new Example(); + $entity->setPreName('hi'); + $entity->resetUpdatedFields(); + $this->setMapperResult($sql, array(), $rows); + $result = $this->mapper->findAllEntities($sql); + $this->assertEquals(array($entity), $result); + } + + public function testFindEntitiesNotFound(){ + $sql = 'hi'; + $rows = array(); + $this->setMapperResult($sql, array(), $rows); + $result = $this->mapper->findAllEntities($sql); + $this->assertEquals(array(), $result); + } + + public function testFindEntitiesMultiple(){ + $sql = 'hi'; + $rows = array( + array('pre_name' => 'jo'), array('email' => 'ho') + ); + $entity1 = new Example(); + $entity1->setPreName('jo'); + $entity1->resetUpdatedFields(); + $entity2 = new Example(); + $entity2->setEmail('ho'); + $entity2->resetUpdatedFields(); + $this->setMapperResult($sql, array(), $rows); + $result = $this->mapper->findAllEntities($sql); + $this->assertEquals(array($entity1, $entity2), $result); + } +} \ No newline at end of file diff --git a/tests/lib/appframework/db/MapperTestUtility.php b/tests/lib/appframework/db/MapperTestUtility.php new file mode 100644 index 0000000000000000000000000000000000000000..fc0e5c2c445e6213aa758d69fc2a6cd064120cee --- /dev/null +++ b/tests/lib/appframework/db/MapperTestUtility.php @@ -0,0 +1,179 @@ +. + * + */ + + +namespace OCP\AppFramework\Db; + + +/** + * Simple utility class for testing mappers + */ +abstract class MapperTestUtility extends \PHPUnit_Framework_TestCase { + + + protected $db; + private $query; + private $pdoResult; + private $queryAt; + private $prepareAt; + private $fetchAt; + private $iterators; + + + /** + * Run this function before the actual test to either set or initialize the + * db. After this the db can be accessed by using $this->db + */ + protected function setUp(){ + $this->db = $this->getMockBuilder( + '\OCP\IDb') + ->disableOriginalConstructor() + ->getMock(); + + $this->query = $this->getMock('Query', array('execute', 'bindValue')); + $this->pdoResult = $this->getMock('Result', array('fetch')); + $this->queryAt = 0; + $this->prepareAt = 0; + $this->iterators = array(); + $this->fetchAt = 0; + } + + + /** + * Create mocks and set expected results for database queries + * @param string $sql the sql query that you expect to receive + * @param array $arguments the expected arguments for the prepare query + * method + * @param array $returnRows the rows that should be returned for the result + * of the database query. If not provided, it wont be assumed that fetch + * will be called on the result + */ + protected function setMapperResult($sql, $arguments=array(), $returnRows=array(), + $limit=null, $offset=null){ + + $this->iterators[] = new ArgumentIterator($returnRows); + + $iterators = $this->iterators; + $fetchAt = $this->fetchAt; + + $this->pdoResult->expects($this->any()) + ->method('fetch') + ->will($this->returnCallback( + function() use ($iterators, $fetchAt){ + $iterator = $iterators[$fetchAt]; + $result = $iterator->next(); + + if($result === false) { + $fetchAt++; + } + + return $result; + } + )); + + $index = 1; + foreach($arguments as $argument) { + switch (gettype($argument)) { + case 'integer': + $pdoConstant = \PDO::PARAM_INT; + break; + + case 'NULL': + $pdoConstant = \PDO::PARAM_NULL; + break; + + case 'boolean': + $pdoConstant = \PDO::PARAM_BOOL; + break; + + default: + $pdoConstant = \PDO::PARAM_STR; + break; + } + $this->query->expects($this->at($this->queryAt)) + ->method('bindValue') + ->with($this->equalTo($index), + $this->equalTo($argument), + $this->equalTo($pdoConstant)); + $index++; + $this->queryAt++; + } + + $this->query->expects($this->at($this->queryAt)) + ->method('execute') + ->with() + ->will($this->returnValue($this->pdoResult)); + $this->queryAt++; + + if($limit === null && $offset === null) { + $this->db->expects($this->at($this->prepareAt)) + ->method('prepareQuery') + ->with($this->equalTo($sql)) + ->will(($this->returnValue($this->query))); + } elseif($limit !== null && $offset === null) { + $this->db->expects($this->at($this->prepareAt)) + ->method('prepareQuery') + ->with($this->equalTo($sql), $this->equalTo($limit)) + ->will(($this->returnValue($this->query))); + } elseif($limit === null && $offset !== null) { + $this->db->expects($this->at($this->prepareAt)) + ->method('prepareQuery') + ->with($this->equalTo($sql), + $this->equalTo(null), + $this->equalTo($offset)) + ->will(($this->returnValue($this->query))); + } else { + $this->db->expects($this->at($this->prepareAt)) + ->method('prepareQuery') + ->with($this->equalTo($sql), + $this->equalTo($limit), + $this->equalTo($offset)) + ->will(($this->returnValue($this->query))); + } + $this->prepareAt++; + $this->fetchAt++; + + } + + +} + + +class ArgumentIterator { + + private $arguments; + + public function __construct($arguments){ + $this->arguments = $arguments; + } + + public function next(){ + $result = array_shift($this->arguments); + if($result === null){ + return false; + } else { + return $result; + } + } +} + diff --git a/tests/lib/appframework/dependencyinjection/DIContainerTest.php b/tests/lib/appframework/dependencyinjection/DIContainerTest.php index d1bc900fb28bfa82a55cc97d810f8a0f20c1806d..acc5c2e66d82900d6b61d62b3668f13d50534d92 100644 --- a/tests/lib/appframework/dependencyinjection/DIContainerTest.php +++ b/tests/lib/appframework/dependencyinjection/DIContainerTest.php @@ -5,8 +5,8 @@ * * @author Bernhard Posselt * @author Morris Jobke - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com - * @copyright 2013 Morris Jobke morris.jobke@gmail.com + * @copyright 2012 Bernhard Posselt + * @copyright 2013 Morris Jobke * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/tests/lib/appframework/http/DispatcherTest.php b/tests/lib/appframework/http/DispatcherTest.php index 9841dcaa1f761300154e1653e76d013eebb1dcf6..8117eec2075920a9069ef112a788d81047d65f7b 100644 --- a/tests/lib/appframework/http/DispatcherTest.php +++ b/tests/lib/appframework/http/DispatcherTest.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -25,8 +25,28 @@ namespace OC\AppFramework\Http; use OC\AppFramework\Middleware\MiddlewareDispatcher; +use OC\AppFramework\Utility\ControllerMethodReflector; use OCP\AppFramework\Http; -//require_once(__DIR__ . "/../classloader.php"); +use OCP\AppFramework\Http\JSONResponse; +use OCP\AppFramework\Controller; + + +class TestController extends Controller { + public function __construct($appName, $request) { + parent::__construct($appName, $request); + } + + /** + * @param int $int + * @param bool $bool + */ + public function exec($int, $bool, $test=4, $test2=1) { + $this->registerResponder('text', function($in) { + return new JSONResponse(array('text' => $in)); + }); + return array($int, $bool, $test, $test2); + } +} class DispatcherTest extends \PHPUnit_Framework_TestCase { @@ -39,6 +59,7 @@ class DispatcherTest extends \PHPUnit_Framework_TestCase { private $lastModified; private $etag; private $http; + private $reflector; protected function setUp() { $this->controllerMethod = 'test'; @@ -64,8 +85,17 @@ class DispatcherTest extends \PHPUnit_Framework_TestCase { '\OCP\AppFramework\Controller', array($this->controllerMethod), array($app, $request)); + $this->request = $this->getMockBuilder( + '\OC\AppFramework\Http\Request') + ->disableOriginalConstructor() + ->getMock(); + + $this->reflector = new ControllerMethodReflector(); + $this->dispatcher = new Dispatcher( - $this->http, $this->middlewareDispatcher); + $this->http, $this->middlewareDispatcher, $this->reflector, + $this->request + ); $this->response = $this->getMockBuilder( '\OCP\AppFramework\Http\Response') @@ -81,7 +111,7 @@ class DispatcherTest extends \PHPUnit_Framework_TestCase { * @param string $out * @param string $httpHeaders */ - private function setMiddlewareExpections($out=null, + private function setMiddlewareExpectations($out=null, $httpHeaders=null, $responseHeaders=array(), $ex=false, $catchEx=true) { @@ -159,14 +189,12 @@ class DispatcherTest extends \PHPUnit_Framework_TestCase { ->with($this->equalTo($this->controller), $this->equalTo($this->controllerMethod), $this->equalTo($out)) - ->will($this->returnValue($out)); - - + ->will($this->returnValue($out)); } public function testDispatcherReturnsArrayWith2Entries() { - $this->setMiddlewareExpections(); + $this->setMiddlewareExpectations(); $response = $this->dispatcher->dispatch($this->controller, $this->controllerMethod); @@ -180,7 +208,7 @@ class DispatcherTest extends \PHPUnit_Framework_TestCase { $out = 'yo'; $httpHeaders = 'Http'; $responseHeaders = array('hell' => 'yeah'); - $this->setMiddlewareExpections($out, $httpHeaders, $responseHeaders); + $this->setMiddlewareExpectations($out, $httpHeaders, $responseHeaders); $response = $this->dispatcher->dispatch($this->controller, $this->controllerMethod); @@ -195,7 +223,7 @@ class DispatcherTest extends \PHPUnit_Framework_TestCase { $out = 'yo'; $httpHeaders = 'Http'; $responseHeaders = array('hell' => 'yeah'); - $this->setMiddlewareExpections($out, $httpHeaders, $responseHeaders, true); + $this->setMiddlewareExpectations($out, $httpHeaders, $responseHeaders, true); $response = $this->dispatcher->dispatch($this->controller, $this->controllerMethod); @@ -210,7 +238,7 @@ class DispatcherTest extends \PHPUnit_Framework_TestCase { $out = 'yo'; $httpHeaders = 'Http'; $responseHeaders = array('hell' => 'yeah'); - $this->setMiddlewareExpections($out, $httpHeaders, $responseHeaders, true, false); + $this->setMiddlewareExpectations($out, $httpHeaders, $responseHeaders, true, false); $this->setExpectedException('\Exception'); $response = $this->dispatcher->dispatch($this->controller, @@ -218,4 +246,148 @@ class DispatcherTest extends \PHPUnit_Framework_TestCase { } + + private function dispatcherPassthrough() { + $this->middlewareDispatcher->expects($this->once()) + ->method('beforeController'); + $this->middlewareDispatcher->expects($this->once()) + ->method('afterController') + ->will($this->returnCallback(function($a, $b, $in) { + return $in; + })); + $this->middlewareDispatcher->expects($this->once()) + ->method('beforeOutput') + ->will($this->returnCallback(function($a, $b, $in) { + return $in; + })); + } + + + public function testControllerParametersInjected() { + $this->request = new Request(array( + 'post' => array( + 'int' => '3', + 'bool' => 'false' + ), + 'method' => 'POST' + )); + $this->dispatcher = new Dispatcher( + $this->http, $this->middlewareDispatcher, $this->reflector, + $this->request + ); + $controller = new TestController('app', $this->request); + + // reflector is supposed to be called once + $this->dispatcherPassthrough(); + $response = $this->dispatcher->dispatch($controller, 'exec'); + + $this->assertEquals('[3,true,4,1]', $response[2]); + } + + + public function testControllerParametersInjectedDefaultOverwritten() { + $this->request = new Request(array( + 'post' => array( + 'int' => '3', + 'bool' => 'false', + 'test2' => 7 + ), + 'method' => 'POST' + )); + $this->dispatcher = new Dispatcher( + $this->http, $this->middlewareDispatcher, $this->reflector, + $this->request + ); + $controller = new TestController('app', $this->request); + + // reflector is supposed to be called once + $this->dispatcherPassthrough(); + $response = $this->dispatcher->dispatch($controller, 'exec'); + + $this->assertEquals('[3,true,4,7]', $response[2]); + } + + + + public function testResponseTransformedByUrlFormat() { + $this->request = new Request(array( + 'post' => array( + 'int' => '3', + 'bool' => 'false' + ), + 'urlParams' => array( + 'format' => 'text' + ), + 'method' => 'GET' + )); + $this->dispatcher = new Dispatcher( + $this->http, $this->middlewareDispatcher, $this->reflector, + $this->request + ); + $controller = new TestController('app', $this->request); + + // reflector is supposed to be called once + $this->dispatcherPassthrough(); + $response = $this->dispatcher->dispatch($controller, 'exec'); + + $this->assertEquals('{"text":[3,false,4,1]}', $response[2]); + } + + + public function testResponseTransformedByAcceptHeader() { + $this->request = new Request(array( + 'post' => array( + 'int' => '3', + 'bool' => 'false' + ), + 'server' => array( + 'HTTP_ACCEPT' => 'application/text, test', + 'HTTP_CONTENT_TYPE' => 'application/x-www-form-urlencoded' + ), + 'method' => 'PUT' + )); + $this->dispatcher = new Dispatcher( + $this->http, $this->middlewareDispatcher, $this->reflector, + $this->request + ); + $controller = new TestController('app', $this->request); + + // reflector is supposed to be called once + $this->dispatcherPassthrough(); + $response = $this->dispatcher->dispatch($controller, 'exec'); + + $this->assertEquals('{"text":[3,false,4,1]}', $response[2]); + } + + + public function testResponsePrimarilyTransformedByParameterFormat() { + $this->request = new Request(array( + 'post' => array( + 'int' => '3', + 'bool' => 'false' + ), + 'get' => array( + 'format' => 'text' + ), + 'server' => array( + 'HTTP_ACCEPT' => 'application/json, test' + ), + 'method' => 'POST' + )); + $this->dispatcher = new Dispatcher( + $this->http, $this->middlewareDispatcher, $this->reflector, + $this->request + ); + $controller = new TestController('app', $this->request); + + // reflector is supposed to be called once + $this->dispatcherPassthrough(); + $response = $this->dispatcher->dispatch($controller, 'exec'); + + $this->assertEquals('{"text":[3,true,4,1]}', $response[2]); + } + + + + } diff --git a/tests/lib/appframework/http/DownloadResponseTest.php b/tests/lib/appframework/http/DownloadResponseTest.php index b305c63ad4d297e010aaf2a57fc08e1935e17894..5be16ce3c497716464e1402896d2b116ca550a1d 100644 --- a/tests/lib/appframework/http/DownloadResponseTest.php +++ b/tests/lib/appframework/http/DownloadResponseTest.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/tests/lib/appframework/http/HttpTest.php b/tests/lib/appframework/http/HttpTest.php index 0bdcee24c995a196b22cab20e692a18790e23b02..c62fa43863abd526fb8f50d96d5829fe83fb4b51 100644 --- a/tests/lib/appframework/http/HttpTest.php +++ b/tests/lib/appframework/http/HttpTest.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/tests/lib/appframework/http/JSONResponseTest.php b/tests/lib/appframework/http/JSONResponseTest.php index fbaae1b922743f4a0ff94bb333bb8890ffdaa01b..c0c58ebf7612a002e02c0fcd7268bd72e8b1e376 100644 --- a/tests/lib/appframework/http/JSONResponseTest.php +++ b/tests/lib/appframework/http/JSONResponseTest.php @@ -5,8 +5,8 @@ * * @author Bernhard Posselt * @author Morris Jobke - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com - * @copyright 2013 Morris Jobke morris.jobke@gmail.com + * @copyright 2012 Bernhard Posselt + * @copyright 2013 Morris Jobke * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/tests/lib/appframework/http/RedirectResponseTest.php b/tests/lib/appframework/http/RedirectResponseTest.php index f62b420f4ee69104041802d1ec06671be035003a..dfd0d7ee7dcc9a03e0f7a27b8b196f24144613ab 100644 --- a/tests/lib/appframework/http/RedirectResponseTest.php +++ b/tests/lib/appframework/http/RedirectResponseTest.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/tests/lib/appframework/http/ResponseTest.php b/tests/lib/appframework/http/ResponseTest.php index 27350725d79a76921e65acf9a5043fce713eca6d..e83fe9e2d8487d1f9e4dee3c20b2bcfb23467a7e 100644 --- a/tests/lib/appframework/http/ResponseTest.php +++ b/tests/lib/appframework/http/ResponseTest.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -42,7 +42,7 @@ class ResponseTest extends \PHPUnit_Framework_TestCase { public function testAddHeader(){ - $this->childResponse->addHeader('hello', 'world'); + $this->childResponse->addHeader(' hello ', 'world'); $headers = $this->childResponse->getHeaders(); $this->assertEquals('world', $headers['hello']); } diff --git a/tests/lib/appframework/http/TemplateResponseTest.php b/tests/lib/appframework/http/TemplateResponseTest.php index 0b158edff6f9392460dbd14ce15c24137abba2b0..afdcf322b85a81817a0cd69973212dbbd213f4c6 100644 --- a/tests/lib/appframework/http/TemplateResponseTest.php +++ b/tests/lib/appframework/http/TemplateResponseTest.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -51,6 +51,22 @@ class TemplateResponseTest extends \PHPUnit_Framework_TestCase { } + public function testSetParamsConstructor(){ + $params = array('hi' => 'yo'); + $this->tpl = new TemplateResponse($this->api, 'home', $params); + + $this->assertEquals(array('hi' => 'yo'), $this->tpl->getParams()); + } + + + public function testSetRenderAsConstructor(){ + $renderAs = 'myrender'; + $this->tpl = new TemplateResponse($this->api, 'home', array(), $renderAs); + + $this->assertEquals($renderAs, $this->tpl->getRenderAs()); + } + + public function testSetParams(){ $params = array('hi' => 'yo'); $this->tpl->setParams($params); @@ -63,36 +79,6 @@ class TemplateResponseTest extends \PHPUnit_Framework_TestCase { $this->assertEquals('home', $this->tpl->getTemplateName()); } - -// public function testRender(){ -// $ocTpl = $this->getMock('Template', array('fetchPage')); -// $ocTpl->expects($this->once()) -// ->method('fetchPage'); -// -// $tpl = new TemplateResponse('core', 'error'); -// -// $tpl->render(); -// } -// -// -// public function testRenderAssignsParams(){ -// $params = array('john' => 'doe'); -// -// $tpl = new TemplateResponse('app', 'home'); -// $tpl->setParams($params); -// -// $tpl->render(); -// } -// -// -// public function testRenderDifferentApp(){ -// -// $tpl = new TemplateResponse('app', 'home', 'app2'); -// -// $tpl->render(); -// } - - public function testGetRenderAs(){ $render = 'myrender'; $this->tpl->renderAs($render); diff --git a/tests/lib/appframework/middleware/MiddlewareDispatcherTest.php b/tests/lib/appframework/middleware/MiddlewareDispatcherTest.php index 935f97d2a6f251630d6d813b0298bd35189b54e3..b1a58e212893d13de8934d67846ae982ddf38d56 100644 --- a/tests/lib/appframework/middleware/MiddlewareDispatcherTest.php +++ b/tests/lib/appframework/middleware/MiddlewareDispatcherTest.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/tests/lib/appframework/middleware/MiddlewareTest.php b/tests/lib/appframework/middleware/MiddlewareTest.php index 7a93c0d4ddac9b309ff43858f60743a91824b560..814efdd8118bc64aadff0933babcad847addb4b2 100644 --- a/tests/lib/appframework/middleware/MiddlewareTest.php +++ b/tests/lib/appframework/middleware/MiddlewareTest.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/tests/lib/appframework/middleware/security/CORSMiddlewareTest.php b/tests/lib/appframework/middleware/security/CORSMiddlewareTest.php new file mode 100644 index 0000000000000000000000000000000000000000..79cd3b278af54610e1c6327c31e2a93167298954 --- /dev/null +++ b/tests/lib/appframework/middleware/security/CORSMiddlewareTest.php @@ -0,0 +1,87 @@ + + * @copyright Bernhard Posselt 2014 + */ + + +namespace OC\AppFramework\Middleware\Security; + +use OC\AppFramework\Http\Request; +use OC\AppFramework\Utility\ControllerMethodReflector; + +use OCP\AppFramework\Http\Response; + + +class CORSMiddlewareTest extends \PHPUnit_Framework_TestCase { + + private $reflector; + + protected function setUp() { + $this->reflector = new ControllerMethodReflector(); + } + + /** + * @CORS + */ + public function testSetCORSAPIHeader() { + $request = new Request( + array('server' => array('HTTP_ORIGIN' => 'test')) + ); + $this->reflector->reflect($this, __FUNCTION__); + $middleware = new CORSMiddleware($request, $this->reflector); + + $response = $middleware->afterController($this, __FUNCTION__, new Response()); + $headers = $response->getHeaders(); + $this->assertEquals('test', $headers['Access-Control-Allow-Origin']); + } + + + public function testNoAnnotationNoCORSHEADER() { + $request = new Request( + array('server' => array('HTTP_ORIGIN' => 'test')) + ); + $middleware = new CORSMiddleware($request, $this->reflector); + + $response = $middleware->afterController($this, __FUNCTION__, new Response()); + $headers = $response->getHeaders(); + $this->assertFalse(array_key_exists('Access-Control-Allow-Origin', $headers)); + } + + + /** + * @CORS + */ + public function testNoOriginHeaderNoCORSHEADER() { + $request = new Request(); + $this->reflector->reflect($this, __FUNCTION__); + $middleware = new CORSMiddleware($request, $this->reflector); + + $response = $middleware->afterController($this, __FUNCTION__, new Response()); + $headers = $response->getHeaders(); + $this->assertFalse(array_key_exists('Access-Control-Allow-Origin', $headers)); + } + + + /** + * @CORS + * @expectedException \OC\AppFramework\Middleware\Security\SecurityException + */ + public function testCorsIgnoredIfWithCredentialsHeaderPresent() { + $request = new Request( + array('server' => array('HTTP_ORIGIN' => 'test')) + ); + $this->reflector->reflect($this, __FUNCTION__); + $middleware = new CORSMiddleware($request, $this->reflector); + + $response = new Response(); + $response->addHeader('AcCess-control-Allow-Credentials ', 'TRUE'); + $response = $middleware->afterController($this, __FUNCTION__, $response); + } + +} diff --git a/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php b/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php index 19e8a68c388db12249b06b6a5164986177cebf8d..6a1bbf72c1393fe0725cc043f8553a76aaf6fad8 100644 --- a/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php +++ b/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -26,6 +26,7 @@ namespace OC\AppFramework\Middleware\Security; use OC\AppFramework\Http; use OC\AppFramework\Http\Request; +use OC\AppFramework\Utility\ControllerMethodReflector; use OCP\AppFramework\Http\RedirectResponse; use OCP\AppFramework\Http\JSONResponse; @@ -37,14 +38,16 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { private $secException; private $secAjaxException; private $request; + private $reader; public function setUp() { $api = $this->getMock('OC\AppFramework\DependencyInjection\DIContainer', array(), array('test')); $this->controller = $this->getMock('OCP\AppFramework\Controller', array(), array($api, new Request())); + $this->reader = new ControllerMethodReflector(); $this->request = new Request(); - $this->middleware = new SecurityMiddleware($api, $this->request); + $this->middleware = new SecurityMiddleware($api, $this->request, $this->reader); $this->secException = new SecurityException('hey', false); $this->secAjaxException = new SecurityException('hey', true); } @@ -68,7 +71,8 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { $api->expects($this->any())->method('getServer') ->will($this->returnValue($serverMock)); - $sec = new SecurityMiddleware($api, $this->request); + $sec = new SecurityMiddleware($api, $this->request, $this->reader); + $this->reader->reflect('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', $method); $sec->beforeController('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', $method); } @@ -99,11 +103,12 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { ->will($this->returnValue(true)); } - $sec = new SecurityMiddleware($api, $this->request); + $sec = new SecurityMiddleware($api, $this->request, $this->reader); try { - $sec->beforeController('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', - $method); + $controller = '\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest'; + $this->reader->reflect($controller, $method); + $sec->beforeController($controller, $method); } catch (SecurityException $ex){ $this->assertEquals($status, $ex->getCode()); } @@ -184,7 +189,9 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { ->method('isLoggedIn') ->will($this->returnValue(true)); - $sec = new SecurityMiddleware($api, $this->request); + $sec = new SecurityMiddleware($api, $this->request, $this->reader); + $this->reader->reflect('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', + 'testNoChecks'); $sec->beforeController('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', 'testNoChecks'); } @@ -207,7 +214,7 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { ->will($this->returnValue(true)); } - $sec = new SecurityMiddleware($api, $this->request); + $sec = new SecurityMiddleware($api, $this->request, $this->reader); if($shouldFail){ $this->setExpectedException('\OC\AppFramework\Middleware\Security\SecurityException'); @@ -215,6 +222,7 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { $this->setExpectedException(null); } + $this->reader->reflect('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', $method); $sec->beforeController('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', $method); } @@ -230,7 +238,8 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { ->method('passesCSRFCheck') ->will($this->returnValue(false)); - $sec = new SecurityMiddleware($api, $request); + $sec = new SecurityMiddleware($api, $request, $this->reader); + $this->reader->reflect('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', 'testCsrfCheck'); $sec->beforeController('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', 'testCsrfCheck'); } @@ -246,7 +255,8 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { ->method('passesCSRFCheck') ->will($this->returnValue(false)); - $sec = new SecurityMiddleware($api, $request); + $sec = new SecurityMiddleware($api, $request, $this->reader); + $this->reader->reflect('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', 'testNoCsrfCheck'); $sec->beforeController('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', 'testNoCsrfCheck'); } @@ -261,7 +271,8 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { ->method('passesCSRFCheck') ->will($this->returnValue(true)); - $sec = new SecurityMiddleware($api, $request); + $sec = new SecurityMiddleware($api, $request, $this->reader); + $this->reader->reflect('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', 'testFailCsrfCheck'); $sec->beforeController('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', 'testFailCsrfCheck'); } @@ -318,7 +329,7 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { $this->request = new Request( array('server' => array('HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'))); - $this->middleware = new SecurityMiddleware($api, $this->request); + $this->middleware = new SecurityMiddleware($api, $this->request, $this->reader); $response = $this->middleware->afterException($this->controller, 'test', $this->secException); diff --git a/tests/lib/appframework/utility/ControllerMethodReflectorTest.php b/tests/lib/appframework/utility/ControllerMethodReflectorTest.php new file mode 100644 index 0000000000000000000000000000000000000000..8939a203edbc289a1d1a8fb80e9b8c5a9ce21ae9 --- /dev/null +++ b/tests/lib/appframework/utility/ControllerMethodReflectorTest.php @@ -0,0 +1,115 @@ + + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library 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 along with this library. If not, see . + * + */ + + +namespace OC\AppFramework\Utility; + + +class ControllerMethodReflectorTest extends \PHPUnit_Framework_TestCase { + + + /** + * @Annotation + */ + public function testReadAnnotation(){ + $reader = new ControllerMethodReflector(); + $reader->reflect( + '\OC\AppFramework\Utility\ControllerMethodReflectorTest', + 'testReadAnnotation' + ); + + $this->assertTrue($reader->hasAnnotation('Annotation')); + } + + + /** + * @Annotation + * @param test + */ + public function testReadAnnotationNoLowercase(){ + $reader = new ControllerMethodReflector(); + $reader->reflect( + '\OC\AppFramework\Utility\ControllerMethodReflectorTest', + 'testReadAnnotationNoLowercase' + ); + + $this->assertTrue($reader->hasAnnotation('Annotation')); + $this->assertFalse($reader->hasAnnotation('param')); + } + + + /** + * @Annotation + * @param int $test + */ + public function testReadTypeIntAnnotations(){ + $reader = new ControllerMethodReflector(); + $reader->reflect( + '\OC\AppFramework\Utility\ControllerMethodReflectorTest', + 'testReadTypeIntAnnotations' + ); + + $this->assertEquals('int', $reader->getType('test')); + } + + + /** + * @Annotation + * @param double $test something special + */ + public function testReadTypeDoubleAnnotations(){ + $reader = new ControllerMethodReflector(); + $reader->reflect( + '\OC\AppFramework\Utility\ControllerMethodReflectorTest', + 'testReadTypeDoubleAnnotations' + ); + + $this->assertEquals('double', $reader->getType('test')); + } + + + public function arguments($arg, $arg2='hi') {} + public function testReflectParameters() { + $reader = new ControllerMethodReflector(); + $reader->reflect( + '\OC\AppFramework\Utility\ControllerMethodReflectorTest', + 'arguments' + ); + + $this->assertEquals(array('arg' => null, 'arg2' => 'hi'), $reader->getParameters()); + } + + + public function arguments2($arg) {} + public function testReflectParameters2() { + $reader = new ControllerMethodReflector(); + $reader->reflect( + '\OC\AppFramework\Utility\ControllerMethodReflectorTest', + 'arguments2' + ); + + $this->assertEquals(array('arg' => null), $reader->getParameters()); + } + + +} diff --git a/tests/lib/errorHandler.php b/tests/lib/errorHandler.php index 32396eafbeacbded7808049f93ee3a2106e1e4eb..58db80b3c6efbcd85f3fc08b04e005a2c35ac8e8 100644 --- a/tests/lib/errorHandler.php +++ b/tests/lib/errorHandler.php @@ -23,7 +23,7 @@ class Test_ErrorHandler extends \PHPUnit_Framework_TestCase { /** - * @brief provide username, password combinations for testRemovePassword + * provide username, password combinations for testRemovePassword * @return array */ function passwordProvider() { @@ -53,7 +53,7 @@ class Test_ErrorHandler extends \PHPUnit_Framework_TestCase { } /** - * @brief dummy class to access protected methods of \OC\Log\ErrorHandler + * dummy class to access protected methods of \OC\Log\ErrorHandler */ class TestableErrorHandler extends \OC\Log\ErrorHandler { diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 5d87693247986b28ec9ce895c97fcbd2076327a9..8ed2ecabd981fbbff383917263d0c1196b13407a 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -343,7 +343,7 @@ class Cache extends \PHPUnit_Framework_TestCase { } /** - * @brief this test show the bug resulting if we have no normalizer installed + * this test show the bug resulting if we have no normalizer installed */ public function testWithoutNormalizer() { // folder name "Schön" with U+00F6 (normalized) @@ -386,7 +386,7 @@ class Cache extends \PHPUnit_Framework_TestCase { } /** - * @brief this test shows that there is no bug if we use the normalizer + * this test shows that there is no bug if we use the normalizer */ public function testWithNormalizer() { diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index f80dd06e1cb6a097c7c3aace88ce3e105cd0b7f4..201eb9ff6cbfcaba0ab547e653475952d441cfc8 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -585,4 +585,24 @@ class View extends \PHPUnit_Framework_TestCase { $info2 = $view->getFileInfo('/test/test'); $this->assertSame($info['etag'], $info2['etag']); } + + /** + * @dataProvider absolutePathProvider + */ + public function testGetAbsolutePath($expectedPath, $relativePath) { + $view = new \OC\Files\View('/files'); + $this->assertEquals($expectedPath, $view->getAbsolutePath($relativePath)); + } + + function absolutePathProvider() { + return array( + array('/files/', ''), + array('/files/0', '0'), + array('/files/false', 'false'), + array('/files/true', 'true'), + array('/files/', '/'), + array('/files/test', 'test'), + array('/files/test', '/test'), + ); + } } diff --git a/tests/lib/group.php b/tests/lib/group.php index 26232187c360a0cb9b47cb380862d561e61df52b..724e723b1871aa922977fcf37ee64e88ebceed32 100644 --- a/tests/lib/group.php +++ b/tests/lib/group.php @@ -4,8 +4,8 @@ * * @author Robin Appelman * @author Bernhard Posselt - * @copyright 2012 Robin Appelman icewind@owncloud.com - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Robin Appelman + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/tests/lib/group/group.php b/tests/lib/group/group.php index 990f8ecc1d5146f5a8b5624da260f0b31845cd25..4d15999a8261b4fda30e1bc0716258285d4b616f 100644 --- a/tests/lib/group/group.php +++ b/tests/lib/group/group.php @@ -17,9 +17,10 @@ class Group extends \PHPUnit_Framework_TestCase { */ protected function getUserManager() { $userManager = $this->getMock('\OC\User\Manager'); - $user1 = new User('user1', null); - $user2 = new User('user2', null); - $user3 = new User('user3', null); + $backend = $this->getMock('\OC_User_Backend'); + $user1 = new User('user1', $backend); + $user2 = new User('user2', $backend); + $user3 = new User('user3', $backend); $userManager->expects($this->any()) ->method('get') ->will($this->returnValueMap(array( @@ -79,6 +80,7 @@ class Group extends \PHPUnit_Framework_TestCase { public function testInGroupSingleBackend() { $backend = $this->getMock('OC_Group_Database'); $userManager = $this->getUserManager(); + $userBackend = $this->getMock('\OC_User_Backend'); $group = new \OC\Group\Group('group1', array($backend), $userManager); $backend->expects($this->once()) @@ -86,13 +88,14 @@ class Group extends \PHPUnit_Framework_TestCase { ->with('user1', 'group1') ->will($this->returnValue(true)); - $this->assertTrue($group->inGroup(new User('user1', null))); + $this->assertTrue($group->inGroup(new User('user1', $userBackend))); } public function testInGroupMultipleBackends() { $backend1 = $this->getMock('OC_Group_Database'); $backend2 = $this->getMock('OC_Group_Database'); $userManager = $this->getUserManager(); + $userBackend = $this->getMock('\OC_User_Backend'); $group = new \OC\Group\Group('group1', array($backend1, $backend2), $userManager); $backend1->expects($this->once()) @@ -105,12 +108,13 @@ class Group extends \PHPUnit_Framework_TestCase { ->with('user1', 'group1') ->will($this->returnValue(true)); - $this->assertTrue($group->inGroup(new User('user1', null))); + $this->assertTrue($group->inGroup(new User('user1', $userBackend))); } public function testAddUser() { $backend = $this->getMock('OC_Group_Database'); $userManager = $this->getUserManager(); + $userBackend = $this->getMock('\OC_User_Backend'); $group = new \OC\Group\Group('group1', array($backend), $userManager); $backend->expects($this->once()) @@ -125,12 +129,13 @@ class Group extends \PHPUnit_Framework_TestCase { ->method('addToGroup') ->with('user1', 'group1'); - $group->addUser(new User('user1', null)); + $group->addUser(new User('user1', $userBackend)); } public function testAddUserAlreadyInGroup() { $backend = $this->getMock('OC_Group_Database'); $userManager = $this->getUserManager(); + $userBackend = $this->getMock('\OC_User_Backend'); $group = new \OC\Group\Group('group1', array($backend), $userManager); $backend->expects($this->once()) @@ -144,12 +149,13 @@ class Group extends \PHPUnit_Framework_TestCase { $backend->expects($this->never()) ->method('addToGroup'); - $group->addUser(new User('user1', null)); + $group->addUser(new User('user1', $userBackend)); } public function testRemoveUser() { $backend = $this->getMock('OC_Group_Database'); $userManager = $this->getUserManager(); + $userBackend = $this->getMock('\OC_User_Backend'); $group = new \OC\Group\Group('group1', array($backend), $userManager); $backend->expects($this->once()) @@ -164,12 +170,13 @@ class Group extends \PHPUnit_Framework_TestCase { ->method('removeFromGroup') ->with('user1', 'group1'); - $group->removeUser(new User('user1', null)); + $group->removeUser(new User('user1', $userBackend)); } public function testRemoveUserNotInGroup() { $backend = $this->getMock('OC_Group_Database'); $userManager = $this->getUserManager(); + $userBackend = $this->getMock('\OC_User_Backend'); $group = new \OC\Group\Group('group1', array($backend), $userManager); $backend->expects($this->once()) @@ -183,13 +190,14 @@ class Group extends \PHPUnit_Framework_TestCase { $backend->expects($this->never()) ->method('removeFromGroup'); - $group->removeUser(new User('user1', null)); + $group->removeUser(new User('user1', $userBackend)); } public function testRemoveUserMultipleBackends() { $backend1 = $this->getMock('OC_Group_Database'); $backend2 = $this->getMock('OC_Group_Database'); $userManager = $this->getUserManager(); + $userBackend = $this->getMock('\OC_User_Backend'); $group = new \OC\Group\Group('group1', array($backend1, $backend2), $userManager); $backend1->expects($this->once()) @@ -216,7 +224,7 @@ class Group extends \PHPUnit_Framework_TestCase { ->method('removeFromGroup') ->with('user1', 'group1'); - $group->removeUser(new User('user1', null)); + $group->removeUser(new User('user1', $userBackend)); } public function testSearchUsers() { diff --git a/tests/lib/group/manager.php b/tests/lib/group/manager.php index 9d1f175c1090e0c9261e8193d117f34e892e8488..6799a598d422c0dfd4940f0cbde49e4b85914c40 100644 --- a/tests/lib/group/manager.php +++ b/tests/lib/group/manager.php @@ -294,10 +294,11 @@ class Manager extends \PHPUnit_Framework_TestCase { * @var \OC\User\Manager $userManager */ $userManager = $this->getMock('\OC\User\Manager'); + $userBackend = $this->getMock('\OC_User_Backend'); $manager = new \OC\Group\Manager($userManager); $manager->addBackend($backend); - $groups = $manager->getUserGroups(new User('user1', null)); + $groups = $manager->getUserGroups(new User('user1', $userBackend)); $this->assertEquals(1, count($groups)); $group1 = $groups[0]; $this->assertEquals('group1', $group1->getGID()); @@ -332,11 +333,12 @@ class Manager extends \PHPUnit_Framework_TestCase { * @var \OC\User\Manager $userManager */ $userManager = $this->getMock('\OC\User\Manager'); + $userBackend = $this->getMock('\OC_User_Backend'); $manager = new \OC\Group\Manager($userManager); $manager->addBackend($backend1); $manager->addBackend($backend2); - $groups = $manager->getUserGroups(new User('user1', null)); + $groups = $manager->getUserGroups(new User('user1', $userBackend)); $this->assertEquals(2, count($groups)); $group1 = $groups[0]; $group2 = $groups[1]; @@ -345,10 +347,12 @@ class Manager extends \PHPUnit_Framework_TestCase { } public function testDisplayNamesInGroupMultipleUserBackends() { - $user1 = new User('user1', null); - $user2 = new User('user2', null); - $user3 = new User('user3', null); - $user4 = new User('user33', null); + $userBackend = $this->getMock('\OC_User_Backend'); + + $user1 = new User('user1', $userBackend); + $user2 = new User('user2', $userBackend); + $user3 = new User('user3', $userBackend); + $user4 = new User('user33', $userBackend); /** * @var \PHPUnit_Framework_MockObject_MockObject | \OC_Group_Backend $backend1 @@ -368,6 +372,7 @@ class Manager extends \PHPUnit_Framework_TestCase { * @var \OC\User\Manager $userManager */ $userManager = $this->getMock('\OC\User\Manager'); + $userBackend = $this->getMock('\OC_User_Backend'); $userManager->expects($this->once()) ->method('search') ->with('user3') @@ -375,12 +380,12 @@ class Manager extends \PHPUnit_Framework_TestCase { $userManager->expects($this->any()) ->method('get') - ->will($this->returnCallback(function($uid) { + ->will($this->returnCallback(function($uid) use ($userBackend) { switch($uid) { - case 'user1' : return new User('user1', null); - case 'user2' : return new User('user2', null); - case 'user3' : return new User('user3', null); - case 'user33': return new User('user33', null); + case 'user1' : return new User('user1', $userBackend); + case 'user2' : return new User('user2', $userBackend); + case 'user3' : return new User('user3', $userBackend); + case 'user33': return new User('user33', $userBackend); default: return null; } @@ -393,4 +398,98 @@ class Manager extends \PHPUnit_Framework_TestCase { $this->assertEquals(1, count($users)); $this->assertTrue(isset($users['user33'])); } + + public function testGetUserGroupsWithAddUser() { + /** + * @var \PHPUnit_Framework_MockObject_MockObject | \OC_Group_Backend $backend + */ + $backend = $this->getMock('\OC_Group_Database'); + $expectedGroups = array(); + $backend->expects($this->any()) + ->method('getUserGroups') + ->with('user1') + ->will($this->returnCallback(function () use (&$expectedGroups) { + return $expectedGroups; + })); + $backend->expects($this->any()) + ->method('groupExists') + ->with('group1') + ->will($this->returnValue(true)); + $backend->expects($this->once()) + ->method('implementsActions') + ->will($this->returnValue(true)); + + /** + * @var \OC\User\Manager $userManager + */ + $userManager = $this->getMock('\OC\User\Manager'); + $manager = new \OC\Group\Manager($userManager); + $manager->addBackend($backend); + + // prime cache + $user1 = new User('user1', null); + $groups = $manager->getUserGroups($user1); + $this->assertEquals(array(), $groups); + + // add user + $group = $manager->get('group1'); + $group->addUser($user1); + $expectedGroups = array('group1'); + + // check result + $groups = $manager->getUserGroups($user1); + $this->assertEquals(1, count($groups)); + $group1 = $groups[0]; + $this->assertEquals('group1', $group1->getGID()); + } + + public function testGetUserGroupsWithRemoveUser() { + /** + * @var \PHPUnit_Framework_MockObject_MockObject | \OC_Group_Backend $backend + */ + $backend = $this->getMock('\OC_Group_Database'); + $expectedGroups = array('group1'); + $backend->expects($this->any()) + ->method('getUserGroups') + ->with('user1') + ->will($this->returnCallback(function () use (&$expectedGroups) { + return $expectedGroups; + })); + $backend->expects($this->any()) + ->method('groupExists') + ->with('group1') + ->will($this->returnValue(true)); + $backend->expects($this->once()) + ->method('implementsActions') + ->will($this->returnValue(true)); + $backend->expects($this->once()) + ->method('inGroup') + ->will($this->returnValue(true)); + $backend->expects($this->once()) + ->method('removeFromGroup') + ->will($this->returnValue(true)); + + /** + * @var \OC\User\Manager $userManager + */ + $userManager = $this->getMock('\OC\User\Manager'); + $manager = new \OC\Group\Manager($userManager); + $manager->addBackend($backend); + + // prime cache + $user1 = new User('user1', null); + $groups = $manager->getUserGroups($user1); + $this->assertEquals(1, count($groups)); + $group1 = $groups[0]; + $this->assertEquals('group1', $group1->getGID()); + + // remove user + $group = $manager->get('group1'); + $group->removeUser($user1); + $expectedGroups = array(); + + // check result + $groups = $manager->getUserGroups($user1); + $this->assertEquals(array(), $groups); + } } diff --git a/tests/lib/helper.php b/tests/lib/helper.php index 5663df7c9ae92e1f4619e03eaaef1da89ad1d982..cfd66e9970463462b7193ac370486c99e975a934 100644 --- a/tests/lib/helper.php +++ b/tests/lib/helper.php @@ -120,15 +120,15 @@ class Test_Helper extends PHPUnit_Framework_TestCase { $this->assertEquals($result, $expected); } - function testIssubdirectory() { - $result = OC_Helper::issubdirectory("./data/", "/anotherDirectory/"); + function testIsSubDirectory() { + $result = OC_Helper::isSubDirectory("./data/", "/anotherDirectory/"); $this->assertFalse($result); - $result = OC_Helper::issubdirectory("./data/", "./data/"); + $result = OC_Helper::isSubDirectory("./data/", "./data/"); $this->assertTrue($result); mkdir("data/TestSubdirectory", 0777); - $result = OC_Helper::issubdirectory("data/TestSubdirectory/", "data"); + $result = OC_Helper::isSubDirectory("data/TestSubdirectory/", "data"); rmdir("data/TestSubdirectory"); $this->assertTrue($result); } @@ -156,7 +156,7 @@ class Test_Helper extends PHPUnit_Framework_TestCase { ); $result = OC_Helper::mb_array_change_key_case($arrayStart, MB_CASE_UPPER); $expected = $arrayResult; - $this->assertEquals($result, $expected); + $this->assertEquals($result, $expected); } function testMb_substr_replace() { @@ -284,7 +284,7 @@ class Test_Helper extends PHPUnit_Framework_TestCase { /** * @small - * @brief test absolute URL construction + * test absolute URL construction * @dataProvider provideDocRootURLs */ function testMakeAbsoluteURLDocRoot($url, $expectedResult) { @@ -296,7 +296,7 @@ class Test_Helper extends PHPUnit_Framework_TestCase { /** * @small - * @brief test absolute URL construction + * test absolute URL construction * @dataProvider provideSubDirURLs */ function testMakeAbsoluteURLSubDir($url, $expectedResult) { @@ -326,7 +326,7 @@ class Test_Helper extends PHPUnit_Framework_TestCase { /** * @small - * @brief test linkTo URL construction + * test linkTo URL construction * @dataProvider provideDocRootAppUrlParts */ public function testLinkToDocRoot($app, $file, $args, $expectedResult) { @@ -338,7 +338,7 @@ class Test_Helper extends PHPUnit_Framework_TestCase { /** * @small - * @brief test linkTo URL construction in sub directory + * test linkTo URL construction in sub directory * @dataProvider provideSubDirAppUrlParts */ public function testLinkToSubDir($app, $file, $args, $expectedResult) { @@ -366,7 +366,7 @@ class Test_Helper extends PHPUnit_Framework_TestCase { /** * @small - * @brief test linkToAbsolute URL construction + * test linkToAbsolute URL construction * @dataProvider provideDocRootAppAbsoluteUrlParts */ public function testLinkToAbsoluteDocRoot($app, $file, $args, $expectedResult) { @@ -378,7 +378,7 @@ class Test_Helper extends PHPUnit_Framework_TestCase { /** * @small - * @brief test linkToAbsolute URL construction in sub directory + * test linkToAbsolute URL construction in sub directory * @dataProvider provideSubDirAppAbsoluteUrlParts */ public function testLinkToAbsoluteSubDir($app, $file, $args, $expectedResult) { @@ -406,7 +406,7 @@ class Test_Helper extends PHPUnit_Framework_TestCase { /** * @small - * @brief test linkToRemoteBase URL construction + * test linkToRemoteBase URL construction */ public function testLinkToRemoteBase() { \OC::$WEBROOT = ''; @@ -420,7 +420,7 @@ class Test_Helper extends PHPUnit_Framework_TestCase { /** * @small - * @brief test linkToRemote URL construction + * test linkToRemote URL construction */ public function testLinkToRemote() { \OC::$WEBROOT = ''; @@ -438,7 +438,7 @@ class Test_Helper extends PHPUnit_Framework_TestCase { /** * @small - * @brief test linkToPublic URL construction + * test linkToPublic URL construction */ public function testLinkToPublic() { \OC::$WEBROOT = ''; diff --git a/tests/lib/logger.php b/tests/lib/logger.php new file mode 100644 index 0000000000000000000000000000000000000000..7d5d4049b289e24043d17ed5ae63a42c31b2a4a4 --- /dev/null +++ b/tests/lib/logger.php @@ -0,0 +1,40 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace Test; + +use OC\Log; + +class Logger extends \PHPUnit_Framework_TestCase { + /** + * @var \OCP\ILogger + */ + private $logger; + static private $logs = array(); + + public function setUp() { + self::$logs = array(); + $this->logger = new Log($this); + } + + public function testInterpolation() { + $logger = $this->logger; + $logger->info('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar')); + + $expected = array('1 {Message {nothing} Bob Bar a}'); + $this->assertEquals($expected, $this->getLogs()); + } + + private function getLogs() { + return self::$logs; + } + + public static function write($app, $message, $level) { + self::$logs[]= "$level $message"; + } +} diff --git a/tests/lib/migrate.php b/tests/lib/migrate.php index d438a7a692e8caa42d8fc61da027fa6bcba3141a..c4442511e1ff71a5af88c669ed115c1fdde06917 100644 --- a/tests/lib/migrate.php +++ b/tests/lib/migrate.php @@ -12,7 +12,7 @@ class Test_Migrate extends PHPUnit_Framework_TestCase { public $tmpfiles = array(); /** - * @brief Generates a test user and sets up their file system + * Generates a test user and sets up their file system * @return string the test users id */ public function generateUser() { @@ -27,8 +27,8 @@ class Test_Migrate extends PHPUnit_Framework_TestCase { } /** - * @brief validates an export for a user - * @brief checks for existence of export_info.json and file folder + * validates an export for a user + * checks for existence of export_info.json and file folder * @param string $exportedUser the user that was exported * @param string $path the path to the .zip export * @param string $exportedBy diff --git a/tests/lib/template.php b/tests/lib/template.php index eedf688721d4d3367890723e950cf940290cf3ab..819d592aacfb9235f2099a37d7cbb61c47345349 100644 --- a/tests/lib/template.php +++ b/tests/lib/template.php @@ -3,7 +3,7 @@ * ownCloud * * @author Bernhard Posselt -* @copyright 2012 Bernhard Posselt nukeawhale@gmail.com +* @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/tests/lib/urlgenerator.php b/tests/lib/urlgenerator.php index 65c7fb569433d87031e7dbc7477077109de89b1c..888512ee426c1d212a28f4ad33a9a1f21a6f3cdb 100644 --- a/tests/lib/urlgenerator.php +++ b/tests/lib/urlgenerator.php @@ -10,7 +10,7 @@ class Test_Urlgenerator extends PHPUnit_Framework_TestCase { /** * @small - * @brief test linkTo URL construction + * test linkTo URL construction * @dataProvider provideDocRootAppUrlParts */ public function testLinkToDocRoot($app, $file, $args, $expectedResult) { @@ -24,7 +24,7 @@ class Test_Urlgenerator extends PHPUnit_Framework_TestCase { /** * @small - * @brief test linkTo URL construction in sub directory + * test linkTo URL construction in sub directory * @dataProvider provideSubDirAppUrlParts */ public function testLinkToSubDir($app, $file, $args, $expectedResult) { @@ -54,7 +54,7 @@ class Test_Urlgenerator extends PHPUnit_Framework_TestCase { /** * @small - * @brief test absolute URL construction + * test absolute URL construction * @dataProvider provideDocRootURLs */ function testGetAbsoluteURLDocRoot($url, $expectedResult) { @@ -68,7 +68,7 @@ class Test_Urlgenerator extends PHPUnit_Framework_TestCase { /** * @small - * @brief test absolute URL construction + * test absolute URL construction * @dataProvider provideSubDirURLs */ function testGetAbsoluteURLSubDir($url, $expectedResult) {