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

126 lines
3.2 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\Note;
use OCA\Pantry\Db\NoteMapper;
use OCA\Pantry\Exception\NotFoundException;
use OCP\AppFramework\Db\DoesNotExistException;
class NoteService {
public function __construct(
private NoteMapper $noteMapper,
) {
}
/**
* @return Note[]
*/
public function listNotes(int $houseId, string $sortBy = 'custom'): array {
return $this->noteMapper->findByHouse($houseId, $sortBy);
}
public function getNote(int $noteId): Note {
try {
return $this->noteMapper->findById($noteId);
} catch (DoesNotExistException) {
throw new NotFoundException('Note not found');
}
}
public function createNote(int $houseId, string $uid, string $title, ?string $content, ?string $color): Note {
$title = trim($title);
if ($title === '') {
throw new \InvalidArgumentException('Note title cannot be empty');
}
if ($color !== null) {
$this->validateColor($color);
}
$now = time();
$note = new Note();
$note->setHouseId($houseId);
$note->setTitle($title);
$note->setContent($content !== null && trim($content) !== '' ? $content : null);
$note->setColor($color);
$note->setCreatedBy($uid);
$note->setSortOrder(0);
$note->setCreatedAt($now);
$note->setUpdatedAt($now);
/** @var Note $saved */
$saved = $this->noteMapper->insert($note);
return $saved;
}
public function updateNote(int $noteId, array $patch): Note {
$note = $this->getNote($noteId);
if (isset($patch['title'])) {
$title = trim((string)$patch['title']);
if ($title === '') {
throw new \InvalidArgumentException('Note title cannot be empty');
}
$note->setTitle($title);
}
if (array_key_exists('content', $patch)) {
$c = $patch['content'];
$note->setContent(is_string($c) && trim($c) !== '' ? $c : null);
}
if (array_key_exists('color', $patch)) {
$color = $patch['color'];
if ($color !== null && $color !== '') {
$this->validateColor((string)$color);
$note->setColor((string)$color);
} else {
$note->setColor(null);
}
}
if (isset($patch['sortOrder'])) {
$note->setSortOrder((int)$patch['sortOrder']);
}
$note->setUpdatedAt(time());
$this->noteMapper->update($note);
return $note;
}
public function deleteNote(int $noteId): void {
$note = $this->getNote($noteId);
$this->noteMapper->delete($note);
}
/**
* Batch reorder notes.
*
* @param list<array{id: int, sortOrder: int}> $items
*/
public function reorderNotes(int $houseId, array $items): void {
foreach ($items as $entry) {
$id = (int)($entry['id'] ?? 0);
$sortOrder = (int)($entry['sortOrder'] ?? 0);
if ($id <= 0) {
continue;
}
try {
$note = $this->noteMapper->findById($id);
} catch (DoesNotExistException) {
continue;
}
if ($note->getHouseId() !== $houseId) {
continue;
}
$note->setSortOrder($sortOrder);
$note->setUpdatedAt(time());
$this->noteMapper->update($note);
}
}
private function validateColor(string $color): void {
if (!preg_match('/^#[0-9a-fA-F]{6}$/', $color)) {
throw new \InvalidArgumentException('Color must be a hex color code (#RRGGBB)');
}
}
}