mediaRepository->findAll(); } /** @return PaginatedResult */ public function findPaginated(int $page, int $perPage): PaginatedResult { $page = max(1, $page); $total = $this->mediaRepository->countAll(); $offset = ($page - 1) * $perPage; return new PaginatedResult( $this->mediaRepository->findPage($perPage, $offset), $total, $page, $perPage, ); } /** @return Media[] */ public function findByUserId(int $userId): array { return $this->mediaRepository->findByUserId($userId); } /** @return PaginatedResult */ public function findByUserIdPaginated(int $userId, int $page, int $perPage): PaginatedResult { $page = max(1, $page); $total = $this->mediaRepository->countByUserId($userId); $offset = ($page - 1) * $perPage; return new PaginatedResult( $this->mediaRepository->findByUserPage($userId, $perPage, $offset), $total, $page, $perPage, ); } public function findById(int $id): ?Media { return $this->mediaRepository->findById($id); } public function store(UploadedFileInterface $uploadedFile, int $userId): string { $preparedUpload = $this->mediaStorage->prepareUpload($uploadedFile, $this->maxSize); $hash = $preparedUpload->getHash(); $existing = $this->mediaRepository->findByHashForUser($hash, $userId); if ($existing !== null) { $this->mediaStorage->cleanupPreparedUpload($preparedUpload); return $existing->getUrl(); } $filename = $this->mediaStorage->storePreparedUpload($uploadedFile, $preparedUpload); $url = rtrim($this->uploadUrl, '/') . '/' . $filename; $media = new Media(0, $filename, $url, $hash, $userId); try { $this->mediaRepository->create($media); } catch (PDOException $e) { $this->mediaStorage->deleteStoredFile($filename); $duplicate = $this->mediaRepository->findByHashForUser($hash, $userId); if ($duplicate !== null) { return $duplicate->getUrl(); } throw $e; } return $url; } /** @return array{count:int, posts:array} */ public function getUsageSummary(Media $media, int $sampleLimit = 5): array { return [ 'count' => $this->postRepository->countByEmbeddedMediaUrl($media->getUrl()), 'posts' => $this->postRepository->findByEmbeddedMediaUrl($media->getUrl(), $sampleLimit), ]; } public function delete(Media $media): void { $this->mediaStorage->deleteStoredFile($media->getFilename()); $this->mediaRepository->delete($media->getId()); } }