diff --git a/appinfo/app.php b/appinfo/app.php index 2c7abea37..f4bb8455f 100644 --- a/appinfo/app.php +++ b/appinfo/app.php @@ -6,6 +6,8 @@ * later. See the COPYING file. * * @author Maxence Lange + * @author Vinicius Cubas Brand + * * @copyright 2017 * @license GNU AGPL version 3 or any later version * @@ -26,5 +28,9 @@ $app = new \OCA\Circles\AppInfo\Application(); -$app->registerNavigation(); $app->registerSettingsAdmin(); +$app->registerNavigation(); +$app->registerFilesNavigation(); +$app->registerFilesPlugin(); + + diff --git a/css/files/circles.filelist.css b/css/files/circles.filelist.css new file mode 100644 index 000000000..c2f42cb31 --- /dev/null +++ b/css/files/circles.filelist.css @@ -0,0 +1,54 @@ +/* + * Circles - Bring cloud-users closer together. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange + * @copyright 2017 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ +#app-content-circlesfilter .select2-container { + width: 30%; + margin-left: 10px; +} + +#app-content-circlesfilter .select2-choices { + white-space: nowrap; + text-overflow: ellipsis; + background: #fff; + color: #555; + box-sizing: content-box; + border-radius: 3px; + border: 1px solid #ddd; + padding: 0; + min-height: auto; +} + +.nav-icon-circlesfilter { + background-image: url('../../img/black_circle.svg'); +} + +#app-sidebar .mainFileInfoView .tag-label { + cursor: pointer; + padding: 13px; +} + +#app-sidebar .mainFileInfoView .icon-tag { + opacity: .5; + vertical-align: middle; +} diff --git a/files/list.php b/files/list.php new file mode 100644 index 000000000..70e82b1f4 --- /dev/null +++ b/files/list.php @@ -0,0 +1,6 @@ +printPage(); diff --git a/js/files/circles.files.app.js b/js/files/circles.files.app.js new file mode 100644 index 000000000..431b7868d --- /dev/null +++ b/js/files/circles.files.app.js @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2017 Cooperativa EITA (eita.org.br) + * + * @author Vinicius Cubas Brand + * @author Daniel Tygel + * + * This file is licensed under the Affero General Public License version 3 + * or later. + * + * See the COPYING-README file. + * + */ + +var api = OCA.Circles.api; + +(function() { + if (!OCA.Circles) { + /** + * @namespace + */ + OCA.Circles = {}; + } + + OCA.Circles.App = { + + initFileList: function($el) { + if (this._fileList) { + return this._fileList; + } + + this._fileList = new OCA.Circles.FileList( + $el, + { + id: 'circles', + scrollContainer: $('#app-content'), + fileActions: this._createFileActions(), + config: OCA.Files.App.getFilesConfig() + } + ); + + this._fileList.appName = t('circles', 'Circles'); + return this._fileList; + }, + + removeFileList: function() { + if (this._fileList) { + this._fileList.$fileList.empty(); + } + }, + + _createFileActions: function() { + // inherit file actions from the files app + var fileActions = new OCA.Files.FileActions(); + // note: not merging the legacy actions because legacy apps are not + // compatible with the sharing overview and need to be adapted first + fileActions.registerDefaultActions(); + fileActions.merge(OCA.Files.fileActions); + + if (!this._globalActionsInitialized) { + // in case actions are registered later + this._onActionsUpdated = _.bind(this._onActionsUpdated, this); + OCA.Files.fileActions.on('setDefault.app-circles', this._onActionsUpdated); + OCA.Files.fileActions.on('registerAction.app-circles', this._onActionsUpdated); + this._globalActionsInitialized = true; + } + + // when the user clicks on a folder, redirect to the corresponding + // folder in the files app instead of opening it directly + fileActions.register('dir', 'Open', OC.PERMISSION_READ, '', function (filename, context) { + OCA.Files.App.setActiveView('files', {silent: true}); + OCA.Files.App.fileList.changeDirectory(OC.joinPaths(context.$file.attr('data-path'), filename), true, true); + }); + fileActions.setDefault('dir', 'Open'); + return fileActions; + }, + + _onActionsUpdated: function(ev) { + if (!this._fileList) { + return; + } + + if (ev.action) { + this._fileList.fileActions.registerAction(ev.action); + } else if (ev.defaultAction) { + this._fileList.fileActions.setDefault( + ev.defaultAction.mime, + ev.defaultAction.name + ); + } + }, + + /** + * Destroy the app + */ + destroy: function() { + OCA.Files.fileActions.off('setDefault.app-circles', this._onActionsUpdated); + OCA.Files.fileActions.off('registerAction.app-circles', this._onActionsUpdated); + this.removeFileList(); + this._fileList = null; + delete this._globalActionsInitialized; + } + }; + +})(); + +$(document).ready(function() { + $('#app-content-circlesfilter').on('show', function(e) { + OCA.Circles.App.initFileList($(e.target)); + }); + $('#app-content-circlesfilter').on('hide', function() { + OCA.Circles.App.removeFileList(); + }); +}); diff --git a/js/files/circles.files.list.js b/js/files/circles.files.list.js new file mode 100644 index 000000000..89bc2e95d --- /dev/null +++ b/js/files/circles.files.list.js @@ -0,0 +1,293 @@ +/* + * Circles - Bring cloud-users closer together. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange + * @copyright 2017 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ +(function() { + /** + * @class OCA.Circles.FileList + * @augments OCA.Files.FileList + * + * @classdesc Circles file list. + * Contains a list of files filtered by circles + * + * @param $el container element with existing markup for the #controls + * and a table + * @param [options] map of options, see other parameters + * @param {Array.} [options.circlesIds] array of system tag ids to + * filter by + */ + var FileList = function($el, options) { + this.initialize($el, options); + }; + FileList.prototype = _.extend({}, OCA.Files.FileList.prototype, + /** @lends OCA.Circles.FileList.prototype */ { + id: 'circlesfilter', + appName: t('circles', 'Circles\' files'), + + /** + * Array of system tag ids to filter by + * + * @type Array. + */ + _circlesIds: [], + _lastUsedTags: [], + + _clientSideSort: true, + _allowSelection: false, + + _filterField: null, + + /** + * @private + */ + initialize: function($el, options) { + OCA.Files.FileList.prototype.initialize.apply(this, arguments); + if (this.initialized) { + return; + } + + if (options && options.circlesIds) { + this._circlesIds = options.circlesIds; + } + + OC.Plugins.attach('OCA.Circles.FileList', this); + + var $controls = this.$el.find('#controls').empty(); + + this._initFilterField($controls); + }, + + destroy: function() { + this.$filterField.remove(); + + OCA.Files.FileList.prototype.destroy.apply(this, arguments); + }, + + _initFilterField: function($container) { + var self = this; + this.$filterField = $(''); + $container.append(this.$filterField); + this.$filterField.select2({ + placeholder: t('circles', 'Select circles to filter by'), + allowClear: false, + multiple: true, + toggleSelect: true, + separator: ',', + query: _.bind(this._queryCirclesAutocomplete, this), + + id: function(circle) { + return circle.unique_id; + }, + + initSelection: function(element, callback) { + var val = $(element).val().trim(); + if (val) { + var circleIds = val.split(','), + circles = []; + + OCA.Circles.api.listCircles("all", '', 1, function(result) { + _.each(circleIds, function(circleId) { + var circle = _.find(result.data,function(circleData) { + return circleData.unique_id == circleId; + }); + if (!_.isUndefined(circle)) { + circles.push(circle); + } + }); + + callback(circles); + }); + + } else { + callback([]); + } + }, + + formatResult: function (circle) { + return circle.name; + }, + + formatSelection: function (circle) { + return circle.name; + //return OC.SystemTags.getDescriptiveTag(tag)[0].outerHTML; + }, + + sortResults: function(results) { + results.sort(function(a, b) { + var aLastUsed = self._lastUsedTags.indexOf(a.id); + var bLastUsed = self._lastUsedTags.indexOf(b.id); + + if (aLastUsed !== bLastUsed) { + if (bLastUsed === -1) { + return -1; + } + if (aLastUsed === -1) { + return 1; + } + return aLastUsed < bLastUsed ? -1 : 1; + } + + // Both not found + return OC.Util.naturalSortCompare(a.name, b.name); + }); + return results; + }, + + escapeMarkup: function(m) { + // prevent double markup escape + return m; + }, + formatNoMatches: function() { + return t('systemtags', 'No circles found'); + } + }); + this.$filterField.on('change', _.bind(this._onTagsChanged, this)); + return this.$filterField; + }, + + /** + * Autocomplete function for dropdown results + * + * @param {Object} query select2 query object + */ + _queryCirclesAutocomplete: function(query) { + + OCA.Circles.api.listCircles("all", query.term, 1, function(result) { + query.callback({ + results: result.data + }); + }); + /* + OC.SystemTags.collection.fetch({ + success: function() { + var results = OC.SystemTags.collection.filterByName(query.term); + + query.callback({ + results: _.invoke(results, 'toJSON') + }); + } + }); + */ + }, + + /** + * Event handler for when the URL changed + */ + _onUrlChanged: function(e) { + if (e.dir) { + var circles = _.filter(e.dir.split('/'), function(val) { return val.trim() !== ''; }); + this.$filterField.select2('val', circles || []); + this._circlesIds = circles; + this.reload(); + } + }, + + _onTagsChanged: function(ev) { + var val = $(ev.target).val().trim(); + if (val !== '') { + this._circlesIds = val.split(','); + } else { + this._circlesIds = []; + } + + this.$el.trigger(jQuery.Event('changeDirectory', { + dir: this._circlesIds.join('/') + })); + this.reload(); + }, + + updateEmptyContent: function() { + var dir = this.getCurrentDirectory(); + if (dir === '/') { + // root has special permissions + if (!this._circlesIds.length) { + // no tags selected + this.$el.find('#emptycontent').html('
' + + '

' + t('systemtags', 'Please select circles to filter by') + '

'); + } else { + // tags selected but no results + this.$el.find('#emptycontent').html('
' + + '

' + t('systemtags', 'No files found for the selected circles') + '

'); + } + this.$el.find('#emptycontent').toggleClass('hidden', !this.isEmpty); + this.$el.find('#filestable thead th').toggleClass('hidden', this.isEmpty); + } + else { + OCA.Files.FileList.prototype.updateEmptyContent.apply(this, arguments); + } + }, + + getDirectoryPermissions: function() { + return OC.PERMISSION_READ | OC.PERMISSION_DELETE; + }, + + updateStorageStatistics: function() { + // no op because it doesn't have + // storage info like free space / used space + }, + + reload: function() { + if (!this._circlesIds.length) { + // don't reload + this.updateEmptyContent(); + this.setFiles([]); + return $.Deferred().resolve(); + } + + this._selectedFiles = {}; + this._selectionSummary.clear(); + if (this._currentFileModel) { + this._currentFileModel.off(); + } + this._currentFileModel = null; + this.$el.find('.select-all').prop('checked', false); + this.showMask(); + this._reloadCall = this.filesClient.getFilteredFiles( + { + circlesIds: this._circlesIds + }, + { + properties: this._getWebdavProperties() + } + ); + if (this._detailsView) { + // close sidebar + this._updateDetailsView(null); + } + var callBack = this.reloadCallback.bind(this); + return this._reloadCall.then(callBack, callBack); + }, + + reloadCallback: function(status, result) { + if (result) { + // prepend empty dir info because original handler + result.unshift({}); + } + + return OCA.Files.FileList.prototype.reloadCallback.call(this, status, result); + } + }); + + OCA.Circles.FileList = FileList; +})(); + diff --git a/lib/Api/v1/Circles.php b/lib/Api/v1/Circles.php index dbac77706..104af315b 100644 --- a/lib/Api/v1/Circles.php +++ b/lib/Api/v1/Circles.php @@ -6,6 +6,9 @@ * later. See the COPYING file. * * @author Maxence Lange + * @author Vinicius Cubas Brand + * @author Daniel Tygel + * * @copyright 2017 * @license GNU AGPL version 3 or any later version * @@ -492,4 +495,20 @@ public static function generateCircleParameter(SharingFrame $frame) { ) ]; } + + /** + * Get a list of objects which are shred with $circleUniqueId. + * + * @since 0.14.0 + * + * @param array $circleUniqueIds + * + * @return string[] array of object ids or empty array if none found + */ + public static function getFilesForCircles($circleUniqueIds) { + $c = self::getContainer(); + + return $c->query(CirclesService::class) + ->getFilesForCircles($circleUniqueIds); + } } \ No newline at end of file diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index dad796b9e..a0c958215 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -6,6 +6,9 @@ * later. See the COPYING file. * * @author Maxence Lange + * @author Vinicius Cubas Brand + * @author Daniel Tygel + * * @copyright 2017 * @license GNU AGPL version 3 or any later version * @@ -26,33 +29,13 @@ namespace OCA\Circles\AppInfo; -use OCA\Circles\Controller\FederatedController; -use OCA\Circles\Controller\GroupsController; -use OCA\Circles\Controller\NavigationController; -use OCA\Circles\Controller\CirclesController; -use OCA\Circles\Controller\MembersController; - - -use OCA\Circles\Controller\SettingsController; -use OCA\Circles\Controller\SharesController; -use OCA\Circles\Db\CirclesRequest; -use OCA\Circles\Db\FederatedLinksRequest; -use OCA\Circles\Db\MembersRequest; -use OCA\Circles\Events\UserEvents; -use OCA\Circles\Service\BroadcastService; -use OCA\Circles\Service\CirclesService; -use OCA\Circles\Service\EventsService; -use OCA\Circles\Service\FederatedLinkService; -use OCA\Circles\Service\GroupsService; -use OCA\Circles\Service\MembersService; -use OCA\Circles\Service\ConfigService; -use OCA\Circles\Service\MiscService; -use OCA\Circles\Service\SearchService; -use OCA\Circles\Service\SharingFrameService; +use OCA\Circles\Api\v1\Circles; +use OCA\Files\App as FilesApp; use OCP\AppFramework\App; use OCP\AppFramework\IAppContainer; use OCP\Util; + class Application extends App { const APP_NAME = 'circles'; @@ -62,17 +45,18 @@ class Application extends App { const CLIENT_TIMEOUT = 3; + /** @var IAppContainer */ + private $container; + /** * @param array $params */ public function __construct(array $params = array()) { parent::__construct(self::APP_NAME, $params); - $container = $this->getContainer(); + $this->container = $this->getContainer(); - // TODO: POURQUOI SELF:: ??!?? - self::registerEvents($container); - self::registerHooks(); + $this->registerHooks(); } @@ -90,48 +74,71 @@ public function registerHooks() { /** - * Register Events - * - * @param IAppContainer $container - */ - public function registerEvents(IAppContainer $container) { -// $container->registerService( -// 'UserEvents', function(IAppContainer $c) { -// return new UserEvents( -// $c->query('MembersService'), $c->query('GroupsService'), $c->query('MiscService') -// ); -// } -// ); - } - - - /** - * Register Navigation Tab + * Register Navigation elements */ public function registerNavigation() { - $this->getContainer() - ->getServer() - ->getNavigationManager() - ->add( - function() { - $urlGen = \OC::$server->getURLGenerator(); - $navName = \OC::$server->getL10N(self::APP_NAME) - ->t('Circles'); - - return [ - 'id' => self::APP_NAME, - 'order' => 5, - 'href' => $urlGen->linkToRoute('circles.Navigation.navigate'), - 'icon' => $urlGen->imagePath(self::APP_NAME, 'circles.svg'), - 'name' => $navName - ]; - } - ); + $appManager = $this->container->getServer() + ->getNavigationManager(); + $appManager->add( + function() { + $urlGen = \OC::$server->getURLGenerator(); + $navName = \OC::$server->getL10N(self::APP_NAME) + ->t('Circles'); + + return [ + 'id' => self::APP_NAME, + 'order' => 5, + 'href' => $urlGen->linkToRoute('circles.Navigation.navigate'), + 'icon' => $urlGen->imagePath(self::APP_NAME, 'circles.svg'), + 'name' => $navName + ]; + } + ); + } + public function registerSettingsAdmin() { \OCP\App::registerAdmin(self::APP_NAME, 'lib/admin'); } + + public function registerFilesPlugin() { + $eventDispatcher = \OC::$server->getEventDispatcher(); + $eventDispatcher->addListener( + 'OCA\Files::loadAdditionalScripts', + function() { + Circles::addJavascriptAPI(); + + Util::addScript('circles', 'files/circles.files.app'); + Util::addScript('circles', 'files/circles.files.list'); + + Util::addStyle('circles', 'files/circles.filelist'); + } + ); + } + + + /** + * + */ + public function registerFilesNavigation() { + + $appManager = FilesApp::getNavigationManager(); + $appManager->add( + function() { + $l = \OC::$server->getL10N('circles'); + + return [ + 'id' => 'circlesfilter', + 'appname' => 'circles', + 'script' => 'files/list.php', + 'order' => 25, + 'name' => $l->t('Shared to Circles'), + ]; + } + ); + } + } diff --git a/lib/Db/CircleProviderRequest.php b/lib/Db/CircleProviderRequest.php new file mode 100644 index 000000000..5b5af1b2e --- /dev/null +++ b/lib/Db/CircleProviderRequest.php @@ -0,0 +1,106 @@ + + * @copyright 2017 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + + +namespace OCA\Circles\Db; + + +use OCA\Circles\Model\Member; + +class CircleProviderRequest extends CircleProviderRequestBuilder { + + + /** + * @param $userId + * @param $circleUniqueIds + * @param $limit + * @param $offset + * + * @return array + */ + public function getFilesForCircles($userId, $circleUniqueIds, $limit, $offset) { + + $qb = $this->getCompleteSelectSql(); + $this->linkToFileCache($qb, $userId); + $this->limitToPage($qb, $limit, $offset); + $this->limitToCircles($qb, $circleUniqueIds); + + $this->linkToMember($qb, $userId, $this->configService->isLinkedGroupsAllowed()); + + $this->leftJoinShareInitiator($qb); + $cursor = $qb->execute(); + + $object_ids = []; + while ($data = $cursor->fetch()) { + + if ($data['initiator_circle_level'] < Member::LEVEL_MEMBER + && ($data['initiator_group_level'] < Member::LEVEL_MEMBER + || !$this->configService->isLinkedGroupsAllowed()) + ) { + continue; + } + + self::editShareFromParentEntry($data); + if (self::isAccessibleResult($data)) { + $object_ids[] = $data['file_source']; + } + } + $cursor->closeCursor(); + + return $object_ids; + } + + + /** + * Returns whether the given database result can be interpreted as + * a share with accessible file (not trashed, not deleted) + * + * @param $data + *F + * + * @return bool + */ + protected static function isAccessibleResult($data) { + if ($data['fileid'] === null) { + return false; + } + + return (!(explode('/', $data['path'], 2)[0] !== 'files' + && explode(':', $data['storage_string_id'], 2)[0] === 'home')); + } + + + /** + * @param $data + */ + protected static function editShareFromParentEntry(&$data) { + if ($data['parent_id'] > 0) { + $data['permissions'] = $data['parent_perms']; + $data['file_target'] = $data['parent_target']; + } + } + +} \ No newline at end of file diff --git a/lib/Db/CircleProviderRequestBuilder.php b/lib/Db/CircleProviderRequestBuilder.php index 75141faec..0e5d06b3b 100644 --- a/lib/Db/CircleProviderRequestBuilder.php +++ b/lib/Db/CircleProviderRequestBuilder.php @@ -7,6 +7,9 @@ * later. See the COPYING file. * * @author Maxence Lange + * @author Vinicius Cubas Brand + * @author Daniel Tygel + * * @copyright 2017 * @license GNU AGPL version 3 or any later version * @@ -32,15 +35,10 @@ use OCA\Circles\Model\Circle; use OCA\Circles\Model\Member; use OCP\DB\QueryBuilder\IQueryBuilder; -use OCP\IDBConnection; use OCP\Share; use OCP\Share\IShare; -class CircleProviderRequestBuilder { - - - /** @var IDBConnection */ - protected $dbConnection; +class CircleProviderRequestBuilder extends CoreRequestBuilder { /** @@ -55,7 +53,7 @@ protected function findShareParentSql($fileId, $circleId) { $qb = $this->getBaseSelectSql(); $this->limitToShareParent($qb); - $this->limitToCircle($qb, $circleId); + $this->limitToCircles($qb, [$circleId]); $this->limitToFiles($qb, $fileId); return $qb; @@ -63,16 +61,25 @@ protected function findShareParentSql($fileId, $circleId) { /** - * Limit the request to a Circle. + * Limit the request to the given Circles. * * @param IQueryBuilder $qb - * @param int $circleId + * @param array $circleUniqueIds */ - protected function limitToCircle(IQueryBuilder &$qb, $circleId) { + protected function limitToCircles(IQueryBuilder &$qb, $circleUniqueIds) { + + if (!is_array($circleUniqueIds)) { + $circleUniqueIds = array($circleUniqueIds); + } + $expr = $qb->expr(); $pf = ($qb->getType() === QueryBuilder::SELECT) ? 's.' : ''; - - $qb->andWhere($expr->eq($pf . 'share_with', $qb->createNamedParameter($circleId))); + $qb->andWhere( + $expr->in( + $pf . 'share_with', + $qb->createNamedParameter($circleUniqueIds, IQueryBuilder::PARAM_STR_ARRAY) + ) + ); } diff --git a/lib/Service/CirclesService.php b/lib/Service/CirclesService.php index 9603c9806..0777893b5 100644 --- a/lib/Service/CirclesService.php +++ b/lib/Service/CirclesService.php @@ -6,6 +6,9 @@ * later. See the COPYING file. * * @author Maxence Lange + * @author Vinicius Cubas Brand + * @author Daniel Tygel + * * @copyright 2017 * @license GNU AGPL version 3 or any later version * @@ -29,16 +32,17 @@ use Exception; use OCA\Circles\AppInfo\Application; +use OCA\Circles\Db\CircleProviderRequest; use OCA\Circles\Db\CirclesRequest; use OCA\Circles\Db\FederatedLinksRequest; use OCA\Circles\Db\MembersRequest; use OCA\Circles\Exceptions\CircleAlreadyExistsException; use OCA\Circles\Exceptions\CircleTypeDisabledException; use OCA\Circles\Exceptions\FederatedCircleNotAllowedException; -use OCA\Circles\Exceptions\MemberDoesNotExistException; use OCA\Circles\Exceptions\MemberIsNotOwnerException; use OCA\Circles\Model\Circle; use OCA\Circles\Model\Member; +use OCA\Circles\ShareByCircleProvider; use OCP\IL10N; class CirclesService { @@ -64,6 +68,9 @@ class CirclesService { /** @var EventsService */ private $eventsService; + /** @var CircleProviderRequest */ + private $circleProviderRequest; + /** @var MiscService */ private $miscService; @@ -78,6 +85,7 @@ class CirclesService { * @param MembersRequest $membersRequest * @param FederatedLinksRequest $federatedLinksRequest * @param EventsService $eventsService + * @param CircleProviderRequest $circleProviderRequest * @param MiscService $miscService */ public function __construct( @@ -88,6 +96,7 @@ public function __construct( MembersRequest $membersRequest, FederatedLinksRequest $federatedLinksRequest, EventsService $eventsService, + CircleProviderRequest $circleProviderRequest, MiscService $miscService ) { $this->userId = $userId; @@ -97,6 +106,7 @@ public function __construct( $this->membersRequest = $membersRequest; $this->federatedLinksRequest = $federatedLinksRequest; $this->eventsService = $eventsService; + $this->circleProviderRequest = $circleProviderRequest; $this->miscService = $miscService; } @@ -490,4 +500,24 @@ public static function getCircleIcon($type, $png = false) { return $urlGen->getAbsoluteURL($urlGen->imagePath(Application::APP_NAME, 'black_circle' . $ext)); } + + /** + * @param string $circleUniqueIds + * @param int $limit + * @param int $offset + * + * @return array + */ + public function getFilesForCircles($circleUniqueIds, $limit = -1, $offset = 0) { + if (!is_array($circleUniqueIds)) { + $circleUniqueIds = [$circleUniqueIds]; + } + + $objectIds = $this->circleProviderRequest->getFilesForCircles( + $this->userId, $circleUniqueIds, $limit, $offset + ); + + return $objectIds; + } + } \ No newline at end of file diff --git a/lib/ShareByCircleProvider.php b/lib/ShareByCircleProvider.php index b7cf447f5..7bba8a5f8 100644 --- a/lib/ShareByCircleProvider.php +++ b/lib/ShareByCircleProvider.php @@ -6,6 +6,9 @@ * later. See the COPYING file. * * @author Maxence Lange + * @author Vinicius Cubas Brand + * @author Daniel Tygel + * * @copyright 2017 * @license GNU AGPL version 3 or any later version * @@ -33,7 +36,7 @@ use OC\Share20\Share; use OCA\Circles\Api\v1\Circles; use OCA\Circles\AppInfo\Application; -use OCA\Circles\Db\CircleProviderRequestBuilder; +use OCA\Circles\Db\CircleProviderRequest; use OCA\Circles\Db\CirclesRequest; use OCA\Circles\Db\MembersRequest; use OCA\Circles\Model\Circle; @@ -55,10 +58,8 @@ use OCP\Share\IShare; use OCP\Share\IShareProvider; -class ShareByCircleProvider extends CircleProviderRequestBuilder implements IShareProvider { - /** @var IDBConnection */ - protected $dbConnection; +class ShareByCircleProvider extends CircleProviderRequest implements IShareProvider { /** @var ILogger */ private $logger; @@ -72,9 +73,6 @@ class ShareByCircleProvider extends CircleProviderRequestBuilder implements ISha /** @var IRootFolder */ private $rootFolder; - /** @var IL10N */ - private $l10n; - /** @var IURLGenerator */ private $urlGenerator; @@ -84,12 +82,6 @@ class ShareByCircleProvider extends CircleProviderRequestBuilder implements ISha /** @var MembersRequest */ private $membersRequest; - /** @var ConfigService */ - private $configService; - - /** @var MiscService */ - private $miscService; - /** * DefaultShareProvider constructor. @@ -106,23 +98,20 @@ public function __construct( IDBConnection $connection, ISecureRandom $secureRandom, IUserManager $userManager, IRootFolder $rootFolder, IL10N $l10n, ILogger $logger, IURLGenerator $urlGenerator ) { - $this->dbConnection = $connection; + $app = new Application(); + $container = $app->getContainer(); + $configService = $container->query(ConfigService::class); + $miscService = $container->query(MiscService::class); + + parent::__construct($l10n, $connection, $configService, $miscService); + $this->secureRandom = $secureRandom; $this->userManager = $userManager; $this->rootFolder = $rootFolder; - $this->l10n = $l10n; $this->logger = $logger; $this->urlGenerator = $urlGenerator; - - $app = new Application(); - $this->circlesRequest = $app->getContainer() - ->query(CirclesRequest::class); - $this->membersRequest = $app->getContainer() - ->query(MembersRequest::class); - $this->configService = $app->getContainer() - ->query(ConfigService::class); - $this->miscService = $app->getContainer() - ->query(MiscService::class); + $this->circlesRequest = $container->query(CirclesRequest::class); + $this->membersRequest = $container->query(MembersRequest::class); } @@ -449,11 +438,11 @@ public function getSharedWith($userId, $shareType, $node, $limit, $offset) { /** - * @param $userId + * @param string $userId * @param $shareType - * @param $node - * @param $limit - * @param $offset + * @param Node $node + * @param int $limit + * @param int $offset * * @return IShare[] */ @@ -492,16 +481,6 @@ private function getSharedWithCircleMembers($userId, $shareType, $node, $limit, return $shares; } - /** - * @param $data - */ - private static function editShareFromParentEntry(&$data) { - if ($data['parent_id'] > 0) { - $data['permissions'] = $data['parent_perms']; - $data['file_target'] = $data['parent_target']; - } - } - /** * Get a share by token @@ -667,25 +646,6 @@ private function assignShareObjectSharesProperties(IShare &$share, $data) { } - /** - * Returns whether the given database result can be interpreted as - * a share with accessible file (not trashed, not deleted) - * - * @param $data - *F - * - * @return bool - */ - private static function isAccessibleResult($data) { - if ($data['fileid'] === null) { - return false; - } - - return (!(explode('/', $data['path'], 2)[0] !== 'files' - && explode(':', $data['storage_string_id'], 2)[0] === 'home')); - } - - /** * @param IShare $share * diff --git a/templates/files/list.php b/templates/files/list.php new file mode 100644 index 000000000..841ce7b5b --- /dev/null +++ b/templates/files/list.php @@ -0,0 +1,38 @@ +
+
+ + + + + + + + + + + + + + + + + +
+ +