Initial dev export (exclude uploads/runtime)
This commit is contained in:
145
core/services/Permissions.php
Normal file
145
core/services/Permissions.php
Normal file
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Core\Services;
|
||||
|
||||
class Permissions
|
||||
{
|
||||
public static function definitions(): array
|
||||
{
|
||||
$defs = [
|
||||
['key' => 'core.dashboard', 'label' => 'Dashboard', 'group' => 'Core'],
|
||||
['key' => 'core.settings', 'label' => 'Settings', 'group' => 'Core'],
|
||||
['key' => 'core.navigation', 'label' => 'Navigation', 'group' => 'Core'],
|
||||
['key' => 'core.accounts', 'label' => 'Accounts', 'group' => 'Core'],
|
||||
['key' => 'core.plugins', 'label' => 'Plugins', 'group' => 'Core'],
|
||||
['key' => 'module.pages', 'label' => 'Pages', 'group' => 'Modules'],
|
||||
['key' => 'module.shortcodes', 'label' => 'Shortcodes', 'group' => 'Modules'],
|
||||
['key' => 'module.blog', 'label' => 'Blog', 'group' => 'Modules'],
|
||||
['key' => 'module.media', 'label' => 'Media', 'group' => 'Modules'],
|
||||
['key' => 'module.newsletter', 'label' => 'Newsletter', 'group' => 'Modules'],
|
||||
];
|
||||
|
||||
foreach (Plugins::all() as $plugin) {
|
||||
$slug = trim((string)($plugin['slug'] ?? ''));
|
||||
if ($slug === '') {
|
||||
continue;
|
||||
}
|
||||
$defs[] = [
|
||||
'key' => 'plugin.' . $slug,
|
||||
'label' => (string)($plugin['name'] ?? ucfirst($slug)),
|
||||
'group' => 'Plugins',
|
||||
];
|
||||
}
|
||||
|
||||
return $defs;
|
||||
}
|
||||
|
||||
public static function matrix(): array
|
||||
{
|
||||
$default = self::defaultMatrix();
|
||||
$raw = Settings::get('role_permissions_json', '');
|
||||
if ($raw === '') {
|
||||
return $default;
|
||||
}
|
||||
$decoded = json_decode($raw, true);
|
||||
if (!is_array($decoded)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
foreach ($default as $perm => $roles) {
|
||||
$row = $decoded[$perm] ?? null;
|
||||
if (!is_array($row)) {
|
||||
continue;
|
||||
}
|
||||
foreach (['admin', 'manager', 'editor'] as $role) {
|
||||
if (array_key_exists($role, $row)) {
|
||||
$default[$perm][$role] = self::toBool($row[$role]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
|
||||
public static function saveMatrix(array $posted): void
|
||||
{
|
||||
$current = self::matrix();
|
||||
foreach ($current as $permission => $roles) {
|
||||
foreach ($roles as $role => $allowed) {
|
||||
$current[$permission][$role] = isset($posted[$permission][$role]);
|
||||
}
|
||||
}
|
||||
Settings::set('role_permissions_json', json_encode($current, JSON_UNESCAPED_SLASHES));
|
||||
}
|
||||
|
||||
public static function can(string $role, string $permission): bool
|
||||
{
|
||||
$matrix = self::matrix();
|
||||
if (!isset($matrix[$permission])) {
|
||||
return true;
|
||||
}
|
||||
return (bool)($matrix[$permission][$role] ?? false);
|
||||
}
|
||||
|
||||
public static function routePermission(string $path): ?string
|
||||
{
|
||||
if ($path === '/admin') {
|
||||
return 'core.dashboard';
|
||||
}
|
||||
if (!str_starts_with($path, '/admin/')) {
|
||||
return null;
|
||||
}
|
||||
$slug = trim((string)explode('/', trim(substr($path, strlen('/admin/')), '/'))[0]);
|
||||
if ($slug === '' || in_array($slug, ['login', 'logout', 'install', 'installer'], true)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$coreMap = [
|
||||
'settings' => 'core.settings',
|
||||
'navigation' => 'core.navigation',
|
||||
'accounts' => 'core.accounts',
|
||||
'plugins' => 'core.plugins',
|
||||
'pages' => 'module.pages',
|
||||
'shortcodes' => 'module.shortcodes',
|
||||
'blog' => 'module.blog',
|
||||
'media' => 'module.media',
|
||||
'newsletter' => 'module.newsletter',
|
||||
];
|
||||
if (isset($coreMap[$slug])) {
|
||||
return $coreMap[$slug];
|
||||
}
|
||||
|
||||
return 'plugin.' . $slug;
|
||||
}
|
||||
|
||||
private static function defaultMatrix(): array
|
||||
{
|
||||
$matrix = [];
|
||||
foreach (self::definitions() as $def) {
|
||||
$key = (string)$def['key'];
|
||||
$matrix[$key] = [
|
||||
'admin' => true,
|
||||
'manager' => true,
|
||||
'editor' => false,
|
||||
];
|
||||
}
|
||||
foreach (['module.pages', 'module.shortcodes', 'module.blog'] as $editorAllowed) {
|
||||
if (isset($matrix[$editorAllowed])) {
|
||||
$matrix[$editorAllowed]['editor'] = true;
|
||||
}
|
||||
}
|
||||
return $matrix;
|
||||
}
|
||||
|
||||
private static function toBool(mixed $value): bool
|
||||
{
|
||||
if (is_bool($value)) {
|
||||
return $value;
|
||||
}
|
||||
if (is_int($value) || is_float($value)) {
|
||||
return ((int)$value) === 1;
|
||||
}
|
||||
$v = strtolower(trim((string)$value));
|
||||
return in_array($v, ['1', 'true', 'yes', 'on'], true);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user