initial commit
This commit is contained in:
parent
11283b22dd
commit
c1a57c64f2
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
build
|
||||
cache
|
||||
lite
|
||||
patch/config.php
|
2
README
Normal file
2
README
Normal file
@ -0,0 +1,2 @@
|
||||
# Crispage Lite
|
||||
Crispage Lite is a version of the [Crispage CMS](https://crispy.cat/software/crispage) with many features removed, intended for the development of other applications based on the framework.
|
23
build.sh
Executable file
23
build.sh
Executable file
@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
rm -rf build;
|
||||
|
||||
if [[ -d cache ]]; then
|
||||
cp -r cache build;
|
||||
else
|
||||
git clone https://git.calitabby.com/crispage/crispage.git build;
|
||||
cp -r build cache;
|
||||
fi;
|
||||
|
||||
while IFS= read -r line; do
|
||||
if [[ "$line" != "" ]]; then
|
||||
rm -rf build/"$line";
|
||||
fi;
|
||||
done < delete.list;
|
||||
|
||||
cp -r patch/* build;
|
||||
|
||||
read -p "Copy build folder? [y/n]" copy
|
||||
if [[ "$copy" = "y" ]]; then
|
||||
rm -rf lite;
|
||||
cp -r build lite;
|
||||
fi;
|
8
delete.list
Normal file
8
delete.list
Normal file
@ -0,0 +1,8 @@
|
||||
.git
|
||||
_crispage
|
||||
core/app/assets
|
||||
core/actions
|
||||
core/components
|
||||
core/templates
|
||||
media/assets
|
||||
media/uploads
|
33
patch/core/actions/Crispage/Actions/DefaultAction.php
Executable file
33
patch/core/actions/Crispage/Actions/DefaultAction.php
Executable file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/*
|
||||
Crispage CMS
|
||||
crispycat <the@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;
|
||||
|
||||
defined("ROOT") or die();
|
||||
|
||||
class DefaultAction extends \Crispage\Response\Action {
|
||||
public static function getExtensionInfo(): array {
|
||||
return [
|
||||
"id" => "crispage.actions.default",
|
||||
"version" => VERSION
|
||||
];
|
||||
}
|
||||
|
||||
public function __construct(\Crispage $app, array $data) {
|
||||
parent::__construct($app, $data);
|
||||
}
|
||||
|
||||
public function run(): void {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
?>
|
187
patch/core/app/assets/Asset.php
Normal file
187
patch/core/app/assets/Asset.php
Normal file
@ -0,0 +1,187 @@
|
||||
<?php
|
||||
/*
|
||||
Crispage CMS
|
||||
crispycat <the@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;
|
||||
|
||||
defined("ROOT") or die();
|
||||
|
||||
use \Crispage\Auth\CorePermissions;
|
||||
|
||||
class Asset {
|
||||
public static function getNames(): array {
|
||||
return ["Asset", "Assets"];
|
||||
}
|
||||
|
||||
public static function getPermissions(): array {
|
||||
return [
|
||||
"create" => CorePermissions::NEVER,
|
||||
"modify" => CorePermissions::NEVER,
|
||||
"modify_own"=> CorePermissions::NEVER,
|
||||
"delete" => CorePermissions::NEVER,
|
||||
"delete_own"=> CorePermissions::NEVER
|
||||
];
|
||||
}
|
||||
|
||||
public static function getRoutingInfo(): array {
|
||||
return [
|
||||
"action" => null,
|
||||
"data" => []
|
||||
];
|
||||
}
|
||||
|
||||
public static function getSortingInfo(): array {
|
||||
return [
|
||||
"field" => "mtime",
|
||||
"desc" => true
|
||||
];
|
||||
}
|
||||
|
||||
public static function getListColumns(): array {
|
||||
global $Crispage;
|
||||
return [
|
||||
"id" => ["label" => "{%ID}"],
|
||||
"slug" => [
|
||||
"label" => "{%SLUG}",
|
||||
"filter" => "\\Crispage\\Utils\\TextUtils::codeify"
|
||||
],
|
||||
"ctime" => [
|
||||
"label" => "{%CREATED}",
|
||||
"filter" => [$Crispage->i18n, "datetime"]
|
||||
],
|
||||
"mtime" => [
|
||||
"label" => "{%MODIFIED}",
|
||||
"filter" => [$Crispage->i18n, "datetime"]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public static function getListActions(): array {
|
||||
return [
|
||||
[
|
||||
"route" => "assets/editor",
|
||||
"label" => "{%CREATE_NEW}",
|
||||
"color" => "success"
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public static function getListItemActions(): array {
|
||||
return [
|
||||
[
|
||||
"route" => "assets/editor",
|
||||
"label" => "{%EDIT}",
|
||||
"color" => "primary",
|
||||
"fields" => [
|
||||
"asset_id" => "id"
|
||||
]
|
||||
],
|
||||
[
|
||||
"route" => "assets/delete",
|
||||
"label" => "{%DELETE}",
|
||||
"color" => "danger",
|
||||
"fields" => [
|
||||
"asset_id" => "id"
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public static function getEditorFields(): array {
|
||||
return [
|
||||
"slug" => [
|
||||
"column" => 1,
|
||||
"component" => "\\Crispage\\Components\\Fields\\TextFieldComponent",
|
||||
"com_data" => [
|
||||
"label" => "{%SLUG}:"
|
||||
],
|
||||
"filter" => "strval"
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public static function getOptionFields(): array {
|
||||
return [];
|
||||
}
|
||||
|
||||
public static function slug(string $text = null): string {
|
||||
if (empty($text)) return strval(time());
|
||||
$slug = strtolower($text);
|
||||
$slug = preg_replace("/[^a-z\\d\\-_]+/", "-", $slug);
|
||||
$slug = preg_replace("/-{2,}/", "-", $slug);
|
||||
$slug = trim($slug, "-");
|
||||
if (empty($slug)) return strval(time());
|
||||
return $slug;
|
||||
}
|
||||
|
||||
public ?string $_table;
|
||||
public int $id;
|
||||
public string $slug;
|
||||
public int $ctime;
|
||||
public int $mtime;
|
||||
public string $options;
|
||||
protected array $_options_array;
|
||||
|
||||
protected function __construct(array $props) {
|
||||
$this->_table = $props["_table"] ?? null;
|
||||
$this->id = $props["id"] ?? 0;
|
||||
$this->slug = $props["slug"] ?? "";
|
||||
$this->ctime = $props["ctime"] ?? time();
|
||||
$this->mtime = $props["mtime"] ?? time();
|
||||
$this->options = $props["options"] ?? "[]";
|
||||
$this->_options_array = json_decode($this->options, true);
|
||||
}
|
||||
|
||||
public function toArray(): array {
|
||||
$arr = [];
|
||||
foreach ($this as $k => $v) {
|
||||
if ($k[0] == "_") continue;
|
||||
if (is_bool($v)) $v = intval($v);
|
||||
$arr[$k] = $v;
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
public function getOption(string $key, $default = null) {
|
||||
return $this->_options_array[$key] ?? $default;
|
||||
}
|
||||
|
||||
public function getOptions(): array {
|
||||
return $this->_options_array;
|
||||
}
|
||||
|
||||
public function setOption(string $key, $value): void {
|
||||
$this->_options_array[$key] = $value;
|
||||
$this->options = json_encode($this->_options_array);
|
||||
}
|
||||
|
||||
public function setOptions(array $data): void {
|
||||
$this->_options_array = array_merge($this->_options_array, $data);
|
||||
$this->options = json_encode($this->_options_array);
|
||||
}
|
||||
|
||||
public function isTemporary(): bool {
|
||||
return $this->_table === null;
|
||||
}
|
||||
|
||||
public function getOwnerId(): int {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getName(): string {
|
||||
return $this->slug;
|
||||
}
|
||||
|
||||
public function getParentId(): int {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
?>
|
359
patch/core/app/assets/AssetManager.php
Normal file
359
patch/core/app/assets/AssetManager.php
Normal file
@ -0,0 +1,359 @@
|
||||
<?php
|
||||
/*
|
||||
Crispage CMS
|
||||
crispycat <the@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;
|
||||
|
||||
defined("ROOT") or die();
|
||||
|
||||
require_once ROOT . "/core/app/assets/Asset.php";
|
||||
|
||||
|
||||
require_once ROOT . "/core/app/assets/class/Module.php";
|
||||
require_once ROOT . "/core/app/assets/class/Plugin.php";
|
||||
require_once ROOT . "/core/app/assets/class/Role.php";
|
||||
require_once ROOT . "/core/app/assets/class/User.php";
|
||||
|
||||
use \Crispage\Events\Receiver;
|
||||
use \Crispage\Text\ShortcodeRenderer;
|
||||
|
||||
class AssetManager {
|
||||
public \Crispage $app;
|
||||
private array $registeredClasses = [];
|
||||
|
||||
public function __construct(\Crispage $app) {
|
||||
$this->app = $app;
|
||||
|
||||
// Register default assets
|
||||
$this->registerClass("\\Crispage\\Assets\\Module");
|
||||
$this->registerClass("\\Crispage\\Assets\\Plugin");
|
||||
$this->registerClass("\\Crispage\\Assets\\Role");
|
||||
$this->registerClass("\\Crispage\\Assets\\User");
|
||||
|
||||
// Automatically update routes
|
||||
$this->app->dispatcher->register(
|
||||
new Receiver(
|
||||
"crispage.assets.update_routes_created",
|
||||
"crispage.assets.asset_created", 0,
|
||||
function (Asset $asset): void {
|
||||
$this->app->router->createContentRoute($asset);
|
||||
$this->app->router->createAdditionalContentRoutes($asset);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
$this->app->dispatcher->register(
|
||||
new Receiver(
|
||||
"crispage.assets.update_routes_set",
|
||||
"crispage.assets.asset_set", 0,
|
||||
function (Asset $asset): void {
|
||||
$this->app->router->deleteContentRoutes($asset);
|
||||
$this->app->router->createContentRoute($asset);
|
||||
$this->app->router->createAdditionalContentRoutes($asset);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
$this->app->dispatcher->register(
|
||||
new Receiver(
|
||||
"crispage.assets.update_routes_deleted",
|
||||
"crispage.assets.asset_deleted", 0,
|
||||
function (Asset $asset): void {
|
||||
$this->app->router->deleteContentRoutes($asset);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
$this->app->shortcodes->mapShortcode(new ShortcodeRenderer(
|
||||
"asset", fn(array $args): string => $this->app->resolveUri("asset://" . ($args["id"] ?? 0))
|
||||
));
|
||||
}
|
||||
|
||||
public function getRegisteredClasses(): array {
|
||||
return $this->registeredClasses;
|
||||
}
|
||||
|
||||
public function registerClass(string $classname): void {
|
||||
if (!in_array($classname, $this->registeredClasses))
|
||||
$this->registeredClasses[] = $classname;
|
||||
}
|
||||
|
||||
public function unregisterClass(string $classname): void {
|
||||
$this->registeredClasses = array_filter(
|
||||
$this->registeredClasses,
|
||||
fn(string $cn): bool => $cn != $classname
|
||||
);
|
||||
}
|
||||
|
||||
public function getTable(string $classname): string {
|
||||
return "assets_" . substr(md5($classname), 0, 8) . @end(explode("\\", $classname));
|
||||
}
|
||||
|
||||
public function getNewID(): int {
|
||||
// Get id from table
|
||||
$res = $this->app->database->select("system", ["next_asset_id"]);
|
||||
$id = $res->fetchColumn();
|
||||
// Increment id
|
||||
$this->app->database->increment("system", "next_asset_id");
|
||||
// Trigger event
|
||||
$this->app->dispatcher->trigger("crispage.assets.id_incremented", $id + 1);
|
||||
// Return id
|
||||
return $id;
|
||||
}
|
||||
|
||||
public function createTable(string $classname): bool {
|
||||
// Error if class is not an asset
|
||||
if (!is_a($classname, "\\Crispage\\Asset", true)) return false;
|
||||
|
||||
// Get table name
|
||||
$table = $this->getTable($classname);
|
||||
|
||||
// Create ReflectionClass
|
||||
$rc = new \ReflectionClass($classname);
|
||||
|
||||
// Build array of columns
|
||||
$cols = [
|
||||
"id" => [$this->app->database::TYPE_INT, false],
|
||||
"slug" => [$this->app->database::TYPE_STRING, false]
|
||||
];
|
||||
foreach ($rc->getProperties() as $prop) {
|
||||
$name = $prop->getName();
|
||||
// If name starts with _, or is "id" or "slug", skip
|
||||
if ($name[0] == "_" || $name == "id" || $name == "slug")
|
||||
continue;
|
||||
$type = $prop->getType();
|
||||
// If type is not \ReflectionNamedType, skip
|
||||
if (!is_a($type, "\\ReflectionNamedType")) continue;
|
||||
// Determine column type from property type
|
||||
switch ($type->getName()) {
|
||||
case "bool":
|
||||
$ctype = $this->app->database::TYPE_BOOL;
|
||||
break;
|
||||
case "int":
|
||||
$ctype = $this->app->database::TYPE_INT;
|
||||
break;
|
||||
case "float":
|
||||
$ctype = $this->app->database::TYPE_FLOAT;
|
||||
break;
|
||||
default:
|
||||
$ctype = $this->app->database::TYPE_STRING;
|
||||
}
|
||||
// Add to columns array
|
||||
$cols[$name] = [$ctype, $type->allowsNull()];
|
||||
}
|
||||
|
||||
// Create the table
|
||||
$this->app->database->createTable($table, $cols);
|
||||
$this->app->database->addPrimaryKey($table, "id");
|
||||
$this->app->database->addForeignKey($table, "id", "assets", "id");
|
||||
$this->app->database->addUnique($table, "slug");
|
||||
|
||||
// Trigger event
|
||||
$this->app->dispatcher->trigger(
|
||||
"crispage.assets.table_created", $classname, $table
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function constructAsset(string $table, string $class, int $id): ?Asset {
|
||||
// Get data from table
|
||||
$res = $this->app->database->select($table, null, ["id" => $id]);
|
||||
$row = $res->fetch();
|
||||
// Check that data exists and class exists
|
||||
if (!$row) return null;
|
||||
if (!class_exists($class)) return null;
|
||||
// Return asset from data
|
||||
$row["_table"] = $table;
|
||||
return new $class($row);
|
||||
}
|
||||
|
||||
public function get(int $id): ?Asset {
|
||||
// Get asset info from table
|
||||
$res = $this->app->database->select("assets", null, ["id" => $id]);
|
||||
$row = $res->fetch();
|
||||
// Check that data exists
|
||||
if (!$row) return null;
|
||||
// Return asset
|
||||
return $this->constructAsset(
|
||||
$row["tablename"], $row["classname"], $id
|
||||
);
|
||||
}
|
||||
|
||||
public function getBySlug(string $classname, string $slug): ?Asset {
|
||||
// Get asset info from table
|
||||
$res = $this->app->database->select(
|
||||
"assets", null, ["classname" => $classname, "slug" => $slug]
|
||||
);
|
||||
$row = $res->fetch();
|
||||
// Check that data exists
|
||||
if (!$row) return null;
|
||||
// Return asset
|
||||
return $this->constructAsset(
|
||||
$row["tablename"], $row["classname"], $row["id"]
|
||||
);
|
||||
}
|
||||
|
||||
public function getAll(string $classname = null): \Generator {
|
||||
// Get asset info from table
|
||||
$res = $this->app->database->select(
|
||||
"assets", null,
|
||||
($classname) ? ["classname" => $classname] : []
|
||||
);
|
||||
// Walk through and yield assets
|
||||
while (($row = $res->fetch()) !== false) {
|
||||
yield $this->constructAsset(
|
||||
$row["tablename"], $row["classname"], $row["id"]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function getAllFiltered(
|
||||
string $classname, array $filters = [], string $sortby = null,
|
||||
bool $desc = false
|
||||
): \Generator {
|
||||
if (!class_exists($classname)) return;
|
||||
// Get table name
|
||||
$table = $this->getTable($classname);
|
||||
// Get ids from table
|
||||
$res = $this->app->database->select(
|
||||
$table, ["id"], $filters, $sortby, $desc
|
||||
);
|
||||
// Walk through and yield assets
|
||||
while (($row = $res->fetch()) !== false)
|
||||
yield $this->constructAsset($table, $classname, $row["id"]);
|
||||
}
|
||||
|
||||
public function countAssets(string $classname = null): int {
|
||||
// Get count
|
||||
$res = $this->app->database->select(
|
||||
"assets", ["COUNT(*)"],
|
||||
($classname) ? ["classname" => $classname] : []
|
||||
);
|
||||
return $res->fetchColumn();
|
||||
}
|
||||
|
||||
public function create(
|
||||
string $classname, array $data, bool $temp = false
|
||||
): Asset {
|
||||
// Error if class is not an asset
|
||||
if (
|
||||
!class_exists($classname) ||
|
||||
!is_a($classname, "\\Crispage\\Asset", true)
|
||||
) {
|
||||
$this->app->handleException(
|
||||
new CrispageException("$classname is not an Asset", 500)
|
||||
);
|
||||
}
|
||||
|
||||
// Create asset
|
||||
$asset = new $classname($data);
|
||||
$asset->id = $this->getNewID();
|
||||
|
||||
if (!$temp) {
|
||||
// Get table name
|
||||
$asset->_table = $this->getTable($classname);
|
||||
|
||||
// Insert into tables
|
||||
$this->app->database->insert("assets", [
|
||||
"id" => $asset->id,
|
||||
"classname" => "\\" . $asset::class,
|
||||
"tablename" => $asset->_table,
|
||||
"slug" => $asset->slug
|
||||
]);
|
||||
$this->app->database->insert(
|
||||
$asset->_table, $asset->toArray()
|
||||
);
|
||||
|
||||
// Trigger event
|
||||
$this->app->dispatcher->trigger(
|
||||
"crispage.assets.asset_created", $asset
|
||||
);
|
||||
} else {
|
||||
$this->app->dispatcher->trigger(
|
||||
"crispage.assets.temporary_asset_created", $asset
|
||||
);
|
||||
}
|
||||
|
||||
return $asset;
|
||||
}
|
||||
|
||||
public function set(Asset $asset): void {
|
||||
if ($asset->isTemporary()) return;
|
||||
$asset->mtime = time();
|
||||
// Update tables
|
||||
$this->app->database->update(
|
||||
$asset->_table, $asset->toArray(), ["id" => $asset->id]
|
||||
);
|
||||
$this->app->database->update(
|
||||
"assets", ["slug" => $asset->slug], ["id" => $asset->id]
|
||||
);
|
||||
// Trigger event
|
||||
$this->app->dispatcher->trigger(
|
||||
"crispage.assets.asset_set", $asset
|
||||
);
|
||||
}
|
||||
|
||||
public function delete(Asset $asset): void {
|
||||
if ($asset->isTemporary) return;
|
||||
// Delete from tables
|
||||
$this->app->database->delete($asset->_table, ["id" => $asset->id]);
|
||||
$this->app->database->delete("assets", ["id" => $asset->id]);
|
||||
// Trigger event
|
||||
$this->app->dispatcher->trigger(
|
||||
"crispage.assets.asset_deleted", $asset
|
||||
);
|
||||
}
|
||||
|
||||
public function makePermanent(Asset $asset): Asset {
|
||||
if (!$asset->isTemporary()) return $asset;
|
||||
|
||||
// Get table name
|
||||
$asset->_table = $this->getTable("\\" . $asset::class);
|
||||
|
||||
// Insert into tables
|
||||
$this->app->database->insert("assets", [
|
||||
"id" => $asset->id,
|
||||
"classname" => "\\" . $asset::class,
|
||||
"tablename" => $asset->_table,
|
||||
"slug" => $asset->slug
|
||||
]);
|
||||
$this->app->database->insert(
|
||||
$asset->_table, $asset->toArray()
|
||||
);
|
||||
|
||||
// Trigger event
|
||||
$this->app->dispatcher->trigger(
|
||||
"crispage.assets.asset_created", $asset
|
||||
);
|
||||
|
||||
return $asset;
|
||||
}
|
||||
|
||||
public function getURI(Asset $asset, int $max = 15): string {
|
||||
$uri = "";
|
||||
$l = 0;
|
||||
while ($l < $max) {
|
||||
$uri = "/" . $asset->slug . $uri;
|
||||
$asset = $this->get($asset->getParentId());
|
||||
if (!$asset) return $uri;
|
||||
$l++;
|
||||
}
|
||||
return $uri;
|
||||
}
|
||||
|
||||
public function assetNameFromID(int $id, string $none = "B_NONE"): string {
|
||||
$asset = $this->get($id);
|
||||
if (!$asset) return $this->app->i18n->getTranslation($none);
|
||||
return $asset->getName();
|
||||
}
|
||||
}
|
||||
?>
|
167
patch/core/app/assets/class/Module.php
Normal file
167
patch/core/app/assets/class/Module.php
Normal file
@ -0,0 +1,167 @@
|
||||
<?php
|
||||
/*
|
||||
Crispage CMS
|
||||
crispycat <the@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\Assets;
|
||||
|
||||
defined("ROOT") or die();
|
||||
|
||||
use \Crispage\Auth\CorePermissions;
|
||||
|
||||
class Module extends \Crispage\Asset {
|
||||
public static function getNames(): array {
|
||||
return ["{%MODULE}", "{%MODULES}"];
|
||||
}
|
||||
|
||||
public static function getPermissions(): array {
|
||||
return [
|
||||
"create" => CorePermissions::MODIFY_LAYOUT,
|
||||
"modify" => CorePermissions::MODIFY_LAYOUT,
|
||||
"modify_own"=> CorePermissions::MODIFY_LAYOUT,
|
||||
"delete" => CorePermissions::MODIFY_LAYOUT,
|
||||
"delete_own"=> CorePermissions::MODIFY_LAYOUT
|
||||
];
|
||||
}
|
||||
|
||||
public static function getSortingInfo(): array {
|
||||
return [
|
||||
"field" => "location",
|
||||
"desc" => false
|
||||
];
|
||||
}
|
||||
|
||||
public static function getListColumns(): array {
|
||||
global $Crispage;
|
||||
return [
|
||||
"id" => ["label" => "{%ID}"],
|
||||
"slug" => [
|
||||
"label" => "{%SLUG}",
|
||||
"filter" => "\\Crispage\\Utils\\TextUtils::codeify"
|
||||
],
|
||||
"component" => [
|
||||
"label" => "{%TYPE}",
|
||||
"filter" => "\\Crispage\\Utils\\TextUtils::codeify"
|
||||
],
|
||||
"location" => [
|
||||
"label" => "{%LOCATION}",
|
||||
"filter" => "htmlentities"
|
||||
],
|
||||
"position" => [
|
||||
"label" => "{%POSITION}",
|
||||
"filter" => null
|
||||
],
|
||||
"enabled" => [
|
||||
"label" => "{%STATE}",
|
||||
"filter" => function(bool $s): string {
|
||||
global $Crispage;
|
||||
return $Crispage->i18n->translate(
|
||||
($s) ? "{%ENABLED}" : "{%DISABLED}"
|
||||
);
|
||||
}
|
||||
],
|
||||
"mtime" => [
|
||||
"label" => "{%MODIFIED}",
|
||||
"filter" => [$Crispage->i18n, "datetime"]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public static function getListActions(): array {
|
||||
return [
|
||||
[
|
||||
"route" => "module_create",
|
||||
"label" => "{%CREATE_NEW}",
|
||||
"color" => "success"
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public static function getEditorFields(): array {
|
||||
return [
|
||||
"enabled" => [
|
||||
"column" => 0,
|
||||
"component" => "\\Crispage\\Components\\Fields\\BooleanFieldComponent",
|
||||
"com_data" => [
|
||||
"label" => "{%ENABLED}:"
|
||||
],
|
||||
"filter" => "boolval"
|
||||
],
|
||||
"slug" => [
|
||||
"column" => 1,
|
||||
"component" => "\\Crispage\\Components\\Fields\\TextFieldComponent",
|
||||
"com_data" => [
|
||||
"label" => "{%SLUG}:",
|
||||
"attrs" => ["placeholder" => "automatic"]
|
||||
],
|
||||
"filter" => "strval"
|
||||
],
|
||||
"location" => [
|
||||
"column" => 1,
|
||||
"component" => "\\Crispage\\Components\\Fields\\TextFieldComponent",
|
||||
"com_data" => [
|
||||
"label" => "{%LOCATION}:",
|
||||
"attrs" => ["required"]
|
||||
],
|
||||
"filter" => "strval"
|
||||
],
|
||||
"position" => [
|
||||
"column" => 1,
|
||||
"component" => "\\Crispage\\Components\\Fields\\NumberFieldComponent",
|
||||
"com_data" => [
|
||||
"label" => "{%POSITION}:",
|
||||
"attrs" => ["required"]
|
||||
],
|
||||
"filter" => "intval"
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public static function getOptionFields(): array {
|
||||
return [
|
||||
"config" => [
|
||||
"component" => "\\Crispage\\Components\\Fields\\ModuleConfigFieldComponent",
|
||||
"com_data" => [],
|
||||
"filter" => function($data): array {
|
||||
global $Crispage;
|
||||
if (!is_array($data)) return [];
|
||||
$asset = $Crispage->assets->get(
|
||||
intval($Crispage->request->params["asset_id"]) ?? 0
|
||||
);
|
||||
|
||||
$Crispage->loadClass($asset->component);
|
||||
|
||||
$ndata = [];
|
||||
foreach ($asset->component::getModuleFields() as $name => $field)
|
||||
$ndata[$name] = $field["filter"]($data[$name] ?? null);
|
||||
return $ndata;
|
||||
}
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public string $component;
|
||||
public string $location;
|
||||
public int $position;
|
||||
public bool $enabled;
|
||||
|
||||
public function __construct(array $props) {
|
||||
parent::__construct($props);
|
||||
$this->component = $props["component"] ?? "\\Crispage\\Components\\DefaultComponent";
|
||||
$this->location = $props["location"] ?? "default";
|
||||
$this->position = $props["position"] ?? 0;
|
||||
$this->enabled = $props["enabled"] ?? false;
|
||||
}
|
||||
|
||||
public function config(string $key, $default = null) {
|
||||
return $this->_options_array["config"][$key] ?? $default;
|
||||
}
|
||||
}
|
||||
?>
|
146
patch/core/app/assets/class/Plugin.php
Normal file
146
patch/core/app/assets/class/Plugin.php
Normal file
@ -0,0 +1,146 @@
|
||||
<?php
|
||||
/*
|
||||
Crispage CMS
|
||||
crispycat <the@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\Assets;
|
||||
|
||||
defined("ROOT") or die();
|
||||
|
||||
use \Crispage\Auth\CorePermissions;
|
||||
|
||||
class Plugin extends \Crispage\Asset {
|
||||
public static function getNames(): array {
|
||||
return ["{%PLUGIN}", "{%PLUGINS}"];
|
||||
}
|
||||
|
||||
public static function getPermissions(): array {
|
||||
return [
|
||||
"create" => CorePermissions::NEVER,
|
||||
"modify" => CorePermissions::MODIFY_SETTINGS,
|
||||
"modify_own"=> CorePermissions::MODIFY_SETTINGS,
|
||||
"delete" => CorePermissions::MODIFY_SETTINGS,
|
||||
"delete_own"=> CorePermissions::MODIFY_SETTINGS
|
||||
];
|
||||
}
|
||||
|
||||
public static function getSortingInfo(): array {
|
||||
return [
|
||||
"field" => "priority",
|
||||
"desc" => false
|
||||
];
|
||||
}
|
||||
|
||||
public static function getListColumns(): array {
|
||||
global $Crispage;
|
||||
return [
|
||||
"id" => ["label" => "{%ID}"],
|
||||
"runnable" => [
|
||||
"label" => "{%TYPE}",
|
||||
"filter" => "\\Crispage\\Utils\\TextUtils::codeify"
|
||||
],
|
||||
"priority" => [
|
||||
"label" => "{%PRIORITY}",
|
||||
"filter" => null
|
||||
],
|
||||
"enabled" => [
|
||||
"label" => "{%STATE}",
|
||||
"filter" => function(bool $s): string {
|
||||
global $Crispage;
|
||||
return $Crispage->i18n->translate(
|
||||
($s) ? "{%ENABLED}" : "{%DISABLED}"
|
||||
);
|
||||
}
|
||||
],
|
||||
"mtime" => [
|
||||
"label" => "{%MODIFIED}",
|
||||
"filter" => [$Crispage->i18n, "datetime"]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public static function getListActions(): array {
|
||||
return [];
|
||||
}
|
||||
|
||||
public static function getListItemActions(): array {
|
||||
return [
|
||||
[
|
||||
"route" => "assets/editor",
|
||||
"label" => "{%EDIT}",
|
||||
"color" => "primary",
|
||||
"fields" => [
|
||||
"asset_id" => "id"
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public static function getEditorFields(): array {
|
||||
return [
|
||||
"enabled" => [
|
||||
"column" => 0,
|
||||
"component" => "\\Crispage\\Components\\Fields\\BooleanFieldComponent",
|
||||
"com_data" => [
|
||||
"label" => "{%ENABLED}:"
|
||||
],
|
||||
"filter" => "boolval"
|
||||
],
|
||||
"priority" => [
|
||||
"column" => 1,
|
||||
"component" => "\\Crispage\\Components\\Fields\\NumberFieldComponent",
|
||||
"com_data" => [
|
||||
"label" => "{%PRIORITY}:",
|
||||
"attrs" => ["required"]
|
||||
],
|
||||
"filter" => "intval"
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public static function getOptionFields(): array {
|
||||
return [
|
||||
"config" => [
|
||||
"component" => "\\Crispage\\Components\\Fields\\PluginConfigFieldComponent",
|
||||
"com_data" => [],
|
||||
"filter" => function($data): array {
|
||||
global $Crispage;
|
||||
if (!is_array($data)) return [];
|
||||
$asset = $Crispage->assets->get(
|
||||
intval($Crispage->request->params["asset_id"]) ?? 0
|
||||
);
|
||||
|
||||
$Crispage->loadClass($asset->component);
|
||||
|
||||
$ndata = [];
|
||||
foreach ($asset->component::getPluginFields() as $name => $field)
|
||||
$ndata[$name] = $field["filter"]($data[$name] ?? null);
|
||||
return $ndata;
|
||||
}
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public string $runnable;
|
||||
public int $priority;
|
||||
public bool $enabled;
|
||||
|
||||
public function __construct(array $props) {
|
||||
parent::__construct($props);
|
||||
$this->runnable = $props["runnable"] ?? "\\Crispage\\Plugins\\DefaultPluginRunnable";
|
||||
$this->priority = $props["priority"] ?? 0;
|
||||
$this->enabled = $props["enabled"] ?? false;
|
||||
}
|
||||
|
||||
public function config(string $key, $default = null) {
|
||||
return $this->_options_array["config"][$key] ?? $default;
|
||||
}
|
||||
}
|
||||
?>
|
122
patch/core/app/assets/class/Role.php
Normal file
122
patch/core/app/assets/class/Role.php
Normal file
@ -0,0 +1,122 @@
|
||||
<?php
|
||||
/*
|
||||
Crispage CMS
|
||||
crispycat <the@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\Assets;
|
||||
|
||||
defined("ROOT") or die();
|
||||
|
||||
require_once ROOT . "/core/app/assets/Asset.php";
|
||||
|
||||
use \Crispage\Auth\CorePermissions;
|
||||
|
||||
class Role extends \Crispage\Asset {
|
||||
public static function getNames(): array {
|
||||
return ["{%ROLE}", "{%ROLES}"];
|
||||
}
|
||||
|
||||
public static function getPermissions(): array {
|
||||
return [
|
||||
"create" => CorePermissions::MODIFY_ROLES,
|
||||
"modify" => CorePermissions::MODIFY_ROLES,
|
||||
"modify_own"=> CorePermissions::MODIFY_ROLES,
|
||||
"delete" => CorePermissions::MODIFY_ROLES,
|
||||
"delete_own"=> CorePermissions::MODIFY_ROLES
|
||||
];
|
||||
}
|
||||
|
||||
public static function getSortingInfo(): array {
|
||||
return [
|
||||
"field" => "rank",
|
||||
"desc" => false
|
||||
];
|
||||
}
|
||||
|
||||
public static function getListColumns(): array {
|
||||
global $Crispage;
|
||||
return [
|
||||
"id" => ["label" => "{%ID}"],
|
||||
"slug" => [
|
||||
"label" => "{%SLUG}",
|
||||
"filter" => "\\Crispage\\Utils\\TextUtils::codeify"
|
||||
],
|
||||
"name" => [
|
||||
"label" => "{%NAME}",
|
||||
"filter" => "htmlentities"
|
||||
],
|
||||
"rank" => [
|
||||
"label" => "{%RANK}",
|
||||
"filter" => null
|
||||
],
|
||||
"mtime" => [
|
||||
"label" => "{%MODIFIED}",
|
||||
"filter" => [$Crispage->i18n, "datetime"]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public static function getEditorFields(): array {
|
||||
return [
|
||||
"name" => [
|
||||
"column" => 0,
|
||||
"component" => "\\Crispage\\Components\\Fields\\TextFieldComponent",
|
||||
"com_data" => [
|
||||
"label" => "{%NAME}:",
|
||||
"attrs" => ["required"]
|
||||
],
|
||||
"filter" => "strval"
|
||||
],
|
||||
"permissions" => [
|
||||
"column" => 0,
|
||||
"component" => "\\Crispage\\Components\\Fields\\PermissionsFieldComponent",
|
||||
"com_data" => [
|
||||
"label" => "{%PERMISSIONS}:",
|
||||
"attrs" => ["required"]
|
||||
],
|
||||
"filter" => "intval"
|
||||
],
|
||||
"slug" => [
|
||||
"column" => 1,
|
||||
"component" => "\\Crispage\\Components\\Fields\\TextFieldComponent",
|
||||
"com_data" => [
|
||||
"label" => "{%SLUG}:",
|
||||
"attrs" => ["placeholder" => "automatic"]
|
||||
],
|
||||
"filter" => "strval"
|
||||
],
|
||||
"rank" => [
|
||||
"column" => 1,
|
||||
"component" => "\\Crispage\\Components\\Fields\\NumberFieldComponent",
|
||||
"com_data" => [
|
||||
"label" => "{%RANK}:",
|
||||
"attrs" => ["required"]
|
||||
],
|
||||
"filter" => "intval"
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public string $name;
|
||||
public int $permissions;
|
||||
public int $rank;
|
||||
|
||||
public function __construct(array $props) {
|
||||
parent::__construct($props);
|
||||
$this->name = $props["name"] ?? "";
|
||||
$this->permissions = $props["permissions"] ?? 0;
|
||||
$this->rank = $props["rank"] ?? 0;
|
||||
}
|
||||
|
||||
public function getName(): string {
|
||||
return $this->name;
|
||||
}
|
||||
}
|
||||
?>
|
189
patch/core/app/assets/class/User.php
Normal file
189
patch/core/app/assets/class/User.php
Normal file
@ -0,0 +1,189 @@
|
||||
<?php
|
||||
/*
|
||||
Crispage CMS
|
||||
crispycat <the@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\Assets;
|
||||
|
||||
defined("ROOT") or die();
|
||||
|
||||
require_once ROOT . "/core/app/assets/Asset.php";
|
||||
|
||||
use \Crispage\Auth\CorePermissions;
|
||||
|
||||
class User extends \Crispage\Asset {
|
||||
public const UNCONFIRMED = 0;
|
||||
public const CONFIRMED = 1;
|
||||
public const ACTIVATED = 2;
|
||||
|
||||
public static function getNames(): array {
|
||||
return ["{%USER}", "{%USERS}"];
|
||||
}
|
||||
|
||||
public static function getPermissions(): array {
|
||||
return [
|
||||
"create" => CorePermissions::NONE,
|
||||
"modify" => CorePermissions::MODIFY_OTHERS,
|
||||
"modify_own"=> CorePermissions::MODIFY_SELF,
|
||||
"delete" => CorePermissions::NEVER,
|
||||
"delete_own"=> CorePermissions::NEVER
|
||||
];
|
||||
}
|
||||
|
||||
public static function getSortingInfo(): array {
|
||||
return [
|
||||
"field" => "mtime",
|
||||
"desc" => true
|
||||
];
|
||||
}
|
||||
|
||||
public static function getListColumns(): array {
|
||||
global $Crispage;
|
||||
return [
|
||||
"id" => ["label" => "{%ID}"],
|
||||
"slug" => [
|
||||
"label" => "{%USERNAME}",
|
||||
"filter" => "\\Crispage\\Utils\\TextUtils::codeify"
|
||||
],
|
||||
"displayname" => [
|
||||
"label" => "{%DISPLAY_NAME}",
|
||||
"filter" => "htmlentities"
|
||||
],
|
||||
"last_login" => [
|
||||
"label" => "{%LAST_LOGIN}",
|
||||
"filter" => [$Crispage->i18n, "datetime"]
|
||||
],
|
||||
"state" => [
|
||||
"label" => "{%STATE}",
|
||||
"filter" => function(int $s): string {
|
||||
global $Crispage;
|
||||
switch ($s) {
|
||||
case self::CONFIRMED:
|
||||
$str = "CONFIRMED";
|
||||
break;
|
||||
case self::ACTIVATED:
|
||||
$str = "ACTIVATED";
|
||||
break;
|
||||
default:
|
||||
$str = "UNCONFIRMED";
|
||||
}
|
||||
return $Crispage->i18n->translate("{%$str}");
|
||||
}
|
||||
],
|
||||
"mtime" => [
|
||||
"label" => "{%MODIFIED}",
|
||||
"filter" => [$Crispage->i18n, "datetime"]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public static function getEditorFields(): array {
|
||||
return [
|
||||
"displayname" => [
|
||||
"column" => 0,
|
||||
"component" => "\\Crispage\\Components\\Fields\\TextFieldComponent",
|
||||
"com_data" => [
|
||||
"label" => "{%DISPLAY_NAME}:",
|
||||
"attrs" => ["required"]
|
||||
],
|
||||
"filter" => "strval"
|
||||
],
|
||||
"email" => [
|
||||
"column" => 0,
|
||||
"component" => "\\Crispage\\Components\\Fields\\TextFieldComponent",
|
||||
"com_data" => [
|
||||
"label" => "{%EMAIL}:",
|
||||
"attrs" => ["required"]
|
||||
],
|
||||
"filter" => "strval"
|
||||
],
|
||||
"role_ids" => [
|
||||
"column" => 1,
|
||||
"component" => "\\Crispage\\Components\\Fields\\RoleSelectFieldComponent",
|
||||
"com_data" => [
|
||||
"label" => "{%ROLES}:"
|
||||
],
|
||||
"filter" => function($data): string {
|
||||
if (!is_array($data)) return "[]";
|
||||
$data = array_filter($data, "ctype_digit");
|
||||
return json_encode(array_values($data));
|
||||
}
|
||||
],
|
||||
"state" => [
|
||||
"column" => 1,
|
||||
"component" => "\\Crispage\\Components\\Fields\\SelectFieldComponent",
|
||||
"com_data" => [
|
||||
"label" => "{%STATE}:",
|
||||
"options" => [
|
||||
0 => "{%DEACTIVATED}",
|
||||
2 => "{%ACTIVATED}"
|
||||
]
|
||||
],
|
||||
"filter" => "intval"
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public string $displayname;
|
||||
public string $email;
|
||||
public int $last_login;
|
||||
public string $role_ids;
|
||||
private array $_role_ids_array;
|
||||
public int $state;
|
||||
|
||||
public function __construct(array $props) {
|
||||
parent::__construct($props);
|
||||
$this->displayname = $props["displayname"] ?? $props["slug"] ?? "";
|
||||
$this->email = $props["email"] ?? "";
|
||||
$this->last_login = $props["last_login"] ?? 0;
|
||||
$this->role_ids = $props["role_ids"] ?? "[]";
|
||||
$this->_role_ids_array = json_decode($this->role_ids, true) ?? [];
|
||||
$this->state = $props["state"] ?? 0;
|
||||
}
|
||||
|
||||
public function getRoles(): array {
|
||||
return $this->_role_ids_array;
|
||||
}
|
||||
|
||||
public function hasRole(int $id): bool {
|
||||
return in_array($id, $this->_role_ids_array);
|
||||
}
|
||||
|
||||
public function setRoles(int ...$ids): array {
|
||||
$this->_role_ids_array = $ids;
|
||||
$this->role_ids = json_encode($this->_role_ids_array);
|
||||
return $this->_role_ids_array;
|
||||
}
|
||||
|
||||
public function addRoles(int ...$ids): array {
|
||||
$this->_role_ids_array = array_unique(array_merge(
|
||||
$this->_role_ids_array, $ids
|
||||
));
|
||||
$this->role_ids = json_encode($this->_role_ids_array);
|
||||
return $this->_role_ids_array;
|
||||
}
|
||||
|
||||
public function removeRoles(int ...$ids): array {
|
||||
$this->_role_ids_array = array_filter(
|
||||
$this->_role_ids_array, fn(int $id): bool => !in_array($id, $ids)
|
||||
);
|
||||
$this->role_ids = json_encode($this->_role_ids_array);
|
||||
return $this->_role_ids_array;
|
||||
}
|
||||
|
||||
public function getName(): string {
|
||||
return $this->displayname;
|
||||
}
|
||||
|
||||
public function getOwnerId(): int {
|
||||
return $this->id;
|
||||
}
|
||||
}
|
||||
?>
|
71
patch/core/app/extensions/CoreExtensions.php
Normal file
71
patch/core/app/extensions/CoreExtensions.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
/*
|
||||
Crispage CMS
|
||||
crispycat <the@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\Extensions;
|
||||
|
||||
defined("ROOT") or die();
|
||||
|
||||
class CoreExtensions {
|
||||
public static function get(): array {
|
||||
return [
|
||||
/*
|
||||
new Extension(
|
||||
id, version, package,
|
||||
classname, type, data
|
||||
),
|
||||
*/
|
||||
|
||||
new Extension(
|
||||
"crispage.core", VERSION, "crispage.core",
|
||||
"crispage.core", "package", []
|
||||
),
|
||||
|
||||
// Actions
|
||||
|
||||
new Extension(
|
||||
"crispage.actions.default", VERSION, "crispage.core",
|
||||
"\\Crispage\\Actions\\DefaultAction",
|
||||
"action", []
|
||||
),
|
||||
|
||||
|
||||
// Components
|
||||
new Extension(
|
||||
"crispage.components.default", VERSION, "crispage.core",
|
||||
"\\Crispage\\Components\\DefaultComponent",
|
||||
"component", ["is_module" => true]
|
||||
),
|
||||
|
||||
|
||||
// Plugins
|
||||
new Extension(
|
||||
"crispage.plugins.default", VERSION, "crispage.core",
|
||||
"\\Crispage\\Plugins\\DefaultPluginRunnable",
|
||||
"component", []
|
||||
),
|
||||
|
||||
|
||||
// Templates
|
||||
new Extension(
|
||||
"crispage.templates.default", VERSION, "crispage.core",
|
||||
"default", "template", []
|
||||
),
|
||||
|
||||
// Translations
|
||||
new Extension(
|
||||
"crispage.translations.en_us.default", VERSION, "crispage.core",
|
||||
"en-US_default", "translation", []
|
||||
)
|
||||
];
|
||||
}
|
||||
}
|
||||
?>
|
41
patch/core/components/Crispage/Components/DefaultComponent.php
Executable file
41
patch/core/components/Crispage/Components/DefaultComponent.php
Executable file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/*
|
||||
Crispage CMS
|
||||
crispycat <the@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\Components;
|
||||
|
||||
defined("ROOT") or die();
|
||||
|
||||
class DefaultComponent extends \Crispage\Response\Component
|
||||
implements \Crispage\Response\ModuleComponent {
|
||||
public static function getExtensionInfo(): array {
|
||||
return [
|
||||
"id" => "crispage.components.default",
|
||||
"version" => VERSION,
|
||||
"name" => "default",
|
||||
"author" => "crispycat",
|
||||
"description" => "The Crispage default module."
|
||||
];
|
||||
}
|
||||
|
||||
public static function getModuleFields(): array {
|
||||
return [];
|
||||
}
|
||||
|
||||
public function __construct(\Crispage $app, array $data) {
|
||||
parent::__construct($app, $data);
|
||||
}
|
||||
|
||||
public function render(): void {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
?>
|
64
patch/core/components/Crispage/Components/ErrorInfoComponent.php
Executable file
64
patch/core/components/Crispage/Components/ErrorInfoComponent.php
Executable file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/*
|
||||
Crispage CMS
|
||||
crispycat <the@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\Components;
|
||||
|
||||
defined("ROOT") or die();
|
||||
|
||||
class ErrorInfoComponent extends \Crispage\Response\Component {
|
||||
public const TITLES = [
|
||||
400 => "BAD_REQUEST",
|
||||
401 => "UNAUTHORIZED",
|
||||
403 => "FORBIDDEN",
|
||||
404 => "PAGE_NOT_FOUND",
|
||||
500 => "INTERNAL_SERVER_ERROR"
|
||||
];
|
||||
|
||||
public static function getExtensionInfo(): array {
|
||||
return [
|
||||
"id" => "crispage.components.errorinfo",
|
||||
"version" => VERSION
|
||||
];
|
||||
}
|
||||
|
||||
public function __construct(\Crispage $app, array $data) {
|
||||
parent::__construct($app, $data);
|
||||
}
|
||||
|
||||
public function render(): void {
|
||||
$exceptions = $this->data["exceptions"] ?? [];
|
||||
if (empty($exceptions)) return;
|
||||
|
||||
$code = $exceptions[0]->getCode();
|
||||
$message = $exceptions[0]->getMessage();
|
||||
$title = $this->app->i18n->getTranslation(self::TITLES[$code] ?? "ERROR");
|
||||
|
||||
echo "<h1 class=\"title is-1\"><span class=\"tag is-danger is-large\">"
|
||||
. "$code</span> $title</h1><p class=\"subtitle is-3\">$message</p>";
|
||||
|
||||
($this->app->i18n)("<p>{%AN_ERROR_HAS_OCCURRED_}</p>");
|
||||
|
||||
|
||||
if (!$exceptions[0]->showDebug) return;
|
||||
|
||||
echo "<hr/>";
|
||||
|
||||
($this->app->i18n)("<h2 class=\"title is-2\">{%DEBUG_INFO}</h2>\n<pre>");
|
||||
foreach ($exceptions as $ind => $exception) {
|
||||
if (!$exception->showDebug ?? true) continue;
|
||||
echo "=======[Exception $ind]=======\n$exception\n\n";
|
||||
}
|
||||
|
||||
echo "</pre>";
|
||||
}
|
||||
}
|
||||
?>
|
91
patch/core/components/Crispage/Components/HeadTagsComponent.php
Executable file
91
patch/core/components/Crispage/Components/HeadTagsComponent.php
Executable file
@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/*
|
||||
Crispage CMS
|
||||
crispycat <the@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\Components;
|
||||
|
||||
defined("ROOT") or die();
|
||||
|
||||
class HeadTagsComponent extends \Crispage\Response\Component {
|
||||
public static function getExtensionInfo(): array {
|
||||
return [
|
||||
"id" => "crispage.components.headtags",
|
||||
"version" => VERSION
|
||||
];
|
||||
}
|
||||
|
||||
public function __construct(\Crispage $app, array $data) {
|
||||
parent::__construct($app, $data);
|
||||
}
|
||||
|
||||
public function render(): void {
|
||||
$blocks = $this->data["render"] ?? ["title", "metas", "links", "scripts", "styles"];
|
||||
|
||||
foreach ($blocks as $block) {
|
||||
switch ($block) {
|
||||
case "title": {
|
||||
$title = $this->app->page->data["title"] ?? "";
|
||||
|
||||
$asset = $this->app->assets->get($this->app->route->data["asset_id"] ?? 0);
|
||||
if ($asset && !$asset->getOption("show_title_suffix", true)) {
|
||||
$prefix = "";
|
||||
$suffix = "";
|
||||
}
|
||||
else {
|
||||
$prefix = $this->app->settings->get("crispage.page.title_prefix", "");
|
||||
$suffix = $this->app->settings->get("crispage.page.title_suffix", "");
|
||||
}
|
||||
echo "<title>$prefix$title$suffix</title>";
|
||||
break;
|
||||
}
|
||||
case "metas": {
|
||||
foreach ($this->app->page->data["metas"] as $meta) {
|
||||
if (!$meta) continue;
|
||||
echo "<meta";
|
||||
foreach ($meta as $attr => $val) echo " $attr=\"$val\"";
|
||||
echo ">";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "links": {
|
||||
foreach ($this->app->page->data["links"] as $link) {
|
||||
if (!$link) continue;
|
||||
echo "<link";
|
||||
foreach ($link as $attr => $val) echo " $attr=\"$val\"";
|
||||
echo ">";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "scripts": {
|
||||
foreach ($this->app->page->data["scripts"] as $script) {
|
||||
if (!$script) continue;
|
||||
echo "<script";
|
||||
foreach ($script as $attr => $val)
|
||||
if ($attr != "_inner") echo " $attr=\"$val\"";
|
||||
echo ">" . ($script["_inner"] ?? "") . "</script>";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "styles": {
|
||||
foreach ($this->app->page->data["styles"] as $style) {
|
||||
if (!$style) continue;
|
||||
echo "<style";
|
||||
foreach ($style as $attr => $val)
|
||||
if ($attr != "_inner") echo " $attr=\"$val\"";
|
||||
echo ">" . ($style["_inner"] ?? "") . "</style>";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
41
patch/core/components/Crispage/Components/MessagesComponent.php
Executable file
41
patch/core/components/Crispage/Components/MessagesComponent.php
Executable file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/*
|
||||
Crispage CMS
|
||||
crispycat <the@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\Components;
|
||||
|
||||
defined("ROOT") or die();
|
||||
|
||||
class MessagesComponent extends \Crispage\Response\Component {
|
||||
public static function getExtensionInfo(): array {
|
||||
return [
|
||||
"id" => "crispage.components.messages",
|
||||
"version" => VERSION
|
||||
];
|
||||
}
|
||||
|
||||
public function __construct(\Crispage $app, array $data) {
|
||||
parent::__construct($app, $data);
|
||||
}
|
||||
|
||||
public function render(): void {
|
||||
?>
|
||||
<div id="messages">
|
||||
<?php foreach ($this->app->page->data["messages"] as $id => $msg) { ?>
|
||||
<div id="msg_<?php echo $id; ?>" class="notification is-<?php echo $msg["color"]; ?> mb-2">
|
||||
<?php echo $msg["content"]; ?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
?>
|
1
patch/core/templates/default/layouts/api.php
Normal file
1
patch/core/templates/default/layouts/api.php
Normal file
@ -0,0 +1 @@
|
||||
<?php $this->app->page->renderMainComponent(); ?>
|
36
patch/core/templates/default/layouts/default.php
Normal file
36
patch/core/templates/default/layouts/default.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
$com_head = $this->app->page->createComponent(
|
||||
"\\Crispage\\Components\\HeadTagsComponent",
|
||||
["render" => ["title", "metas", "links", "scripts", "styles"]]
|
||||
);
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="<?php echo $this->app->i18n->getLanguage(); ?>" dir="<?php echo $this->app->i18n->getDirection(); ?>">
|
||||
<head>
|
||||
<?php $this->app->page->renderComponent($com_head); ?>
|
||||
<style>
|
||||
html {
|
||||
background: #7f7f7f;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #ffffff;
|
||||
font-family: monospace;
|
||||
width: 100%;
|
||||
max-width: 960px;
|
||||
margin: 20px auto;
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
$com_msgs = $this->app->page->createComponent(
|
||||
"\\Crispage\\Components\\MessagesComponent", []
|
||||
);
|
||||
$this->app->page->renderComponent($com_msgs);
|
||||
$this->app->page->renderMainComponent();
|
||||
?>
|
||||
</body>
|
||||
</html>
|
34
patch/user/actions/CrispageLite/DefaultAction.php
Executable file
34
patch/user/actions/CrispageLite/DefaultAction.php
Executable file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/*
|
||||
Crispage CMS
|
||||
crispycat <the@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 CrispageLite;
|
||||
|
||||
defined("ROOT") or die();
|
||||
|
||||
class DefaultAction extends \Crispage\Response\Action {
|
||||
public static function getExtensionInfo(): array {
|
||||
return [
|
||||
"id" => "crispagelite.defaultaction",
|
||||
"version" => VERSION
|
||||
];
|
||||
}
|
||||
|
||||
public function __construct(\Crispage $app, array $data) {
|
||||
parent::__construct($app, $data);
|
||||
}
|
||||
|
||||
public function run(): void {
|
||||
$this->app->page->setPersistentMessage("lite_installed", "Crispage Lite has been installed successfully.");
|
||||
$this->app->page->actionFinished();
|
||||
}
|
||||
}
|
||||
?>
|
Reference in New Issue
Block a user