Skip to content

Commit f5ddfa8

Browse files
committed
Listen to more events for albums
Signed-off-by: Louis Chemineau <[email protected]>
1 parent abc4f5f commit f5ddfa8

File tree

4 files changed

+97
-30
lines changed

4 files changed

+97
-30
lines changed

lib/Album/AlbumMapper.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,33 @@ public function removeFile(int $albumId, int $fileId): void {
273273
$query->executeStatement();
274274
}
275275

276+
public function removeFileWithOwner(int $fileId, string $ownerId): void {
277+
// Get concerned albums before deleting them.
278+
$query = $this->connection->getQueryBuilder();
279+
$albumsRows = $query->select('album_id')
280+
->from("photos_albums_files")
281+
->where($query->expr()->eq("owner_id", $query->createNamedParameter($ownerId)))
282+
->andWhere($query->expr()->eq("file_id", $query->createNamedParameter($fileId, IQueryBuilder::PARAM_INT)))
283+
->executeQuery()
284+
->fetchAll();
285+
286+
// Remove any occurrence of fileId when owner is ownerId.
287+
$query = $this->connection->getQueryBuilder();
288+
$query->delete("photos_albums_files")
289+
->where($query->expr()->eq("owner_id", $query->createNamedParameter($ownerId)))
290+
->andWhere($query->expr()->eq("file_id", $query->createNamedParameter($fileId, IQueryBuilder::PARAM_INT)))
291+
->executeStatement();
292+
293+
// Update last_added_photo for concerned albums.
294+
foreach ($albumsRows as $row) {
295+
$query = $this->connection->getQueryBuilder();
296+
$query->update("photos_albums")
297+
->set('last_added_photo', $query->createNamedParameter($this->getLastAdded($row['album_id']), IQueryBuilder::PARAM_INT))
298+
->where($query->expr()->eq('album_id', $query->createNamedParameter($row['album_id'], IQueryBuilder::PARAM_INT)));
299+
$query->executeStatement();
300+
}
301+
}
302+
276303
private function getLastAdded(int $albumId): int {
277304
$query = $this->connection->getQueryBuilder();
278305
$query->select("file_id")

lib/AppInfo/Application.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,14 @@
2828
use OCA\DAV\Events\SabrePluginAuthInitEvent;
2929
use OCA\Photos\Listener\SabrePluginAuthInitListener;
3030
use OCA\DAV\Connector\Sabre\Principal;
31-
use OCA\Photos\Listener\CacheEntryRemovedListener;
31+
use OCA\Photos\Listener\AlbumsManagementFileEventListener;
3232
use OCP\AppFramework\App;
3333
use OCP\AppFramework\Bootstrap\IBootContext;
3434
use OCP\AppFramework\Bootstrap\IBootstrap;
3535
use OCP\AppFramework\Bootstrap\IRegistrationContext;
3636
use OCP\Files\Cache\CacheEntryRemovedEvent;
37+
use OCP\Share\Events\ShareDeletedEvent;
38+
use OCP\User\Events\UserDeletedEvent;
3739

3840
class Application extends App implements IBootstrap {
3941
public const APP_ID = 'photos';
@@ -65,7 +67,9 @@ public function __construct() {
6567
public function register(IRegistrationContext $context): void {
6668
/** Register $principalBackend for the DAV collection */
6769
$context->registerServiceAlias('principalBackend', Principal::class);
68-
$context->registerEventListener(CacheEntryRemovedEvent::class, CacheEntryRemovedListener::class);
70+
$context->registerEventListener(CacheEntryRemovedEvent::class, AlbumsManagementFileEventListener::class);
71+
$context->registerEventListener(UserDeletedEvent::class, AlbumsManagementFileEventListener::class);
72+
$context->registerEventListener(ShareDeletedEvent::class, AlbumsManagementFileEventListener::class);
6973
$context->registerEventListener(SabrePluginAuthInitEvent::class, SabrePluginAuthInitListener::class);
7074
}
7175

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
namespace OCA\Photos\Listener;
4+
5+
use OCA\Photos\Album\AlbumMapper;
6+
use OCP\Files\File;
7+
use OCP\Files\Folder;
8+
use OCP\Files\Node;
9+
use OCP\EventDispatcher\Event;
10+
use OCP\EventDispatcher\IEventListener;
11+
use OCP\Files\Cache\CacheEntryRemovedEvent;
12+
use OCP\Share\Events\ShareDeletedEvent;
13+
use OCP\User\Events\UserDeletedEvent;
14+
15+
class AlbumsManagementFileEventListener implements IEventListener {
16+
private AlbumMapper $albumMapper;
17+
18+
public function __construct(AlbumMapper $albumMapper) {
19+
$this->albumMapper = $albumMapper;
20+
}
21+
22+
public function handle(Event $event): void {
23+
if ($event instanceof CacheEntryRemovedEvent) {
24+
// Remove node from all albums containing it.
25+
$albums = $this->albumMapper->getForFile($event->getFileId());
26+
foreach ($albums as $album) {
27+
$this->albumMapper->removeFile($album->getId(), $event->getFileId());
28+
}
29+
}
30+
31+
if ($event instanceof UserDeletedEvent) {
32+
// Delete all user's albums.
33+
$albums = $this->albumMapper->getForUser($event->getUser()->getUID());
34+
foreach ($albums as $album) {
35+
$this->albumMapper->delete($album->getId());
36+
}
37+
}
38+
39+
if ($event instanceof ShareDeletedEvent) {
40+
$receiverId = $event->getShare()->getSharedWith();
41+
$this->forEachSubNode(
42+
$event->getShare()->getNode(),
43+
// Remove node from any album when the owner is $receiverId.
44+
fn ($node) => $this->albumMapper->removeFileWithOwner($node->getId(), $receiverId),
45+
);
46+
}
47+
}
48+
49+
private function forEachSubNode(Node $node, callable $callback): void {
50+
if ($node instanceof Folder) {
51+
foreach ($node->getDirectoryListing() as $subNode) {
52+
$this->forEachSubNode($subNode, $callback);
53+
}
54+
}
55+
56+
if ($node instanceof File) {
57+
if (!str_starts_with($node->getMimeType(), 'image')) {
58+
return;
59+
}
60+
61+
$callback($node);
62+
}
63+
}
64+
}

lib/Listener/CacheEntryRemovedListener.php

Lines changed: 0 additions & 28 deletions
This file was deleted.

0 commit comments

Comments
 (0)