slug checks, asset editor improvements

This commit is contained in:
crispycat 2024-10-06 23:07:49 -04:00
parent b77cefb218
commit 08cdb94dae
2 changed files with 104 additions and 85 deletions

View File

@ -3,7 +3,7 @@
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
@ -14,7 +14,6 @@
defined("ROOT") or die();
use \Crispage\Exceptions\AssetException;
use \Crispage\Utils\URIUtils;
use \Crispage\Framework\Asset;
@ -26,81 +25,69 @@
];
}
public function __construct(\Crispage $app, array $data) {
parent::__construct($app, $data);
}
public function run(): void {
// Get class name
$this->data["classname"] = strval(
$this->app->request->params["classname"] ?? "\\Crispage\\Framework\\Asset"
);
// get asset
$this->data["asset_id"] = intval($this->app->request->params["asset_id"] ?? 0);
$this->data["asset"] = $this->app->assets->get($this->data["asset_id"]);
// Check class is valid
if (!class_exists($this->data["classname"]))
throw new AssetException("Class {$this->data["classname"]} does not exist");
if (!is_a($this->data["classname"], "\\Crispage\\Framework\\Asset", true))
throw new AssetException("Class {$this->data["classname"]} is not an Asset");
$edit = false;
if ($this->data["asset"]) {
$edit = true;
$this->data["classname"] = "\\" . $this->data["asset"]::class;
}
else {
// get and validate classname string
$this->data["classname"] = strval($this->app->request->params["classname"] ?? "");
if (
!class_exists($this->data["classname"]) ||
!is_a($this->data["classname"], "\\Crispage\\Framework\\Asset", true)
) {
$this->app->page->setPersistentMessage(
"invalid_asset_class",
"Invalid asset class {$this->data["classname"]}",
"danger"
);
$this->app->page->redirect(URIUtils::iuri("/backend", ["route" => "dashboard"]));
}
}
$this->data["list_uri"] = URIUtils::iuri("/backend", [
"route" => "assets/list",
"classname" => $this->data["classname"]
]);
// Get asset id
$this->data["asset_id"] = intval($this->app->request->params["asset_id"] ?? 0);
// If id is not 0, edit mode
if ($this->data["asset_id"]) {
// Get asset
$this->data["asset"] = $this->app->assets->get($this->data["asset_id"]);
// Check that asset exists
if (!$this->data["asset"]) {
$this->app->page->setPersistentMessage(
"asset_not_exist",
$this->app->i18n->translate(
"{%ASSET_WITH_ID_X_DOES_NOT_EXIST}",
$this->data["asset_id"]
),
"danger"
if (!$this->data["asset"] && $this->data["asset_id"] > 0) {
$this->app->page->setPersistentMessage(
"asset_not_exist",
$this->app->i18n->translate(
"{%ASSET_WITH_ID_X_DOES_NOT_EXIST}",
$this->data["asset_id"]
),
"danger"
);
$this->app->page->redirect($this->data["list_uri"]);
}
$this->app->page->redirect($this->data["list_uri"]);
}
$this->data["classname"] = "\\" . $this->data["asset"]::class;
// Check permissions
// permission check
if ($edit) {
if ($this->data["asset"]->getOwnerId() == $this->app->auth->currentUser->id)
$perm = $this->data["asset"]::getPermissions()["modify_own"];
else $perm = $this->data["asset"]::getPermissions()["modify"];
if (!$this->app->auth->userHasPermission($perm)) {
$this->app->page->setPersistentMessage(
"no_permission",
$this->app->i18n->translate(
"{%YOU_DO_NOT_HAVE_PERMISSION__THIS_ACTION}",
),
"danger"
);
$this->app->page->redirect($this->data["list_uri"]);
}
}
// Otherwise, create mode
else {
$this->data["asset"] = null;
else $perm = $this->data["classname"]::getPermissions()["create"];
$perm = $this->data["classname"]::getPermissions()["create"];
if (!$this->app->auth->userHasPermission($perm)) {
$this->app->page->setPersistentMessage(
"no_permission",
$this->app->i18n->translate(
"{%YOU_DO_NOT_HAVE_PERMISSION__THIS_ACTION}",
),
"danger"
);
$this->app->page->redirect($this->data["list_uri"]);
}
if (!$this->app->auth->userHasPermission($perm)) {
$this->app->page->setPersistentMessage(
"no_permission",
$this->app->i18n->translate(
"{%YOU_DO_NOT_HAVE_PERMISSION__THIS_ACTION}",
),
"danger"
);
$this->app->page->redirect($this->data["list_uri"]);
}
$this->data["fields"] = $this->data["classname"]::getEditorFields();
@ -109,6 +96,7 @@
// If fields given, create or edit the asset
$data = $this->app->request->params["fields"] ?? null;
if (!empty($data) && is_array($data)) {
// create temporary asset
if (!$this->data["asset"]) {
$this->data["asset"] = $this->app->assets->create(
$this->data["classname"], [], true
@ -116,6 +104,7 @@
}
foreach ($this->data["fields"] as $field) {
if ($field->name == "slug") continue;
$this->data["asset"]->{$field->name} = $field->filter(
$this->app, $this->app->request->params["fields"][$field->name] ?? null,
$this->data["asset"]->{$field->name}
@ -132,42 +121,55 @@
);
}
// Automatic slug
if (empty($this->data["asset"]->slug))
$this->data["asset"]->slug = Asset::slug($this->data["asset"]->getName());
else $this->data["asset"]->slug = Asset::slug($this->data["asset"]->slug);
$slug = $this->app->request->params["fields"]["slug"] ?? "";
if (empty($slug)) $slug = $this->data["asset"]->getName();
$slug = Asset::slug($slug);
// Check slug for duplicates
$asset = $this->app->assets->getBySlug(
$this->data["classname"], $this->data["asset"]->slug
);
if ($asset && $asset->id != $this->data["asset_id"])
$this->data["asset"]->slug .= "_" . time();
if (!$edit && $slug != $this->data["asset"]->slug) {
$existing = $this->app->assets->getBySlug($this->data["classname"], $slug, null);
if ($existing && $existing->id != $this->data["asset"]->id)
$slug = uniqid("{$slug}_");
}
// Save
if ($this->data["asset"]->isTemporary())
$this->data["asset"] = $this->app->assets->makePermanent($this->data["asset"]);
else $this->app->assets->set($this->data["asset"]);
$this->data["asset"]->slug = $slug;
// Set message
$this->app->page->data["messages"]["changes_saved"] = [
"color" => "success",
"content" => $this->app->i18n->translate("{%CHANGES_SAVED}")
];
if ($edit) {
$this->app->assets->set($this->data["asset"]);
$this->app->page->data["messages"]["changes_saved"] = [
"color" => "success",
"content" => $this->app->i18n->translate("{%CHANGES_SAVED}")
];
}
else {
$asset = $this->app->assets->makePermanent($this->data["asset"]);
$this->app->page->setPersistentMessage(
"changes_saved",
$this->app->i18n->translate("{%CHANGES_SAVED}"),
"success"
);
$this->app->page->redirect(
URIUtils::iuri("/backend", [
"route" => "assets/editor",
"asset_id" => $asset->id
])
);
}
}
// Set title
if ($this->data["asset"]) {
$this->app->page->data["title"] = $this->app->i18n->translate(
// title
if ($edit) {
$title = $this->app->i18n->translate(
"{%EDITOR_TITLE_EDIT}", $this->data["asset"]->getName()
);
}
else {
$this->app->page->data["title"] = $this->app->i18n->translate(
$title = $this->app->i18n->translate(
"{%EDITOR_TITLE_CREATE}",
$this->app->i18n->translate($this->data["classname"]::getNames()[0])
);
}
$this->app->page->data["title"] = $title;
// Set main component
$com = $this->app->page->createComponent(

View File

@ -341,6 +341,15 @@
if ($asset->isTemporary()) return;
$asset->mtime = time();
// check for conflicting slug
$res = $this->app->database->select("assets", null, [
"classname" => "\\" . $asset::class,
"slug" => $asset->slug,
"id" => [$asset->id, $this->app->database::OP_NOT_EQUAL]
]);
if ($res->fetch() !== false)
throw new AssetException("Asset of type " . $asset::class . " with slug {$asset->slug} already exists");
// Update tables
$this->app->database->update(
$asset->_table, $asset->toArray(), ["id" => $asset->id]
@ -402,6 +411,14 @@
public function makePermanent(Asset $asset): Asset {
if (!$asset->isTemporary()) return $asset;
// check for conflicting slug
$res = $this->app->database->select("assets", null, [
"classname" => "\\" . $asset::class,
"slug" => $asset->slug
]);
if ($res->fetch() !== false)
throw new AssetException("Asset of type " . $asset::class . " with slug {$asset->slug} already exists");
$data = $asset->toArray();
$data["id"] = $this->getNewID();
$data["_table"] = $this->getTable("\\" . $asset::class);