summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLouis <6653109+artonge@users.noreply.github.com>2023-01-25 17:34:58 +0100
committerGitHub <noreply@github.com>2023-01-25 17:34:58 +0100
commitc0089cb4e4166aadc539ecd6b1d2b695529c1daa (patch)
treee2aa0077901662fc1f8f6ba2b8367a15a7596086
parente209f7b3eda1034cb6ba8923e17580d68013a825 (diff)
parentc2ac203888f05082742ccfda2f8959b03cd3c1db (diff)
Merge pull request #1601 from simonspa/devv26.0.0beta1
Correctly listen to group change events
-rw-r--r--lib/Album/AlbumMapper.php64
-rw-r--r--lib/AppInfo/Application.php10
-rw-r--r--lib/Listener/GroupDeletedListener.php47
-rw-r--r--lib/Listener/GroupUserRemovedListener.php34
4 files changed, 146 insertions, 9 deletions
diff --git a/lib/Album/AlbumMapper.php b/lib/Album/AlbumMapper.php
index 815238b9..613562e4 100644
--- a/lib/Album/AlbumMapper.php
+++ b/lib/Album/AlbumMapper.php
@@ -273,6 +273,22 @@ class AlbumMapper {
$query->executeStatement();
}
+ public function removeFilesForUser(int $albumId, string $userId) {
+ // Remove all photos by this user from the album:
+ $query = $this->connection->getQueryBuilder();
+ $query->delete('photos_albums_files')
+ ->where($query->expr()->eq('album_id', $query->createNamedParameter($albumId, IQueryBuilder::PARAM_INT)))
+ ->andWhere($query->expr()->eq('owner', $query->createNamedParameter($userId)))
+ ->executeStatement();
+
+ // Update the last added photo:
+ $query = $this->connection->getQueryBuilder();
+ $query->update("photos_albums")
+ ->set('last_added_photo', $query->createNamedParameter($this->getLastAdded($albumId), IQueryBuilder::PARAM_INT))
+ ->where($query->expr()->eq('album_id', $query->createNamedParameter($albumId, IQueryBuilder::PARAM_INT)))
+ ->executeStatement();
+ }
+
private function getLastAdded(int $albumId): int {
$query = $this->connection->getQueryBuilder();
$query->select("file_id")
@@ -430,6 +446,34 @@ class AlbumMapper {
/**
* @param string $collaboratorId
+ * @param int $collaboratorType
+ * @return AlbumInfo[]
+ */
+ public function getSharedAlbumsForCollaborator(string $collaboratorId, int $collaboratorType): array {
+ $query = $this->connection->getQueryBuilder();
+ $rows = $query
+ ->select("a.album_id", "name", "user", "location", "created", "last_added_photo")
+ ->from("photos_albums_collabs", "c")
+ ->leftJoin("c", "photos_albums", "a", $query->expr()->eq("a.album_id", "c.album_id"))
+ ->where($query->expr()->eq('collaborator_id', $query->createNamedParameter($collaboratorId)))
+ ->andWhere($query->expr()->eq('collaborator_type', $query->createNamedParameter($collaboratorType, IQueryBuilder::PARAM_INT)))
+ ->executeQuery()
+ ->fetchAll();
+
+ return array_map(function (array $row) {
+ return new AlbumInfo(
+ (int)$row['album_id'],
+ $row['user'],
+ $row['name'].' ('.$row['user'].')',
+ $row['location'],
+ (int)$row['created'],
+ (int)$row['last_added_photo']
+ );
+ }, $rows);
+ }
+
+ /**
+ * @param string $collaboratorId
* @param string $collaboratorsType - The type of the collaborator, either a user or a group.
* @return AlbumWithFiles[]
*/
@@ -483,7 +527,6 @@ class AlbumMapper {
* @return void
*/
public function deleteUserFromAlbumCollaboratorsList(string $userId, int $albumId): void {
- // TODO: only delete if this was not a group share
$query = $this->connection->getQueryBuilder();
$query->delete('photos_albums_collabs')
->where($query->expr()->eq('album_id', $query->createNamedParameter($albumId, IQueryBuilder::PARAM_INT)))
@@ -492,17 +535,20 @@ class AlbumMapper {
->executeStatement();
// Remove all photos by this user from the album:
- $query = $this->connection->getQueryBuilder();
- $query->delete('photos_albums_files')
- ->where($query->expr()->eq('album_id', $query->createNamedParameter($albumId, IQueryBuilder::PARAM_INT)))
- ->andWhere($query->expr()->eq('owner', $query->createNamedParameter($userId)))
- ->executeStatement();
+ $this->removeFilesForUser($albumId, $userId);
+ }
- // Update the last added photo:
+ /**
+ * @param string $groupId
+ * @param int $albumId
+ * @return void
+ */
+ public function deleteGroupFromAlbumCollaboratorsList(string $groupId, int $albumId): void {
$query = $this->connection->getQueryBuilder();
- $query->update("photos_albums")
- ->set('last_added_photo', $query->createNamedParameter($this->getLastAdded($albumId), IQueryBuilder::PARAM_INT))
+ $query->delete('photos_albums_collabs')
->where($query->expr()->eq('album_id', $query->createNamedParameter($albumId, IQueryBuilder::PARAM_INT)))
+ ->andWhere($query->expr()->eq('collaborator_id', $query->createNamedParameter($groupId)))
+ ->andWhere($query->expr()->eq('collaborator_type', $query->createNamedParameter(self::TYPE_GROUP, IQueryBuilder::PARAM_INT)))
->executeStatement();
}
diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php
index f3e9fbc3..11507922 100644
--- a/lib/AppInfo/Application.php
+++ b/lib/AppInfo/Application.php
@@ -29,11 +29,15 @@ use OCA\DAV\Events\SabrePluginAuthInitEvent;
use OCA\Photos\Listener\SabrePluginAuthInitListener;
use OCA\DAV\Connector\Sabre\Principal;
use OCA\Photos\Listener\NodeDeletedListener;
+use OCA\Photos\Listener\GroupUserRemovedListener;
+use OCA\Photos\Listener\GroupDeletedListener;
use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\Files\Events\Node\NodeDeletedEvent;
+use OCP\Group\Events\UserRemovedEvent;
+use OCP\Group\Events\GroupDeletedEvent;
class Application extends App implements IBootstrap {
public const APP_ID = 'photos';
@@ -65,7 +69,13 @@ class Application extends App implements IBootstrap {
public function register(IRegistrationContext $context): void {
/** Register $principalBackend for the DAV collection */
$context->registerServiceAlias('principalBackend', Principal::class);
+
$context->registerEventListener(NodeDeletedEvent::class, NodeDeletedListener::class);
+
+ $context->registerEventListener(UserRemovedEvent::class, GroupUserRemovedListener::class);
+
+ $context->registerEventListener(GroupDeletedEvent::class, GroupDeletedListener::class);
+
$context->registerEventListener(SabrePluginAuthInitEvent::class, SabrePluginAuthInitListener::class);
}
diff --git a/lib/Listener/GroupDeletedListener.php b/lib/Listener/GroupDeletedListener.php
new file mode 100644
index 00000000..6a2f45c1
--- /dev/null
+++ b/lib/Listener/GroupDeletedListener.php
@@ -0,0 +1,47 @@
+<?php
+
+namespace OCA\Photos\Listener;
+
+use OCA\Photos\Album\AlbumMapper;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+use OCP\Group\Events\GroupDeletedEvent;
+
+class GroupDeletedListener implements IEventListener {
+ private AlbumMapper $albumMapper;
+
+ public function __construct(AlbumMapper $albumMapper) {
+ $this->albumMapper = $albumMapper;
+ }
+
+ public function handle(Event $event): void {
+ if (!($event instanceof GroupDeletedEvent)) {
+ return;
+ }
+
+ // Get all shared albums for this group:
+ $albums_group = $this->albumMapper->getSharedAlbumsForCollaborator($event->getGroup()->getGID(), AlbumMapper::TYPE_GROUP);
+
+ // Get all users of this group:
+ $users = $event->getGroup()->getUsers();
+
+ foreach ($users as $user) {
+ $uid = $user->getUID();
+
+ // Get all albums shared with this specific user:
+ $albums_user = $this->albumMapper->getSharedAlbumsForCollaborator($user->getUID(), AlbumMapper::TYPE_USER);
+
+ // Get all group-shared albums that are not directly shared with the removed user in addition
+ $albums = array_udiff($albums_group, $albums_user, fn ($a, $b) => ($a->getId() - $b->getId()));
+
+ // Remove their photos from theses albums:
+ foreach ($albums as $album) {
+ $this->albumMapper->removeFilesForUser($album->getId(), $user->getUID());
+ }
+ }
+
+ foreach ($albums_group as $album) {
+ $this->albumMapper->deleteGroupFromAlbumCollaboratorsList($event->getGroup()->getGID(), $album->getId());
+ }
+ }
+}
diff --git a/lib/Listener/GroupUserRemovedListener.php b/lib/Listener/GroupUserRemovedListener.php
new file mode 100644
index 00000000..141b5516
--- /dev/null
+++ b/lib/Listener/GroupUserRemovedListener.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace OCA\Photos\Listener;
+
+use OCA\Photos\Album\AlbumMapper;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+use OCP\Group\Events\UserRemovedEvent;
+
+class GroupUserRemovedListener implements IEventListener {
+ private AlbumMapper $albumMapper;
+
+ public function __construct(AlbumMapper $albumMapper) {
+ $this->albumMapper = $albumMapper;
+ }
+
+ public function handle(Event $event): void {
+ if (!($event instanceof UserRemovedEvent)) {
+ return;
+ }
+
+ // Get all shared albums for this group:
+ $albums_group = $this->albumMapper->getSharedAlbumsForCollaborator($event->getGroup()->getGID(), AlbumMapper::TYPE_GROUP);
+ // Get all albums shared with this specific user:
+ $albums_user = $this->albumMapper->getSharedAlbumsForCollaborator($event->getUser()->getUID(), AlbumMapper::TYPE_USER);
+ // Get all group-shared albums that are not directly shared with the removed user in addition
+ $albums = array_udiff($albums_group, $albums_user, fn ($a, $b) => ($a->getId() - $b->getId()));
+
+ // Remove their photos from theses albums:
+ foreach ($albums as $album) {
+ $this->albumMapper->removeFilesForUser($album->getId(), $event->getUser()->getUID());
+ }
+ }
+}