added APICommentAction, api fixes
This commit is contained in:
parent
765def895d
commit
b8c302a50e
159
core/actions/Crispage/Actions/API/APICommentAction.php
Normal file
159
core/actions/Crispage/Actions/API/APICommentAction.php
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
Crispage CMS
|
||||||
|
crispycat <cc@crispy.cat>
|
||||||
|
https://crispy.cat/software/crispage
|
||||||
|
|
||||||
|
Crispage is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Crispage\Actions\API;
|
||||||
|
|
||||||
|
defined("ROOT") or die();
|
||||||
|
|
||||||
|
use \Crispage\Framework\Asset;
|
||||||
|
use \Crispage\Auth\CorePermissions;
|
||||||
|
use \Crispage\Exceptions\APIException;
|
||||||
|
use \Crispage\Assets\Comment;
|
||||||
|
|
||||||
|
class APICommentAction extends \Crispage\Framework\Action
|
||||||
|
implements \Crispage\Response\APIPermissions {
|
||||||
|
public static function getExtensionInfo(): array {
|
||||||
|
return [
|
||||||
|
"id" => "crispage.actions.api.comment",
|
||||||
|
"version" => VERSION
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getAPIPermissions(): array {
|
||||||
|
return [
|
||||||
|
"GET" => CorePermissions::NONE,
|
||||||
|
"POST" => CorePermissions::POST_COMMENT,
|
||||||
|
"PATCH" => CorePermissions::MODERATE_COMMENTS
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function run(): void {
|
||||||
|
if (!$this->app->settings->get("crispage.comments_enabled", true))
|
||||||
|
throw new APIException("Comments disabled", 403);
|
||||||
|
|
||||||
|
switch ($this->app->request->method) {
|
||||||
|
case "GET": {
|
||||||
|
// get content asset
|
||||||
|
$content = $this->app->assets->get(
|
||||||
|
intval($this->app->request->json["content_id"] ?? 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 404 if content doesn't exist or comments disabled
|
||||||
|
if (!$content || !$content->getOption("show_comments", true))
|
||||||
|
throw new APIException("Not found", 404);
|
||||||
|
|
||||||
|
// include approved comments only unless user has backend permissions
|
||||||
|
$filter = boolval(
|
||||||
|
$this->app->request->json["filter"] ?? 1
|
||||||
|
);
|
||||||
|
if (!$this->app->auth->userHasPermission(CorePermissions::BACKEND))
|
||||||
|
$filter = true;
|
||||||
|
|
||||||
|
$filters = ["content_id" => $content->id];
|
||||||
|
if ($filter) $filters["state"] = Comment::APPROVED;
|
||||||
|
|
||||||
|
// get comments
|
||||||
|
$comments = $this->app->assets->getAllFiltered(
|
||||||
|
"\\Crispage\\Assets\\Comment",
|
||||||
|
$filters, "mtime", true
|
||||||
|
);
|
||||||
|
|
||||||
|
$out = [];
|
||||||
|
foreach ($comments as $comment) {
|
||||||
|
$author = $this->app->assets->get($comment->author_id);
|
||||||
|
if (!$author) continue;
|
||||||
|
|
||||||
|
$out[] = [
|
||||||
|
"comment_id" => $comment->id,
|
||||||
|
"body" => $comment->body,
|
||||||
|
"content_id" => $comment->content_id,
|
||||||
|
"author_id" => $author->id,
|
||||||
|
"author_slug" => $author->slug,
|
||||||
|
"author_name" => $author->displayname,
|
||||||
|
"posted" => $comment->ctime,
|
||||||
|
"state" => $comment->state
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "POST": {
|
||||||
|
// get content asset
|
||||||
|
$content = $this->app->assets->get(
|
||||||
|
intval($this->app->request->json["content_id"] ?? 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 404 if content doesn't exist or comments disabled
|
||||||
|
if (!$content || !$content->getOption("show_comments", true))
|
||||||
|
throw new APIException("Not found", 404);
|
||||||
|
|
||||||
|
|
||||||
|
$body = strval($this->app->request->json["body"] ?? "");
|
||||||
|
if (empty($body)) throw new APIException("Body empty", 400);
|
||||||
|
|
||||||
|
$ra = $this->app->settings->get("crispage.comments_require_approval", false);
|
||||||
|
$state = ($ra) ? Comment::PENDING_APPROVAL : Comment::APPROVED;
|
||||||
|
|
||||||
|
|
||||||
|
$comment = $this->app->assets->create(
|
||||||
|
"\\Crispage\\Assets\\Comment", [
|
||||||
|
"slug" => $content->slug . "_" . dechex(time()) . bin2hex(random_bytes(2)),
|
||||||
|
"author_id" => $this->app->auth->currentUser->id,
|
||||||
|
"content_id" => $content->id,
|
||||||
|
"body" => $body,
|
||||||
|
"state" => $state
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$out = [
|
||||||
|
"comment_id" => $comment->id,
|
||||||
|
"body" => $comment->body,
|
||||||
|
"content_id" => $comment->content_id,
|
||||||
|
"author_id" => $this->app->auth->currentUser->id,
|
||||||
|
"author_slug" => $this->app->auth->currentUser->slug,
|
||||||
|
"author_name" => $this->app->auth->currentUser->displayname,
|
||||||
|
"posted" => $comment->ctime,
|
||||||
|
"state" => $comment->state
|
||||||
|
];
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "PATCH": {
|
||||||
|
$comment = $this->app->assets->get(
|
||||||
|
intval($this->app->request->json["comment_id"] ?? 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!$comment || !is_a($comment, "\\Crispage\\Assets\\Comment"))
|
||||||
|
throw new APIException("Invalid ID", 400);
|
||||||
|
|
||||||
|
$state = intval($this->app->request->json["state"] ?? 0);
|
||||||
|
if ($state != Comment::HIDDEN && $state != Comment::APPROVED)
|
||||||
|
throw new APIException("Invalid state", 400);
|
||||||
|
|
||||||
|
$comment->state = $state;
|
||||||
|
$this->app->assets->set($comment);
|
||||||
|
|
||||||
|
$out = [
|
||||||
|
"comment_id" => $comment->id,
|
||||||
|
"author_id" => $comment->author_id,
|
||||||
|
"state" => $comment->state
|
||||||
|
];
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->app->page->setAPIOutput($out);
|
||||||
|
$this->app->page->actionFinished();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
@ -30,25 +30,26 @@
|
|||||||
// Get route
|
// Get route
|
||||||
$route = $this->getRoute("api");
|
$route = $this->getRoute("api");
|
||||||
|
|
||||||
|
$this->setRouteLayout($route, "api", "default");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!$route) throw new APIException(404, "Invalid endpoint");
|
if (!$route) throw new APIException(404, "Invalid endpoint");
|
||||||
|
|
||||||
// Get required permissions
|
// Get required permissions
|
||||||
$this->app->loadClass($route->action, "action");
|
$this->app->loadClass($route->action, "action");
|
||||||
if (!is_a($route->action, "\\Crispage\\Response\\APIPermissions", true))
|
if (!is_a($route->action, "\\Crispage\\Response\\APIPermissions", true))
|
||||||
throw new APIException(500, "Invalid action");
|
throw new APIException("Invalid action", 500);
|
||||||
|
|
||||||
$perms = $route->action::getAPIPermissions();
|
$perms = $route->action::getAPIPermissions();
|
||||||
$perm = $perms[$this->app->request->method] ?? CorePermissions::NEVER;
|
$perm = $perms[$this->app->request->method] ?? CorePermissions::NEVER;
|
||||||
|
|
||||||
// Error on invalid method
|
// Error on invalid method
|
||||||
if ($perm == CorePermissions::NEVER)
|
if ($perm === CorePermissions::NEVER)
|
||||||
throw new APIException(405, "Method not allowed");
|
throw new APIException("Method not allowed", 405);
|
||||||
// Check permissions
|
// Check permissions
|
||||||
if (!$this->app->auth->userHasPermission($perm))
|
if (!$this->app->auth->userHasPermission($perm))
|
||||||
throw new APIException(401, "Unauthorized");
|
throw new APIException("Unauthorized", 401);
|
||||||
|
|
||||||
$this->setRouteLayout($route, "api", "default");
|
|
||||||
$this->route($route);
|
$this->route($route);
|
||||||
}
|
}
|
||||||
catch (APIException $e) {
|
catch (APIException $e) {
|
||||||
|
@ -192,6 +192,11 @@
|
|||||||
"\\Crispage\\Actions\\API\\APIAssetSearchAction",
|
"\\Crispage\\Actions\\API\\APIAssetSearchAction",
|
||||||
"action", []
|
"action", []
|
||||||
),
|
),
|
||||||
|
new Extension(
|
||||||
|
"crispage.actions.api.comment", VERSION, "crispage.core",
|
||||||
|
"\\Crispage\\Actions\\API\\APICommentAction",
|
||||||
|
"action", []
|
||||||
|
),
|
||||||
new Extension(
|
new Extension(
|
||||||
"crispage.actions.api.default", VERSION, "crispage.core",
|
"crispage.actions.api.default", VERSION, "crispage.core",
|
||||||
"\\Crispage\\Actions\\API\\APIDefaultAction",
|
"\\Crispage\\Actions\\API\\APIDefaultAction",
|
||||||
|
@ -70,6 +70,7 @@
|
|||||||
new Route("asset/status", "\\Crispage\\Actions\\API\\APIAssetStatusAction", static::RDATA_API),
|
new Route("asset/status", "\\Crispage\\Actions\\API\\APIAssetStatusAction", static::RDATA_API),
|
||||||
new Route("assets", "\\Crispage\\Actions\\API\\APIAssetsAction", static::RDATA_API),
|
new Route("assets", "\\Crispage\\Actions\\API\\APIAssetsAction", static::RDATA_API),
|
||||||
new Route("assets/search", "\\Crispage\\Actions\\API\\APIAssetSearchAction", static::RDATA_API),
|
new Route("assets/search", "\\Crispage\\Actions\\API\\APIAssetSearchAction", static::RDATA_API),
|
||||||
|
new Route("comment", "\\Crispage\\Actions\\API\\APICommentAction", static::RDATA_API),
|
||||||
new Route("media", "\\Crispage\\Actions\\API\\APIMediaAction", static::RDATA_API),
|
new Route("media", "\\Crispage\\Actions\\API\\APIMediaAction", static::RDATA_API),
|
||||||
new Route("media/folder", "\\Crispage\\Actions\\API\\APIMediaFolderAction", static::RDATA_API),
|
new Route("media/folder", "\\Crispage\\Actions\\API\\APIMediaFolderAction", static::RDATA_API),
|
||||||
new Route("session", "\\Crispage\\Actions\\API\\APISessionAction", static::RDATA_API),
|
new Route("session", "\\Crispage\\Actions\\API\\APISessionAction", static::RDATA_API),
|
||||||
|
Loading…
Reference in New Issue
Block a user