diff options
25 files changed, 418 insertions, 84 deletions
diff --git a/apps/files/css/files.css b/apps/files/css/files.css index 2ba1f774d49..d0a2cce1a86 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -570,6 +570,10 @@ a.action > img { margin-bottom: -1px; } +html.ie8 .column-mtime .selectedActions { + top: -95px; +} + #fileList a.action { display: inline; padding: 17px 8px; diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js index 03330ad7c5d..8bae8567a05 100644 --- a/apps/files/js/file-upload.js +++ b/apps/files/js/file-upload.js @@ -201,8 +201,11 @@ OC.Upload = { return true; }); if (conflicts.length) { - _.each(conflicts, function(conflictData) { - OC.dialogs.fileexists(conflictData[1], conflictData[0], conflictData[1].files[0], OC.Upload); + // wait for template loading + OC.dialogs.fileexists(null, null, null, OC.Upload).done(function() { + _.each(conflicts, function(conflictData) { + OC.dialogs.fileexists(conflictData[1], conflictData[0], conflictData[1].files[0], OC.Upload); + }); }); } diff --git a/apps/files/lib/activity.php b/apps/files/lib/activity.php index bf80d0cfd7c..f3bbff48640 100644 --- a/apps/files/lib/activity.php +++ b/apps/files/lib/activity.php @@ -145,6 +145,24 @@ class Activity implements IExtension { } $l = $this->getL10N($languageCode); + + if ($this->activityManager->isFormattingFilteredObject()) { + $translation = $this->translateShort($text, $l, $params); + if ($translation !== false) { + return $translation; + } + } + + return $this->translateLong($text, $l, $params); + } + + /** + * @param string $text + * @param IL10N $l + * @param array $params + * @return bool|string + */ + protected function translateLong($text, IL10N $l, array $params) { switch ($text) { case 'created_self': return (string) $l->t('You created %1$s', $params); @@ -171,6 +189,26 @@ class Activity implements IExtension { } /** + * @param string $text + * @param IL10N $l + * @param array $params + * @return bool|string + */ + protected function translateShort($text, IL10N $l, array $params) { + switch ($text) { + case 'changed_by': + return (string) $l->t('Changed by %2$s', $params); + case 'deleted_by': + return (string) $l->t('Deleted by %2$s', $params); + case 'restored_by': + return (string) $l->t('Restored by %2$s', $params); + + default: + return false; + } + } + + /** * The extension can define the type of parameters for translation * * Currently known types are: diff --git a/apps/files_sharing/api/remote.php b/apps/files_sharing/api/remote.php index 0f6d2dc265a..76f9babcd19 100644 --- a/apps/files_sharing/api/remote.php +++ b/apps/files_sharing/api/remote.php @@ -27,9 +27,9 @@ use OCA\Files_Sharing\External\Manager; class Remote { /** - * Accept a remote share + * Get list of pending remote shares * - * @param array $params contains the shareID 'id' which should be accepted + * @param array $params empty * @return \OC_OCS_Result */ public static function getOpenShares($params) { @@ -90,4 +90,101 @@ class Remote { return new \OC_OCS_Result(null, 404, "wrong share ID, share doesn't exist."); } + + /** + * @param array $share Share with info from the share_external table + * @return enriched share info with data from the filecache + */ + private static function extendShareInfo($share) { + $view = new \OC\Files\View('/' . \OC_User::getUser() . '/files/'); + $info = $view->getFileInfo($shares['mountpoint']); + + $share['mimetype'] = $info->getMimetype(); + $share['mtime'] = $info->getMtime(); + $share['permissions'] = $info->getPermissions(); + $share['type'] = $info->getType(); + $share['file_id'] = $info->getId(); + + return $share; + } + + /** + * List accepted remote shares + * + * @param array $params + * @return \OC_OCS_Result + */ + public static function getShares($params) { + $externalManager = new Manager( + \OC::$server->getDatabaseConnection(), + Filesystem::getMountManager(), + Filesystem::getLoader(), + \OC::$server->getHTTPHelper(), + \OC::$server->getNotificationManager(), + \OC_User::getUser() + ); + + $shares = $externalManager->getAcceptedShares(); + + $shares = array_map('self::extendShareInfo', $shares); + + return new \OC_OCS_Result($shares); + } + + /** + * Get info of a remote share + * + * @param array $params contains the shareID 'id' + * @return \OC_OCS_Result + */ + public static function getShare($params) { + $externalManager = new Manager( + \OC::$server->getDatabaseConnection(), + Filesystem::getMountManager(), + Filesystem::getLoader(), + \OC::$server->getHTTPHelper(), + \OC::$server->getNotificationManager(), + \OC_User::getUser() + ); + + $shareInfo = $externalManager->getShare($params['id']); + + if ($shareInfo === false) { + return new \OC_OCS_Result(null, 404, 'share does not exist'); + } else { + $shareInfo = self::extendShareInfo($shareInfo); + return new \OC_OCS_Result($shareInfo); + } + } + + /** + * Unshare a remote share + * + * @param array $params contains the shareID 'id' which should be unshared + * @return \OC_OCS_Result + */ + public static function unshare($params) { + $externalManager = new Manager( + \OC::$server->getDatabaseConnection(), + Filesystem::getMountManager(), + Filesystem::getLoader(), + \OC::$server->getHTTPHelper(), + \OC::$server->getNotificationManager(), + \OC_User::getUser() + ); + + $shareInfo = $externalManager->getShare($params['id']); + + if ($shareInfo === false) { + return new \OC_OCS_Result(null, 404, 'Share does not exist'); + } + + $mountPoint = '/' . \OC_User::getUser() . '/files' . $shareInfo['mountpoint']; + + if ($externalManager->removeShare($mountPoint) === true) { + return new \OC_OCS_Result(null); + } else { + return new \OC_OCS_Result(null, 403, 'Could not unshare'); + } + } } diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php index 15c0b864b08..1417dd6214b 100644 --- a/apps/files_sharing/appinfo/app.php +++ b/apps/files_sharing/appinfo/app.php @@ -70,7 +70,8 @@ $eventDispatcher->addListener( \OC::$server->getActivityManager()->registerExtension(function() { return new \OCA\Files_Sharing\Activity( \OC::$server->query('L10NFactory'), - \OC::$server->getURLGenerator() + \OC::$server->getURLGenerator(), + \OC::$server->getActivityManager() ); }); diff --git a/apps/files_sharing/appinfo/routes.php b/apps/files_sharing/appinfo/routes.php index 375124cb730..3794df37992 100644 --- a/apps/files_sharing/appinfo/routes.php +++ b/apps/files_sharing/appinfo/routes.php @@ -89,19 +89,35 @@ API::register('delete', API::register('get', '/apps/files_sharing/api/v1/remote_shares', + array('\OCA\Files_Sharing\API\Remote', 'getShares'), + 'files_sharing'); + +API::register('get', + '/apps/files_sharing/api/v1/remote_shares/pending', array('\OCA\Files_Sharing\API\Remote', 'getOpenShares'), 'files_sharing'); API::register('post', - '/apps/files_sharing/api/v1/remote_shares/{id}', + '/apps/files_sharing/api/v1/remote_shares/pending/{id}', array('\OCA\Files_Sharing\API\Remote', 'acceptShare'), 'files_sharing'); API::register('delete', - '/apps/files_sharing/api/v1/remote_shares/{id}', + '/apps/files_sharing/api/v1/remote_shares/pending/{id}', array('\OCA\Files_Sharing\API\Remote', 'declineShare'), 'files_sharing'); +API::register('get', + '/apps/files_sharing/api/v1/remote_shares/{id}', + array('\OCA\Files_Sharing\API\Remote', 'getShare'), + 'files_sharing'); + +API::register('delete', + '/apps/files_sharing/api/v1/remote_shares/{id}', + array('\OCA\Files_Sharing\API\Remote', 'unshare'), + 'files_sharing'); + + $sharees = new \OCA\Files_Sharing\API\Sharees(\OC::$server->getGroupManager(), \OC::$server->getUserManager(), \OC::$server->getContactsManager(), diff --git a/apps/files_sharing/lib/activity.php b/apps/files_sharing/lib/activity.php index 63ac2e90b2a..c5eb7d09ede 100644 --- a/apps/files_sharing/lib/activity.php +++ b/apps/files_sharing/lib/activity.php @@ -24,6 +24,8 @@ namespace OCA\Files_Sharing; use OCP\Activity\IExtension; +use OCP\Activity\IManager; +use OCP\IL10N; use OCP\IURLGenerator; use OCP\L10N\IFactory; @@ -67,13 +69,18 @@ class Activity implements IExtension { /** @var IURLGenerator */ protected $URLGenerator; + /** @var IManager */ + protected $activityManager; + /** * @param IFactory $languageFactory * @param IURLGenerator $URLGenerator + * @param IManager $activityManager */ - public function __construct(IFactory $languageFactory, IURLGenerator $URLGenerator) { + public function __construct(IFactory $languageFactory, IURLGenerator $URLGenerator, IManager $activityManager) { $this->languageFactory = $languageFactory; $this->URLGenerator = $URLGenerator; + $this->activityManager = $activityManager; } protected function getL10N($languageCode = null) { @@ -149,49 +156,102 @@ class Activity implements IExtension { * @return string|false */ public function translate($app, $text, $params, $stripPath, $highlightParams, $languageCode) { + if ($app !== self::FILES_SHARING_APP) { + return false; + } + $l = $this->getL10N($languageCode); - if ($app === self::FILES_SHARING_APP) { - switch ($text) { - case self::SUBJECT_REMOTE_SHARE_RECEIVED: - if (sizeof($params) === 2) { - // New activity ownCloud 8.2+ - return (string) $l->t('You received a new remote share %2$s from %1$s', $params); - } - return (string) $l->t('You received a new remote share from %s', $params); - case self::SUBJECT_REMOTE_SHARE_ACCEPTED: - return (string) $l->t('%1$s accepted remote share %2$s', $params); - case self::SUBJECT_REMOTE_SHARE_DECLINED: - return (string) $l->t('%1$s declined remote share %2$s', $params); - case self::SUBJECT_REMOTE_SHARE_UNSHARED: - return (string) $l->t('%1$s unshared %2$s from you', $params); - case self::SUBJECT_PUBLIC_SHARED_FOLDER_DOWNLOADED: - return (string) $l->t('Public shared folder %1$s was downloaded', $params); - case self::SUBJECT_PUBLIC_SHARED_FILE_DOWNLOADED: - return (string) $l->t('Public shared file %1$s was downloaded', $params); - case self::SUBJECT_SHARED_USER_SELF: - return (string) $l->t('You shared %1$s with %2$s', $params); - case self::SUBJECT_SHARED_GROUP_SELF: - return (string) $l->t('You shared %1$s with group %2$s', $params); - case self::SUBJECT_RESHARED_USER_BY: - return (string) $l->t('%2$s shared %1$s with %3$s', $params); - case self::SUBJECT_RESHARED_GROUP_BY: - return (string) $l->t('%2$s shared %1$s with group %3$s', $params); - case self::SUBJECT_RESHARED_LINK_BY: - return (string) $l->t('%2$s shared %1$s via link', $params); - case self::SUBJECT_SHARED_WITH_BY: - return (string) $l->t('%2$s shared %1$s with you', $params); - case self::SUBJECT_SHARED_LINK_SELF: - return (string) $l->t('You shared %1$s via link', $params); - case self::SUBJECT_SHARED_EMAIL: - return (string) $l->t('You shared %1$s with %2$s', $params); + if ($this->activityManager->isFormattingFilteredObject()) { + $translation = $this->translateShort($text, $l, $params); + if ($translation !== false) { + return $translation; } } + return $this->translateLong($text, $l, $params); + } + + /** + * @param string $text + * @param IL10N $l + * @param array $params + * @return bool|string + */ + protected function translateLong($text, IL10N $l, array $params) { + + switch ($text) { + case self::SUBJECT_REMOTE_SHARE_RECEIVED: + if (sizeof($params) === 2) { + // New activity ownCloud 8.2+ + return (string) $l->t('You received a new remote share %2$s from %1$s', $params); + } + return (string) $l->t('You received a new remote share from %s', $params); + case self::SUBJECT_REMOTE_SHARE_ACCEPTED: + return (string) $l->t('%1$s accepted remote share %2$s', $params); + case self::SUBJECT_REMOTE_SHARE_DECLINED: + return (string) $l->t('%1$s declined remote share %2$s', $params); + case self::SUBJECT_REMOTE_SHARE_UNSHARED: + return (string) $l->t('%1$s unshared %2$s from you', $params); + case self::SUBJECT_PUBLIC_SHARED_FOLDER_DOWNLOADED: + return (string) $l->t('Public shared folder %1$s was downloaded', $params); + case self::SUBJECT_PUBLIC_SHARED_FILE_DOWNLOADED: + return (string) $l->t('Public shared file %1$s was downloaded', $params); + case self::SUBJECT_SHARED_USER_SELF: + return (string) $l->t('You shared %1$s with %2$s', $params); + case self::SUBJECT_SHARED_GROUP_SELF: + return (string) $l->t('You shared %1$s with group %2$s', $params); + case self::SUBJECT_RESHARED_USER_BY: + return (string) $l->t('%2$s shared %1$s with %3$s', $params); + case self::SUBJECT_RESHARED_GROUP_BY: + return (string) $l->t('%2$s shared %1$s with group %3$s', $params); + case self::SUBJECT_RESHARED_LINK_BY: + return (string) $l->t('%2$s shared %1$s via link', $params); + case self::SUBJECT_SHARED_WITH_BY: + return (string) $l->t('%2$s shared %1$s with you', $params); + case self::SUBJECT_SHARED_LINK_SELF: + return (string) $l->t('You shared %1$s via link', $params); + case self::SUBJECT_SHARED_EMAIL: + return (string) $l->t('You shared %1$s with %2$s', $params); + } + return false; } /** + * @param string $text + * @param IL10N $l + * @param array $params + * @return bool|string + */ + protected function translateShort($text, IL10N $l, array $params) { + switch ($text) { + case self::SUBJECT_PUBLIC_SHARED_FOLDER_DOWNLOADED: + case self::SUBJECT_PUBLIC_SHARED_FILE_DOWNLOADED: + return (string) $l->t('Downloaded via public link'); + case self::SUBJECT_SHARED_USER_SELF: + return (string) $l->t('Shared with %2$s', $params); + case self::SUBJECT_SHARED_GROUP_SELF: + return (string) $l->t('Shared with group %2$s', $params); + case self::SUBJECT_RESHARED_USER_BY: + return (string) $l->t('Shared with %3$s by %2$s', $params); + case self::SUBJECT_RESHARED_GROUP_BY: + return (string) $l->t('Shared with group %3$s by %2$s', $params); + case self::SUBJECT_RESHARED_LINK_BY: + return (string) $l->t('Shared via link by %2$s', $params); + case self::SUBJECT_SHARED_WITH_BY: + return (string) $l->t('Shared by %2$s', $params); + case self::SUBJECT_SHARED_LINK_SELF: + return (string) $l->t('Shared via public link'); + case self::SUBJECT_SHARED_EMAIL: + return (string) $l->t('Shared with %2$s', $params); + + default: + return false; + } + } + + /** * The extension can define the type of parameters for translation * * Currently known types are: diff --git a/apps/files_sharing/lib/external/manager.php b/apps/files_sharing/lib/external/manager.php index 8552b2fbd34..2ba02f40d2f 100644 --- a/apps/files_sharing/lib/external/manager.php +++ b/apps/files_sharing/lib/external/manager.php @@ -180,9 +180,9 @@ class Manager { * @param int $id share id * @return mixed share of false */ - private function getShare($id) { + public function getShare($id) { $getShare = $this->connection->prepare(' - SELECT `remote`, `remote_id`, `share_token`, `name` + SELECT `id`, `remote`, `remote_id`, `share_token`, `name`, `owner`, `user`, `mountpoint`, `accepted` FROM `*PREFIX*share_external` WHERE `id` = ? AND `user` = ?'); $result = $getShare->execute(array($id, $this->uid)); @@ -407,6 +407,15 @@ class Manager { } /** + * return a list of shares wich are accepted by the user + * + * @return array list of accepted server-to-server shares + */ + public function getAcceptedShares() { + return $this->getShares(true); + } + + /** * return a list of shares for the user * * @param bool|null $accepted True for accepted only, @@ -415,7 +424,9 @@ class Manager { * @return array list of open server-to-server shares */ private function getShares($accepted) { - $query = 'SELECT * FROM `*PREFIX*share_external` WHERE `user` = ?'; + $query = 'SELECT `id`, `remote`, `remote_id`, `share_token`, `name`, `owner`, `user`, `mountpoint`, `accepted` + FROM `*PREFIX*share_external` + WHERE `user` = ?'; $parameters = [$this->uid]; if (!is_null($accepted)) { $query .= ' AND `accepted` = ?'; diff --git a/apps/files_sharing/tests/activity.php b/apps/files_sharing/tests/activity.php index 53a306b70f7..f7f324cdfc3 100644 --- a/apps/files_sharing/tests/activity.php +++ b/apps/files_sharing/tests/activity.php @@ -36,7 +36,10 @@ class Activity extends \OCA\Files_Sharing\Tests\TestCase{ parent::setUp(); $this->activity = new \OCA\Files_Sharing\Activity( $this->getMock('\OC\L10N\Factory'), - $this->getMockBuilder('\OC\URLGenerator') + $this->getMockBuilder('\OCP\IURLGenerator') + ->disableOriginalConstructor() + ->getMock(), + $this->getMockBuilder('\OCP\Activity\IManager') ->disableOriginalConstructor() ->getMock() ); diff --git a/apps/files_trashbin/lib/storage.php b/apps/files_trashbin/lib/storage.php index 4185fc6aec4..0e42df1e967 100644 --- a/apps/files_trashbin/lib/storage.php +++ b/apps/files_trashbin/lib/storage.php @@ -142,6 +142,13 @@ class Storage extends Wrapper { ) { return call_user_func_array([$this->storage, $method], [$path]); } + + // check permissions before we continue, this is especially important for + // shared files + if (!$this->isDeletable($path)) { + return false; + } + $normalized = Filesystem::normalizePath($this->mountPoint . '/' . $path); $result = true; if (!isset($this->deletedFiles[$normalized])) { diff --git a/apps/files_trashbin/lib/trashbin.php b/apps/files_trashbin/lib/trashbin.php index 840fd4fa146..ea6f0993dd6 100644 --- a/apps/files_trashbin/lib/trashbin.php +++ b/apps/files_trashbin/lib/trashbin.php @@ -136,27 +136,28 @@ class Trashbin { * * @param string $sourcePath * @param string $owner - * @param string $ownerPath + * @param $targetPath + * @param $user * @param integer $timestamp */ - private static function copyFilesToOwner($sourcePath, $owner, $ownerPath, $timestamp) { + private static function copyFilesToUser($sourcePath, $owner, $targetPath, $user, $timestamp) { self::setUpTrash($owner); - $ownerFilename = basename($ownerPath); - $ownerLocation = dirname($ownerPath); + $targetFilename = basename($targetPath); + $targetLocation = dirname($targetPath); $sourceFilename = basename($sourcePath); $view = new \OC\Files\View('/'); - $source = \OCP\User::getUser() . '/files_trashbin/files/' . $sourceFilename . '.d' . $timestamp; - $target = $owner . '/files_trashbin/files/' . $ownerFilename . '.d' . $timestamp; + $target = $user . '/files_trashbin/files/' . $targetFilename . '.d' . $timestamp; + $source = $owner . '/files_trashbin/files/' . $sourceFilename . '.d' . $timestamp; self::copy_recursive($source, $target, $view); if ($view->file_exists($target)) { $query = \OC_DB::prepare("INSERT INTO `*PREFIX*files_trash` (`id`,`timestamp`,`location`,`user`) VALUES (?,?,?,?)"); - $result = $query->execute(array($ownerFilename, $timestamp, $ownerLocation, $owner)); + $result = $query->execute(array($targetFilename, $timestamp, $targetLocation, $user)); if (!$result) { \OCP\Util::writeLog('files_trashbin', 'trash bin database couldn\'t be updated for the files owner', \OCP\Util::ERROR); } @@ -168,6 +169,7 @@ class Trashbin { * move file to the trash bin * * @param string $file_path path to the deleted file/directory relative to the files root directory + * @return bool */ public static function move2trash($file_path) { // get the user for which the filesystem is setup @@ -176,9 +178,9 @@ class Trashbin { $size = 0; list($owner, $ownerPath) = self::getUidAndFilename($file_path); - $view = new \OC\Files\View('/' . $user); + $ownerView = new \OC\Files\View('/' . $owner); // file has been deleted in between - if (!$view->file_exists('/files/' . $file_path)) { + if (!$ownerView->file_exists('/files/' . $ownerPath)) { return true; } @@ -188,7 +190,7 @@ class Trashbin { self::setUpTrash($owner); } - $path_parts = pathinfo($file_path); + $path_parts = pathinfo($ownerPath); $filename = $path_parts['basename']; $location = $path_parts['dirname']; @@ -200,9 +202,9 @@ class Trashbin { $trashPath = '/files_trashbin/files/' . $filename . '.d' . $timestamp; /** @var \OC\Files\Storage\Storage $trashStorage */ - list($trashStorage, $trashInternalPath) = $view->resolvePath($trashPath); + list($trashStorage, $trashInternalPath) = $ownerView->resolvePath($trashPath); /** @var \OC\Files\Storage\Storage $sourceStorage */ - list($sourceStorage, $sourceInternalPath) = $view->resolvePath('/files/' . $file_path); + list($sourceStorage, $sourceInternalPath) = $ownerView->resolvePath('/files/' . $ownerPath); try { $sizeOfAddedFiles = $sourceStorage->filesize($sourceInternalPath); if ($trashStorage->file_exists($trashInternalPath)) { @@ -222,23 +224,23 @@ class Trashbin { return false; } - $view->getUpdater()->rename('/files/' . $file_path, $trashPath); + $ownerView->getUpdater()->rename('/files/' . $ownerPath, $trashPath); if ($sizeOfAddedFiles !== false) { $size = $sizeOfAddedFiles; $query = \OC_DB::prepare("INSERT INTO `*PREFIX*files_trash` (`id`,`timestamp`,`location`,`user`) VALUES (?,?,?,?)"); - $result = $query->execute(array($filename, $timestamp, $location, $user)); + $result = $query->execute(array($filename, $timestamp, $location, $owner)); if (!$result) { \OCP\Util::writeLog('files_trashbin', 'trash bin database couldn\'t be updated', \OCP\Util::ERROR); } \OCP\Util::emitHook('\OCA\Files_Trashbin\Trashbin', 'post_moveToTrash', array('filePath' => \OC\Files\Filesystem::normalizePath($file_path), 'trashPath' => \OC\Files\Filesystem::normalizePath($filename . '.d' . $timestamp))); - $size += self::retainVersions($file_path, $filename, $owner, $ownerPath, $timestamp); + $size += self::retainVersions($filename, $owner, $ownerPath, $timestamp); // if owner !== user we need to also add a copy to the owners trash if ($user !== $owner) { - self::copyFilesToOwner($file_path, $owner, $ownerPath, $timestamp); + self::copyFilesToUser($ownerPath, $owner, $file_path, $user, $timestamp); } } @@ -258,7 +260,6 @@ class Trashbin { /** * Move file versions to trash so that they can be restored later * - * @param string $file_path path to original file * @param string $filename of deleted file * @param string $owner owner user id * @param string $ownerPath path relative to the owner's home storage @@ -266,7 +267,7 @@ class Trashbin { * * @return int size of stored versions */ - private static function retainVersions($file_path, $filename, $owner, $ownerPath, $timestamp) { + private static function retainVersions($filename, $owner, $ownerPath, $timestamp) { $size = 0; if (\OCP\App::isEnabled('files_versions') && !empty($ownerPath)) { diff --git a/apps/files_versions/js/versioncollection.js b/apps/files_versions/js/versioncollection.js index 3f8214cde8c..176f8e7529c 100644 --- a/apps/files_versions/js/versioncollection.js +++ b/apps/files_versions/js/versioncollection.js @@ -67,6 +67,11 @@ return this.fetch({remove: false}); }, + reset: function() { + this._currentIndex = 0; + OC.Backbone.Collection.prototype.reset.apply(this, arguments); + }, + parse: function(result) { var results = _.map(result.data.versions, function(version) { var revision = parseInt(version.version, 10); diff --git a/apps/files_versions/js/versionstabview.js b/apps/files_versions/js/versionstabview.js index 55f24868196..f2b1c18bd37 100644 --- a/apps/files_versions/js/versionstabview.js +++ b/apps/files_versions/js/versionstabview.js @@ -85,12 +85,18 @@ ev.preventDefault(); revision = $target.attr('data-revision'); + this.$el.find('.versions, .showMoreVersions').addClass('hidden'); + var versionModel = this.collection.get(revision); versionModel.revert({ success: function() { // reset and re-fetch the updated collection + self.$versionsContainer.empty(); self.collection.setFileInfo(fileInfoModel); - self.collection.fetch(); + self.collection.reset([], {silent: true}); + self.collection.fetchNext(); + + self.$el.find('.versions').removeClass('hidden'); // update original model fileInfoModel.trigger('busy', fileInfoModel, false); @@ -157,7 +163,7 @@ if (fileInfo) { this.render(); this.collection.setFileInfo(fileInfo); - this.collection.reset({silent: true}); + this.collection.reset([], {silent: true}); this.nextPage(); } else { this.render(); diff --git a/config/config.sample.php b/config/config.sample.php index cf4b25b0674..88d1a294622 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -1141,6 +1141,15 @@ $CONFIG = array( 'debug' => false, /** + * Skips the migration test during upgrades + * + * If this is set to true the migration test are deactivated during upgrade. + * This is only recommended in installations where upgrade tests are run in + * advance with the same data on a test system. + */ +'update.skip-migration-test' => false, + +/** * This entry is just here to show a warning in case somebody copied the sample * configuration. DO NOT ADD THIS SWITCH TO YOUR CONFIGURATION! * diff --git a/core/ajax/update.php b/core/ajax/update.php index ff18d2bc04b..11d159f15d1 100644 --- a/core/ajax/update.php +++ b/core/ajax/update.php @@ -41,12 +41,21 @@ if (OC::checkUpgrade(false)) { // avoid side effects \OC_User::setIncognitoMode(true); + + $logger = \OC::$server->getLogger(); + $config = \OC::$server->getConfig(); $updater = new \OC\Updater( \OC::$server->getHTTPHelper(), - \OC::$server->getConfig(), + $config, $logger ); + + if ($config->getSystemValue('update.skip-migration-test', false)) { + $eventSource->send('success', (string)$l->t('Migration tests are skipped - "update.skip-migration-test" is activated in config.php')); + $updater->setSimulateStepEnabled(false); + } + $incompatibleApps = []; $disabledThirdPartyApps = []; diff --git a/core/command/upgrade.php b/core/command/upgrade.php index fa160d9a1c0..f50a0d92479 100644 --- a/core/command/upgrade.php +++ b/core/command/upgrade.php @@ -92,6 +92,12 @@ class Upgrade extends Command { $updateStepEnabled = true; $skip3rdPartyAppsDisable = false; + if ($this->config->getSystemValue('update.skip-migration-test', false)) { + $output->writeln( + '<info>"skip-migration-test" is activated via config.php</info>' + ); + $simulateStepEnabled = false; + } if ($input->getOption('skip-migration-test')) { $simulateStepEnabled = false; } @@ -119,7 +125,7 @@ class Upgrade extends Command { $self = $this; $updater = new Updater(\OC::$server->getHTTPHelper(), - \OC::$server->getConfig()); + $this->config); $updater->setSimulateStepEnabled($simulateStepEnabled); $updater->setUpdateStepEnabled($updateStepEnabled); diff --git a/core/js/oc-dialogs.js b/core/js/oc-dialogs.js index c38250c79c6..7af50c4ddfc 100644 --- a/core/js/oc-dialogs.js +++ b/core/js/oc-dialogs.js @@ -312,9 +312,11 @@ var OCdialogs = { * @param {object} original file with name, size and mtime * @param {object} replacement file with name, size and mtime * @param {object} controller with onCancel, onSkip, onReplace and onRename methods + * @return {Promise} jquery promise that resolves after the dialog template was loaded */ fileexists:function(data, original, replacement, controller) { var self = this; + var dialogDeferred = new $.Deferred(); var getCroppedPreview = function(file) { var deferred = new $.Deferred(); @@ -540,7 +542,7 @@ var OCdialogs = { //recalculate dimensions $(window).trigger('resize'); - + dialogDeferred.resolve(); } else { //create dialog this._fileexistsshown = true; @@ -559,8 +561,10 @@ var OCdialogs = { }); $('body').append($dlg); - var $conflicts = $dlg.find('.conflicts'); - addConflict($conflicts, original, replacement); + if (original && replacement) { + var $conflicts = $dlg.find('.conflicts'); + addConflict($conflicts, original, replacement); + } var buttonlist = [{ text: t('core', 'Cancel'), @@ -612,7 +616,7 @@ var OCdialogs = { }); $(dialogId).find('.conflicts').on('click', '.replacement input[type="checkbox"],.original:not(.readonly) input[type="checkbox"]', function() { var $checkbox = $(this); - $checkbox.prop('checked', !checkbox.prop('checked')); + $checkbox.prop('checked', !$checkbox.prop('checked')); }); //update counters @@ -643,12 +647,15 @@ var OCdialogs = { $(dialogId).find('.allexistingfiles + .count').text(''); } }); + dialogDeferred.resolve(); }) .fail(function() { + dialogDeferred.reject(); alert(t('core', 'Error loading file exists template')); }); } //} + return dialogDeferred.promise(); }, _getFilePickerTemplate: function() { var defer = $.Deferred(); diff --git a/lib/private/activitymanager.php b/lib/private/activitymanager.php index fc250173536..340f3d335e5 100644 --- a/lib/private/activitymanager.php +++ b/lib/private/activitymanager.php @@ -44,6 +44,12 @@ class ActivityManager implements IManager { /** @var IConfig */ protected $config; + /** @var string */ + protected $formattingObjectType; + + /** @var int */ + protected $formattingObjectId; + /** * constructor of the controller * @@ -304,6 +310,24 @@ class ActivityManager implements IManager { } /** + * @param string $type + * @param int $id + */ + public function setFormattingObject($type, $id) { + $this->formattingObjectType = $type; + $this->formattingObjectId = $id; + } + + /** + * @return bool + */ + public function isFormattingFilteredObject() { + return 'filter' === $this->request->getParam('filter') + && $this->formattingObjectType === $this->request->getParam('objecttype') + && $this->formattingObjectId === $this->request->getParam('objectid'); + } + + /** * @param string $app * @param string $text * @param array $params diff --git a/lib/private/util.php b/lib/private/util.php index 9abaef71a68..746a2e09523 100644 --- a/lib/private/util.php +++ b/lib/private/util.php @@ -223,7 +223,12 @@ class OC_Util { if (\OC::$server->getAppConfig()->getValue('core', 'shareapi_exclude_groups', 'no') === 'yes') { $user = \OCP\User::getUser(); $groupsList = \OC::$server->getAppConfig()->getValue('core', 'shareapi_exclude_groups_list', ''); - $excludedGroups = explode(',', $groupsList); + $excludedGroups = json_decode($groupsList); + if (is_null($excludedGroups)) { + $excludedGroups = explode(',', $groupsList); + $newValue = json_encode($excludedGroups); + \OC::$server->getAppConfig()->setValue('core', 'shareapi_exclude_groups_list', $newValue); + } $usersGroups = \OC_Group::getUserGroups($user); if (!empty($usersGroups)) { $remainingGroups = array_diff($usersGroups, $excludedGroups); diff --git a/lib/public/activity/imanager.php b/lib/public/activity/imanager.php index b3a4969fb06..280babb7fa9 100644 --- a/lib/public/activity/imanager.php +++ b/lib/public/activity/imanager.php @@ -138,6 +138,19 @@ interface IManager { public function getTypeIcon($type); /** + * @param string $type + * @param int $id + * @since 8.2.0 + */ + public function setFormattingObject($type, $id); + + /** + * @return bool + * @since 8.2.0 + */ + public function isFormattingFilteredObject(); + + /** * @param string $app * @param string $text * @param array $params diff --git a/settings/admin.php b/settings/admin.php index 31c9b8c1376..ec49b3e823f 100644 --- a/settings/admin.php +++ b/settings/admin.php @@ -87,7 +87,7 @@ $template->assign('shareEnforceExpireDate', $appConfig->getValue('core', 'sharea $excludeGroups = $appConfig->getValue('core', 'shareapi_exclude_groups', 'no') === 'yes' ? true : false; $template->assign('shareExcludeGroups', $excludeGroups); $excludedGroupsList = $appConfig->getValue('core', 'shareapi_exclude_groups_list', ''); -$excludedGroupsList = explode(',', $excludedGroupsList); // FIXME: this should be JSON! +$excludedGroupsList = json_decode($excludedGroupsList); $template->assign('shareExcludedGroupsList', implode('|', $excludedGroupsList)); $template->assign('encryptionEnabled', \OC::$server->getEncryptionManager()->isEnabled()); $backends = \OC::$server->getUserManager()->getBackends(); diff --git a/settings/js/admin.js b/settings/js/admin.js index 7117c7b46cf..9f7133c6571 100644 --- a/settings/js/admin.js +++ b/settings/js/admin.js @@ -23,11 +23,7 @@ $(document).ready(function(){ OC.Settings.setupGroupsSelect($(element)); $(element).change(function(ev) { var groups = ev.val || []; - if (groups.length > 0) { - groups = ev.val.join(','); // FIXME: make this JSON - } else { - groups = ''; - } + groups = JSON.stringify(groups); OC.AppConfig.setValue('core', $(this).attr('name'), groups); }); }); diff --git a/settings/js/users/groups.js b/settings/js/users/groups.js index 322db6c1b45..c8d2ef7c5b1 100644 --- a/settings/js/users/groups.js +++ b/settings/js/users/groups.js @@ -49,18 +49,26 @@ GroupList = { return parseInt($groupLiElement.data('usercount'), 10); }, - modEveryoneCount: function(diff) { - var $li = GroupList.getGroupLI(GroupList.everyoneGID); + modGroupCount: function(gid, diff) { + var $li = GroupList.getGroupLI(gid); var count = GroupList.getUserCount($li) + diff; GroupList.setUserCount($li, count); }, incEveryoneCount: function() { - GroupList.modEveryoneCount(1); + GroupList.modGroupCount(GroupList.everyoneGID, 1); }, decEveryoneCount: function() { - GroupList.modEveryoneCount(-1); + GroupList.modGroupCount(GroupList.everyoneGID, -1); + }, + + incGroupCount: function(gid) { + GroupList.modGroupCount(gid, 1); + }, + + decGroupCount: function(gid) { + GroupList.modGroupCount(gid, -1); }, getCurrentGID: function () { diff --git a/settings/js/users/users.js b/settings/js/users/users.js index 47d63c11b95..519fe9655db 100644 --- a/settings/js/users/users.js +++ b/settings/js/users/users.js @@ -470,6 +470,11 @@ var UserList = { UserList.availableGroups.push(groupName); } + if (response.data.action === 'add') { + GroupList.incGroupCount(groupName); + } else { + GroupList.decGroupCount(groupName); + } } if (response.data.message) { OC.Notification.show(response.data.message); diff --git a/tests/lib/util.php b/tests/lib/util.php index 49579b3b6bd..eaa3d0795e3 100644 --- a/tests/lib/util.php +++ b/tests/lib/util.php @@ -303,7 +303,7 @@ class Test_Util extends \Test\TestCase { } $appConfig = \OC::$server->getAppConfig(); - $appConfig->setValue('core', 'shareapi_exclude_groups_list', implode(',', $excludedGroups)); + $appConfig->setValue('core', 'shareapi_exclude_groups_list', json_encode($excludedGroups)); $appConfig->setValue('core', 'shareapi_exclude_groups', 'yes'); $result = \OCP\Util::isSharingDisabledForUser(); |