294 lines
9.7 KiB
PHP
294 lines
9.7 KiB
PHP
<?php
|
|
|
|
namespace classes;
|
|
|
|
use modules\subusers\helpers\subusers_permission_node_key;
|
|
|
|
class subuser_permission_templates_service
|
|
{
|
|
public const TEMPLATE_DEACTIVATED = 'deactivated';
|
|
public const TEMPLATE_DRIVER = 'driver';
|
|
public const TEMPLATE_BOOKING_COORDINATOR = 'booking_coordinator';
|
|
public const TEMPLATE_FLEET_ADMIN = 'fleet_admin';
|
|
public const TEMPLATE_CUSTOM = 'custom';
|
|
|
|
/**
|
|
* @var array<string, array{label:string,description:string,enabled:bool,permissions:array<int,string>}>
|
|
*/
|
|
private const TEMPLATES = [
|
|
self::TEMPLATE_DEACTIVATED => [
|
|
'label' => 'Deactivated',
|
|
'description' => 'Keeps the driver linked to the customer without active access.',
|
|
'enabled' => false,
|
|
'permissions' => [],
|
|
],
|
|
self::TEMPLATE_DRIVER => [
|
|
'label' => 'Driver',
|
|
'description' => 'Can use self-service, manage own bookings, see vehicles, and view orders.',
|
|
'enabled' => true,
|
|
'permissions' => [
|
|
'VEHICLES_LIST',
|
|
'SELFSERVE_LIST',
|
|
'SELFSERVE_ADD',
|
|
'BOOKINGS_LIST',
|
|
'BOOKINGS_ADD',
|
|
'ORDERS_LIST',
|
|
],
|
|
],
|
|
self::TEMPLATE_BOOKING_COORDINATOR => [
|
|
'label' => 'Booking coordinator',
|
|
'description' => 'Can coordinate bookings and see the related vehicles and orders.',
|
|
'enabled' => true,
|
|
'permissions' => [
|
|
'VEHICLES_LIST',
|
|
'BOOKINGS_LIST',
|
|
'BOOKINGS_ADD',
|
|
'BOOKINGS_EDIT',
|
|
'ORDERS_LIST',
|
|
],
|
|
],
|
|
self::TEMPLATE_FLEET_ADMIN => [
|
|
'label' => 'Fleet admin',
|
|
'description' => 'Can manage drivers, vehicles, bookings, self-service, and orders for the customer.',
|
|
'enabled' => true,
|
|
'permissions' => [
|
|
'VEHICLES_LIST',
|
|
'VEHICLES_EDIT',
|
|
'VEHICLES_DELETE',
|
|
'VEHICLES_ADD',
|
|
'SELFSERVE_LIST',
|
|
'SELFSERVE_EDIT',
|
|
'SELFSERVE_DELETE',
|
|
'SELFSERVE_ADD',
|
|
'BOOKINGS_LIST',
|
|
'BOOKINGS_EDIT',
|
|
'BOOKINGS_DELETE',
|
|
'BOOKINGS_ADD',
|
|
'ORDERS_LIST',
|
|
'ORDERS_EDIT',
|
|
'SUBUSERS_LIST',
|
|
'SUBUSERS_EDIT',
|
|
'SUBUSERS_DELETE',
|
|
'SUBUSERS_ADD',
|
|
],
|
|
],
|
|
];
|
|
|
|
/**
|
|
* @var array<string, array{group:string,capability:string}>
|
|
*/
|
|
private const PERMISSION_CAPABILITIES = [
|
|
'VEHICLES_LIST' => ['group' => 'vehicles', 'capability' => 'view_vehicles'],
|
|
'VEHICLES_EDIT' => ['group' => 'vehicles', 'capability' => 'edit_vehicles'],
|
|
'VEHICLES_DELETE' => ['group' => 'vehicles', 'capability' => 'delete_vehicles'],
|
|
'VEHICLES_ADD' => ['group' => 'vehicles', 'capability' => 'add_vehicles'],
|
|
'SELFSERVE_LIST' => ['group' => 'selfserve', 'capability' => 'view_selfserve'],
|
|
'SELFSERVE_EDIT' => ['group' => 'selfserve', 'capability' => 'edit_selfserve'],
|
|
'SELFSERVE_DELETE' => ['group' => 'selfserve', 'capability' => 'delete_selfserve'],
|
|
'SELFSERVE_ADD' => ['group' => 'selfserve', 'capability' => 'start_selfserve'],
|
|
'BOOKINGS_LIST' => ['group' => 'bookings', 'capability' => 'view_bookings'],
|
|
'BOOKINGS_EDIT' => ['group' => 'bookings', 'capability' => 'edit_bookings'],
|
|
'BOOKINGS_DELETE' => ['group' => 'bookings', 'capability' => 'delete_bookings'],
|
|
'BOOKINGS_ADD' => ['group' => 'bookings', 'capability' => 'add_bookings'],
|
|
'ORDERS_LIST' => ['group' => 'orders', 'capability' => 'view_orders'],
|
|
'ORDERS_EDIT' => ['group' => 'orders', 'capability' => 'edit_orders'],
|
|
'SUBUSERS_LIST' => ['group' => 'driver_management', 'capability' => 'view_drivers'],
|
|
'SUBUSERS_EDIT' => ['group' => 'driver_management', 'capability' => 'edit_driver_access'],
|
|
'SUBUSERS_DELETE' => ['group' => 'driver_management', 'capability' => 'disable_driver_access'],
|
|
'SUBUSERS_ADD' => ['group' => 'driver_management', 'capability' => 'invite_drivers'],
|
|
];
|
|
|
|
/**
|
|
* @var array<int, string>
|
|
*/
|
|
private const GROUP_ORDER = [
|
|
'vehicles',
|
|
'selfserve',
|
|
'bookings',
|
|
'orders',
|
|
'driver_management',
|
|
];
|
|
|
|
/**
|
|
* @return array<string, mixed>
|
|
*/
|
|
public function accessModel(): array
|
|
{
|
|
return [
|
|
'templates' => $this->templates(),
|
|
'groups' => $this->groups(),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @return array<int, array<string, mixed>>
|
|
*/
|
|
public function templates(): array
|
|
{
|
|
$templates = [];
|
|
foreach (self::TEMPLATES as $key => $template) {
|
|
$templates[] = [
|
|
'key' => $key,
|
|
'label' => $template['label'],
|
|
'description' => $template['description'],
|
|
'enabled' => $template['enabled'],
|
|
'permissions' => array_values($template['permissions']),
|
|
'permission_groups' => $this->permissionGroups($template['permissions']),
|
|
];
|
|
}
|
|
|
|
return $templates;
|
|
}
|
|
|
|
/**
|
|
* @return array<int, array{key:string,capabilities:array<int,string>}>
|
|
*/
|
|
public function groups(): array
|
|
{
|
|
$groups = [];
|
|
foreach (self::GROUP_ORDER as $group) {
|
|
$capabilities = [];
|
|
foreach (self::PERMISSION_CAPABILITIES as $capability) {
|
|
if ($capability['group'] === $group) {
|
|
$capabilities[] = $capability['capability'];
|
|
}
|
|
}
|
|
$groups[] = [
|
|
'key' => $group,
|
|
'capabilities' => array_values(array_unique($capabilities)),
|
|
];
|
|
}
|
|
|
|
return $groups;
|
|
}
|
|
|
|
/**
|
|
* @return array{enabled:bool,permissions:array<int,string>}
|
|
*/
|
|
public function expandTemplate(string $templateKey): array
|
|
{
|
|
$key = $this->normalizeTemplateKey($templateKey);
|
|
if ($key === null || $key === self::TEMPLATE_CUSTOM) {
|
|
throw new \InvalidArgumentException('Unknown driver access template.');
|
|
}
|
|
|
|
return [
|
|
'enabled' => self::TEMPLATES[$key]['enabled'],
|
|
'permissions' => array_values(self::TEMPLATES[$key]['permissions']),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @return array{enabled:bool,permissions:array<int,string>}|null
|
|
*/
|
|
public function expandTemplateForWritePayload(?string $templateKey): ?array
|
|
{
|
|
$key = $this->normalizeTemplateKey($templateKey);
|
|
if ($key === self::TEMPLATE_CUSTOM) {
|
|
return null;
|
|
}
|
|
|
|
if ($key === null) {
|
|
throw new \InvalidArgumentException('Unknown driver access template.');
|
|
}
|
|
|
|
return $this->expandTemplate($key);
|
|
}
|
|
|
|
public function normalizeTemplateKey(?string $templateKey): ?string
|
|
{
|
|
if ($templateKey === null) {
|
|
return null;
|
|
}
|
|
|
|
$key = strtolower(trim($templateKey));
|
|
if ($key === self::TEMPLATE_CUSTOM) {
|
|
return self::TEMPLATE_CUSTOM;
|
|
}
|
|
|
|
return array_key_exists($key, self::TEMPLATES) ? $key : null;
|
|
}
|
|
|
|
/**
|
|
* @param array<int, string> $permissions
|
|
*/
|
|
public function classify(array $permissions, bool $enabled = true): string
|
|
{
|
|
$normalized = $this->normalizePermissions($permissions);
|
|
if (!$enabled || $normalized === []) {
|
|
return self::TEMPLATE_DEACTIVATED;
|
|
}
|
|
|
|
foreach (self::TEMPLATES as $key => $template) {
|
|
if (!$template['enabled']) {
|
|
continue;
|
|
}
|
|
|
|
if ($normalized === $this->normalizePermissions($template['permissions'])) {
|
|
return $key;
|
|
}
|
|
}
|
|
|
|
return self::TEMPLATE_CUSTOM;
|
|
}
|
|
|
|
/**
|
|
* @param array<int, string> $permissions
|
|
* @return array<int, array{key:string,capabilities:array<int,string>}>
|
|
*/
|
|
public function permissionGroups(array $permissions): array
|
|
{
|
|
$permissions = $this->normalizePermissions($permissions);
|
|
$groups = [];
|
|
foreach ($permissions as $permission) {
|
|
$capability = self::PERMISSION_CAPABILITIES[$permission] ?? null;
|
|
if ($capability === null) {
|
|
continue;
|
|
}
|
|
|
|
$group = $capability['group'];
|
|
$groups[$group] ??= [];
|
|
$groups[$group][] = $capability['capability'];
|
|
}
|
|
|
|
$payload = [];
|
|
foreach (self::GROUP_ORDER as $group) {
|
|
if (!isset($groups[$group])) {
|
|
continue;
|
|
}
|
|
|
|
$payload[] = [
|
|
'key' => $group,
|
|
'capabilities' => array_values(array_unique($groups[$group])),
|
|
];
|
|
}
|
|
|
|
return $payload;
|
|
}
|
|
|
|
/**
|
|
* @param array<int, string> $permissions
|
|
* @return array<int, string>
|
|
*/
|
|
private function normalizePermissions(array $permissions): array
|
|
{
|
|
$normalized = [];
|
|
foreach ($permissions as $permission) {
|
|
if ($permission instanceof subusers_permission_node_key) {
|
|
$permission = $permission->name;
|
|
}
|
|
if (!is_string($permission)) {
|
|
continue;
|
|
}
|
|
$permission = strtoupper(trim($permission));
|
|
if ($permission !== '' && subusers_permission_node_key::tryFrom($permission) !== null) {
|
|
$normalized[] = $permission;
|
|
}
|
|
}
|
|
|
|
$normalized = array_values(array_unique($normalized));
|
|
sort($normalized);
|
|
return $normalized;
|
|
}
|
|
}
|