Files
nextcloud-pantry/lib/Service/PhotoService.php

211 lines
5.6 KiB
PHP

<?php
declare(strict_types=1);
// SPDX-FileCopyrightText: Chen Asraf <contact@casraf.dev>
// SPDX-License-Identifier: AGPL-3.0-or-later
namespace OCA\Pantry\Service;
use OCA\Pantry\Db\Photo;
use OCA\Pantry\Db\PhotoFolder;
use OCA\Pantry\Db\PhotoFolderMapper;
use OCA\Pantry\Db\PhotoMapper;
use OCA\Pantry\Exception\NotFoundException;
use OCP\AppFramework\Db\DoesNotExistException;
class PhotoService {
public function __construct(
private PhotoMapper $photoMapper,
private PhotoFolderMapper $folderMapper,
private ImageService $images,
) {
}
// ----- Folders -----
/**
* @return PhotoFolder[]
*/
public function listFolders(int $houseId, string $sortBy = 'custom'): array {
return $this->folderMapper->findByHouse($houseId, $sortBy);
}
public function getFolder(int $folderId): PhotoFolder {
try {
return $this->folderMapper->findById($folderId);
} catch (DoesNotExistException) {
throw new NotFoundException('Folder not found');
}
}
public function createFolder(int $houseId, string $name): PhotoFolder {
$name = trim($name);
if ($name === '') {
throw new \InvalidArgumentException('Folder name cannot be empty');
}
$now = time();
$folder = new PhotoFolder();
$folder->setHouseId($houseId);
$folder->setName($name);
$folder->setSortOrder(0);
$folder->setCreatedAt($now);
$folder->setUpdatedAt($now);
/** @var PhotoFolder $saved */
$saved = $this->folderMapper->insert($folder);
return $saved;
}
public function updateFolder(int $folderId, array $patch): PhotoFolder {
$folder = $this->getFolder($folderId);
if (isset($patch['name'])) {
$name = trim((string)$patch['name']);
if ($name === '') {
throw new \InvalidArgumentException('Folder name cannot be empty');
}
$folder->setName($name);
}
if (isset($patch['sortOrder'])) {
$folder->setSortOrder((int)$patch['sortOrder']);
}
$folder->setUpdatedAt(time());
$this->folderMapper->update($folder);
return $folder;
}
public function deleteFolder(int $folderId, bool $deleteContents = false, ?string $uid = null): void {
$folder = $this->getFolder($folderId);
if ($deleteContents) {
$photos = $this->photoMapper->findByFolder($folderId);
foreach ($photos as $photo) {
if ($uid !== null) {
$this->images->deleteFile($photo->getFileId(), $uid);
}
$this->photoMapper->delete($photo);
}
} else {
// Move all photos in this folder to the board root
$this->photoMapper->moveToRoot($folderId);
}
$this->folderMapper->delete($folder);
}
/**
* Batch reorder folders.
*
* @param array<array{id: int, sortOrder: int}> $items
*/
public function reorderFolders(int $houseId, array $items): void {
foreach ($items as $entry) {
$id = (int)($entry['id'] ?? 0);
$sortOrder = (int)($entry['sortOrder'] ?? 0);
if ($id <= 0) {
continue;
}
try {
$folder = $this->folderMapper->findById($id);
} catch (DoesNotExistException) {
continue;
}
if ($folder->getHouseId() !== $houseId) {
continue;
}
$folder->setSortOrder($sortOrder);
$folder->setUpdatedAt(time());
$this->folderMapper->update($folder);
}
}
// ----- Photos -----
/**
* @return Photo[]
*/
public function listPhotos(int $houseId, string $sortBy = 'custom'): array {
return $this->photoMapper->findByHouse($houseId, $sortBy);
}
/**
* @return Photo[]
*/
public function listPhotosByFolder(int $folderId, string $sortBy = 'custom'): array {
return $this->photoMapper->findByFolder($folderId, $sortBy);
}
public function getPhoto(int $photoId): Photo {
try {
return $this->photoMapper->findById($photoId);
} catch (DoesNotExistException) {
throw new NotFoundException('Photo not found');
}
}
public function addPhoto(int $houseId, string $uid, int $fileId, ?int $folderId, ?string $caption): Photo {
$now = time();
$photo = new Photo();
$photo->setHouseId($houseId);
$photo->setFolderId($folderId);
$photo->setFileId($fileId);
$photo->setCaption($caption !== null && trim($caption) !== '' ? trim($caption) : null);
$photo->setUploadedBy($uid);
$photo->setSortOrder(0);
$photo->setCreatedAt($now);
$photo->setUpdatedAt($now);
/** @var Photo $saved */
$saved = $this->photoMapper->insert($photo);
return $saved;
}
public function updatePhoto(int $photoId, array $patch): Photo {
$photo = $this->getPhoto($photoId);
if (array_key_exists('caption', $patch)) {
$caption = $patch['caption'];
$photo->setCaption(is_string($caption) && trim($caption) !== '' ? trim($caption) : null);
}
if (array_key_exists('folderId', $patch)) {
$fid = $patch['folderId'];
$photo->setFolderId(is_int($fid) && $fid > 0 ? $fid : null);
}
if (isset($patch['sortOrder'])) {
$photo->setSortOrder((int)$patch['sortOrder']);
}
$photo->setUpdatedAt(time());
$this->photoMapper->update($photo);
return $photo;
}
public function deletePhoto(int $photoId, ?string $uid = null): void {
$photo = $this->getPhoto($photoId);
if ($uid !== null) {
$this->images->deleteFile($photo->getFileId(), $uid);
}
$this->photoMapper->delete($photo);
}
/**
* Batch reorder photos.
*
* @param array<array{id: int, sortOrder: int}> $items
*/
public function reorderPhotos(int $houseId, array $items): void {
foreach ($items as $entry) {
$id = (int)($entry['id'] ?? 0);
$sortOrder = (int)($entry['sortOrder'] ?? 0);
if ($id <= 0) {
continue;
}
try {
$photo = $this->photoMapper->findById($id);
} catch (DoesNotExistException) {
continue;
}
if ($photo->getHouseId() !== $houseId) {
continue;
}
$photo->setSortOrder($sortOrder);
$photo->setUpdatedAt(time());
$this->photoMapper->update($photo);
}
}
}