Files
AudioCore/core/services/Permissions.php
2026-03-04 20:46:11 +00:00

146 lines
4.7 KiB
PHP

<?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);
}
}