Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,26 @@ In non-SSL environments (like on development setups) it is necessary to set two

`./occ config:app:set circles --value 1 local_is_non_ssl`

## Allow mirroring circles as groups

```bash
./occ maintenance:mode --on

./occ config:app:set circles --value 1 group_backend # Mirroring circles as groups
./occ config:app:set circles --value 0 allow_listed_circles # Hide circles in shared list, useful with the 'group_backend' option

# ./occ config:app:set circles --value "🌀 " group_backend_name_prefix # You can customize group name prefix
# ./occ config:app:set circles --value " " group_backend_name_suffix # Remove default group name suffix with a `space` character

./occ config:app:set circles --value 12 allow_circles # Only show 'public' and 'closed' circles
./occ config:app:set circles --value 1 skip_invitation_to_closed_circles

./occ config:app:set circles --value 0 allow_files_filtered_by_circles # Disable files list filtering by circles in the 'files' application
./occ config:app:set circles --value 0 allow_adding_any_group_members # Adding group members only for groups where the current user is a member or global administrators

./occ maintenance:mode --off
```

# Credits

App Icon by [Madebyoliver](http://www.flaticon.com/authors/madebyoliver) under Creative Commons BY 3.0
108 changes: 91 additions & 17 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,18 @@

namespace OCA\Circles\AppInfo;

use OC;
use OCA\Circles\Api\v1\Circles;
use OCA\Circles\Notification\Notifier;
use OCA\Circles\Service\ConfigService;
use OCA\Circles\Service\DavService;
use OCA\Circles\Service\GroupsBackendService;
use OCA\Files\App as FilesApp;
use OCP\App\ManagerEvent;
use OCP\AppFramework\App;
use OCP\AppFramework\IAppContainer;
use OCP\AppFramework\QueryException;
use OCP\IGroup;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Util;

require_once __DIR__ . '/../../appinfo/autoload.php';
Expand All @@ -56,22 +58,36 @@ class Application extends App {
/** @var IAppContainer */
private $container;

/** @var \OC\ServerServer */
private $server;

/** @var IEventDispatcher */
private $dispatcher;

/**
* @param array $params
*/
public function __construct(array $params = array()) {
parent::__construct(self::APP_NAME, $params);
}

public function register()
{
$this->container = $this->getContainer();
$this->server = $this->container->getServer();
$this->dispatcher = $this->server->query(IEventDispatcher::class);

$manager = OC::$server->getNotificationManager();
$manager = $this->server->getNotificationManager();
$manager->registerNotifierService(Notifier::class);

$this->registerNavigation();
$this->registerFilesNavigation();
$this->registerFilesPlugin();
$this->registerHooks();
$this->registerDavHooks();
$this->registerGroupsBackendHooks();
}


/**
* Register Hooks
*/
Expand All @@ -91,7 +107,7 @@ public function registerHooks() {
public function registerNavigation() {
/** @var ConfigService $configService */
try {
$configService = OC::$server->query(ConfigService::class);
$configService = $this->server->query(ConfigService::class);
} catch (QueryException $e) {
return;
}
Expand All @@ -104,8 +120,8 @@ public function registerNavigation() {
->getNavigationManager();
$appManager->add(
function() {
$urlGen = OC::$server->getURLGenerator();
$navName = OC::$server->getL10N(self::APP_NAME)
$urlGen = $this->server->getURLGenerator();
$navName = $this->server->getL10N(self::APP_NAME)
->t('Circles');

return [
Expand All @@ -121,8 +137,17 @@ function() {
}

public function registerFilesPlugin() {
$eventDispatcher = OC::$server->getEventDispatcher();
$eventDispatcher->addListener(
try {
/** @var ConfigService $configService */
$configService = $this->server->query(ConfigService::class);
if (!$configService->isFilesFilteredCirclesAllowed()) {
return;
}
} catch (QueryException $e) {
return;
}

$this->dispatcher->addListener(
'OCA\Files::loadAdditionalScripts',
function() {
Circles::addJavascriptAPI();
Expand All @@ -140,10 +165,20 @@ function() {
*
*/
public function registerFilesNavigation() {
try {
/** @var ConfigService $configService */
$configService = $this->server->query(ConfigService::class);
if (!$configService->isFilesFilteredCirclesAllowed()) {
return;
}
} catch (QueryException $e) {
return;
}

$appManager = FilesApp::getNavigationManager();
$appManager->add(
function() {
$l = OC::$server->getL10N('circles');
$l = $this->server->getL10N('circles');

return [
'id' => 'circlesfilter',
Expand All @@ -160,24 +195,63 @@ function() {
public function registerDavHooks() {
try {
/** @var ConfigService $configService */
$configService = OC::$server->query(ConfigService::class);
$configService = $this->server->query(ConfigService::class);
if (!$configService->isContactsBackend()) {
return;
}

/** @var DavService $davService */
$davService = OC::$server->query(DavService::class);
$davService = $this->server->query(DavService::class);
} catch (QueryException $e) {
return;
}

$event = OC::$server->getEventDispatcher();
$this->dispatcher->addListener(ManagerEvent::EVENT_APP_ENABLE, [$davService, 'onAppEnabled']);
$this->dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::createCard', [$davService, 'onCreateCard']);
$this->dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::updateCard', [$davService, 'onUpdateCard']);
$this->dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::deleteCard', [$davService, 'onDeleteCard']);
}

$event->addListener(ManagerEvent::EVENT_APP_ENABLE, [$davService, 'onAppEnabled']);
$event->addListener('\OCA\DAV\CardDAV\CardDavBackend::createCard', [$davService, 'onCreateCard']);
$event->addListener('\OCA\DAV\CardDAV\CardDavBackend::updateCard', [$davService, 'onUpdateCard']);
$event->addListener('\OCA\DAV\CardDAV\CardDavBackend::deleteCard', [$davService, 'onDeleteCard']);
public function registerGroupsBackendHooks() {
try {
/** @var ConfigService $configService */
$configService = $this->server->query(ConfigService::class);
if (!$configService->isGroupsBackend()) {
return;
}

/** @var GroupsBackendService $groupsBackendService */
$groupsBackendService = $this->server->query(GroupsBackendService::class);
} catch (QueryException $e) {
return;
}

$this->dispatcher->addListener(ManagerEvent::EVENT_APP_ENABLE, [$groupsBackendService, 'onAppEnabled']);
$this->dispatcher->addListener('\OCA\Circles::onCircleCreation', [$groupsBackendService, 'onCircleCreation']);
$this->dispatcher->addListener('\OCA\Circles::onCircleDestruction', [$groupsBackendService, 'onCircleDestruction']);
$this->dispatcher->addListener('\OCA\Circles::onMemberNew', [$groupsBackendService, 'onMemberNew']);
$this->dispatcher->addListener('\OCA\Circles::onMemberInvited', [$groupsBackendService, 'onMemberInvited']);
$this->dispatcher->addListener('\OCA\Circles::onMemberRequesting', [$groupsBackendService, 'onMemberRequesting']);
$this->dispatcher->addListener('\OCA\Circles::onMemberLeaving', [$groupsBackendService, 'onMemberLeaving']);
$this->dispatcher->addListener('\OCA\Circles::onMemberLevel', [$groupsBackendService, 'onMemberLevel']);
$this->dispatcher->addListener('\OCA\Circles::onMemberOwner', [$groupsBackendService, 'onMemberOwner']);
$this->dispatcher->addListener('\OCA\Circles::onGroupLink', [$groupsBackendService, 'onGroupLink']);
$this->dispatcher->addListener('\OCA\Circles::onGroupUnlink', [$groupsBackendService, 'onGroupUnlink']);
$this->dispatcher->addListener('\OCA\Circles::onGroupLevel', [$groupsBackendService, 'onGroupLevel']);
$this->dispatcher->addListener('\OCA\Circles::onLinkRequestSent', [$groupsBackendService, 'onLinkRequestSent']);
$this->dispatcher->addListener('\OCA\Circles::onLinkRequestReceived', [$groupsBackendService, 'onLinkRequestReceived']);
$this->dispatcher->addListener('\OCA\Circles::onLinkRequestRejected', [$groupsBackendService, 'onLinkRequestRejected']);
$this->dispatcher->addListener('\OCA\Circles::onLinkRequestCanceled', [$groupsBackendService, 'onLinkRequestCanceled']);
$this->dispatcher->addListener('\OCA\Circles::onLinkRequestAccepted', [$groupsBackendService, 'onLinkRequestAccepted']);
$this->dispatcher->addListener('\OCA\Circles::onLinkRequestAccepting', [$groupsBackendService, 'onLinkRequestAccepting']);
$this->dispatcher->addListener('\OCA\Circles::onLinkUp', [$groupsBackendService, 'onLinkUp']);
$this->dispatcher->addListener('\OCA\Circles::onLinkDown', [$groupsBackendService, 'onLinkDown']);
$this->dispatcher->addListener('\OCA\Circles::onLinkRemove', [$groupsBackendService, 'onLinkRemove']);
$this->dispatcher->addListener('\OCA\Circles::onSettingsChange', [$groupsBackendService, 'onSettingsChange']);

$this->dispatcher->addListener(IGroup::class . '::postAddUser', [$groupsBackendService, 'onGroupPostAddUser']);
$this->dispatcher->addListener(IGroup::class . '::postRemoveUser', [$groupsBackendService, 'onGroupPostRemoveUser']);
$this->dispatcher->addListener(IGroup::class . '::postDelete', [$groupsBackendService, 'onGroupPostDelete']);
}

}

33 changes: 32 additions & 1 deletion lib/Db/CirclesRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,36 @@ public function forceGetCircleByName($name) {
}


/**
* forceGetCircleByGroupId();
*
* returns data of a circle from its Group ID.
*
* WARNING: This function does not filters data regarding the current user/viewer.
* In case of interaction with users, do not use this method.
*
* @param $groupId
*
* @return null|Circle
*/
public function forceGetCircleByGroupId($groupId) {
$qb = $this->getCirclesSelectSql();

$this->limitToGroupId($qb, $groupId);

$cursor = $qb->execute();
$data = $cursor->fetch();
$cursor->closeCursor();

if ($data === false) {
return null;
}

$entry = $this->parseCirclesSelectSql($data);

return $entry;
}

/**
* @param string $userId
* @param int $type
Expand Down Expand Up @@ -331,7 +361,8 @@ public function updateCircle(Circle $circle, $userId) {
$qb = $this->getCirclesUpdateSql($circle->getUniqueId(true));
$qb->set('name', $qb->createNamedParameter($circle->getName()))
->set('description', $qb->createNamedParameter($circle->getDescription()))
->set('settings', $qb->createNamedParameter($circle->getSettings(true)));
->set('settings', $qb->createNamedParameter($circle->getSettings(true)))
->set('group_id', $qb->createNamedParameter($circle->getGroupId()));

$qb->execute();
}
Expand Down
3 changes: 2 additions & 1 deletion lib/Db/CirclesRequestBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ protected function getCirclesSelectSql() {
$qb->selectDistinct('c.unique_id')
->addSelect(
'c.id', 'c.name', 'c.description', 'c.settings', 'c.type', 'contact_addressbook',
'contact_groupname', 'c.creation'
'contact_groupname', 'c.creation', 'c.group_id'
)
->from(CoreRequestBuilder::TABLE_CIRCLES, 'c');
$this->default_select_alias = 'c';
Expand All @@ -419,6 +419,7 @@ protected function parseCirclesSelectSql($data) {
if ($data['contact_groupname'] !== null) {
$circle->setContactGroupName($data['contact_groupname']);
}
$circle->setGroupId($data['group_id']);
$circle->setSettings($data['settings']);
$circle->setType($data['type']);
$circle->setCreation($data['creation']);
Expand Down
9 changes: 8 additions & 1 deletion lib/Db/MembersRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,14 @@ public function unlinkAllFromGroup($groupId) {
}


public function unlinkFromGroup($circleId, $groupId) {
$qb = $this->getGroupsDeleteSql($groupId);
$this->limitToCircleId($qb, $circleId);

$qb->execute();
}


/**
* @param string $contactId
*
Expand Down Expand Up @@ -731,4 +739,3 @@ public function removeMembersByContactId(string $contactId, int $type = 0) {


}

81 changes: 81 additions & 0 deletions lib/Migration/Version0017Date20200221173726.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php
/**
* 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 <[email protected]>
* @copyright 2019
* @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 <http://www.gnu.org/licenses/>.
*
*/

declare(strict_types=1);

namespace OCA\Circles\Migration;

use Closure;
use Doctrine\DBAL\Schema\SchemaException;
use Doctrine\DBAL\Types\Type;
use OCP\DB\ISchemaWrapper;
use OCP\IDBConnection;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;

/**
* Auto-generated migration step: Please modify to your needs!
*/
class Version0017Date20200221173726 extends SimpleMigrationStep {


/** @var IDBConnection */
private $connection;


/**
* @param IDBConnection $connection
*/
public function __construct(IDBConnection $connection) {
$this->connection = $connection;
}


/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
*
* @return null|ISchemaWrapper
* @throws SchemaException
*/
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();

$table = $schema->getTable('circles_circles');
$table->addColumn(
'group_id', 'string', [
'notnull' => false,
'default' => '',
'length' => 64,
]
);

return $schema;
}

}
Loading