Files
nextcloud-forum/lib/Controller/TemplateController.php

174 lines
5.3 KiB
PHP

<?php
declare(strict_types=1);
// SPDX-FileCopyrightText: Chen Asraf <contact@casraf.dev>
// SPDX-License-Identifier: AGPL-3.0-or-later
namespace OCA\Forum\Controller;
use OCA\Forum\Db\Template;
use OCA\Forum\Db\TemplateMapper;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\Attribute\ApiRoute;
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCSController;
use OCP\IRequest;
use Psr\Log\LoggerInterface;
class TemplateController extends OCSController {
public function __construct(
string $appName,
IRequest $request,
private TemplateMapper $templateMapper,
private LoggerInterface $logger,
private ?string $userId,
) {
parent::__construct($appName, $request);
}
/**
* List current user's templates
*
* @param string|null $visibility Optional visibility filter (threads, replies)
* @param int<1, 100> $limit Maximum number of templates to return
* @param int<0, max> $offset Offset for pagination
* @return DataResponse<Http::STATUS_OK, list<array<string, mixed>>, array{}>
*
* 200: Templates returned
*/
#[NoAdminRequired]
#[ApiRoute(verb: 'GET', url: '/api/templates')]
public function index(?string $visibility = null, int $limit = 100, int $offset = 0): DataResponse {
try {
$templates = $this->templateMapper->findByUserId($this->userId, $visibility, $limit, $offset);
return new DataResponse(array_map(fn ($t) => $t->jsonSerialize(), $templates));
} catch (\Exception $e) {
$this->logger->error('Error fetching templates: ' . $e->getMessage());
return new DataResponse(['error' => 'Failed to fetch templates'], Http::STATUS_INTERNAL_SERVER_ERROR);
}
}
/**
* Create a template
*
* @param string $name Template name
* @param string $content Template content (BBCode)
* @param string $visibility Visibility setting
* @param int $sortOrder Sort order
* @return DataResponse<Http::STATUS_CREATED, array<string, mixed>, array{}>
*
* 201: Template created
*/
#[NoAdminRequired]
#[ApiRoute(verb: 'POST', url: '/api/templates')]
public function create(
string $name,
string $content,
string $visibility = 'both',
int $sortOrder = 0,
): DataResponse {
try {
$now = time();
$template = new Template();
$template->setUserId($this->userId);
$template->setName($name);
$template->setContent($content);
$template->setVisibility($visibility);
$template->setSortOrder($sortOrder);
$template->setCreatedAt($now);
$template->setUpdatedAt($now);
/** @var Template */
$created = $this->templateMapper->insert($template);
return new DataResponse($created->jsonSerialize(), Http::STATUS_CREATED);
} catch (\Exception $e) {
$this->logger->error('Error creating template: ' . $e->getMessage());
return new DataResponse(['error' => 'Failed to create template'], Http::STATUS_INTERNAL_SERVER_ERROR);
}
}
/**
* Update a template
*
* @param int $id Template ID
* @param string|null $name Template name
* @param string|null $content Template content
* @param string|null $visibility Visibility setting
* @param int|null $sortOrder Sort order
* @return DataResponse<Http::STATUS_OK, array<string, mixed>, array{}>
*
* 200: Template updated
*/
#[NoAdminRequired]
#[ApiRoute(verb: 'PUT', url: '/api/templates/{id}')]
public function update(
int $id,
?string $name = null,
?string $content = null,
?string $visibility = null,
?int $sortOrder = null,
): DataResponse {
try {
$template = $this->templateMapper->find($id);
if ($template->getUserId() !== $this->userId) {
return new DataResponse(['error' => 'Forbidden'], Http::STATUS_FORBIDDEN);
}
if ($name !== null) {
$template->setName($name);
}
if ($content !== null) {
$template->setContent($content);
}
if ($visibility !== null) {
$template->setVisibility($visibility);
}
if ($sortOrder !== null) {
$template->setSortOrder($sortOrder);
}
$template->setUpdatedAt(time());
/** @var Template */
$updated = $this->templateMapper->update($template);
return new DataResponse($updated->jsonSerialize());
} catch (DoesNotExistException $e) {
return new DataResponse(['error' => 'Template not found'], Http::STATUS_NOT_FOUND);
} catch (\Exception $e) {
$this->logger->error('Error updating template: ' . $e->getMessage());
return new DataResponse(['error' => 'Failed to update template'], Http::STATUS_INTERNAL_SERVER_ERROR);
}
}
/**
* Delete a template
*
* @param int $id Template ID
* @return DataResponse<Http::STATUS_OK, array{success: bool}, array{}>
*
* 200: Template deleted
*/
#[NoAdminRequired]
#[ApiRoute(verb: 'DELETE', url: '/api/templates/{id}')]
public function destroy(int $id): DataResponse {
try {
$template = $this->templateMapper->find($id);
if ($template->getUserId() !== $this->userId) {
return new DataResponse(['error' => 'Forbidden'], Http::STATUS_FORBIDDEN);
}
$this->templateMapper->delete($template);
return new DataResponse(['success' => true]);
} catch (DoesNotExistException $e) {
return new DataResponse(['error' => 'Template not found'], Http::STATUS_NOT_FOUND);
} catch (\Exception $e) {
$this->logger->error('Error deleting template: ' . $e->getMessage());
return new DataResponse(['error' => 'Failed to delete template'], Http::STATUS_INTERNAL_SERVER_ERROR);
}
}
}