146 lines
4.7 KiB
PHP
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);
|
|
}
|
|
}
|