155 lines
4.4 KiB
PHP
155 lines
4.4 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use Illuminate\Support\Facades\Cache;
|
|
|
|
class XenforoService {
|
|
|
|
private const array PERMISSIONS_KEPT = [ 'general', 'romhackplaza' ];
|
|
private const int TTL_PERMISSIONS = 300;
|
|
private const int TTL_ROUTES = 86400;
|
|
|
|
/**
|
|
* Get permissions for a specific user ID.
|
|
*
|
|
* @param int $userId
|
|
* @param int $permissionCombinationId
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getPermissions(int $userId, int $permissionCombinationId): array {
|
|
|
|
return Cache::remember("xf_permissions_{$userId}", self::TTL_PERMISSIONS, function() use($permissionCombinationId) {
|
|
$row = \DB::connection('xenforo')
|
|
->table('permission_combination')
|
|
->where('permission_combination_id', $permissionCombinationId)
|
|
->value('cache_value');
|
|
|
|
if( !$row )
|
|
return [];
|
|
|
|
$data = json_decode($row, true);
|
|
$data = array_intersect_key($data, array_flip(self::PERMISSIONS_KEPT));
|
|
|
|
return $data ?: [];
|
|
|
|
});
|
|
|
|
}
|
|
|
|
/**
|
|
* Clear user data.
|
|
*
|
|
* @param int $userId
|
|
*
|
|
* @return void
|
|
*/
|
|
public function clearUserData(int $userId): void
|
|
{
|
|
Cache::forget("xf_permissions_{$userId}");
|
|
}
|
|
|
|
/**
|
|
*
|
|
*
|
|
* @param string $routeName <prefix>.<secname>
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getRoute( string $routeName, array $arguments ): string {
|
|
|
|
$routes = Cache::remember("xf_routes", self::TTL_ROUTES, function(){
|
|
return \DB::connection('xenforo')
|
|
->table('route')
|
|
->where('route_type', 'public' )
|
|
->get(['route_prefix', 'sub_name', 'format'])
|
|
->map(fn($r) => (array) $r )
|
|
->toArray();
|
|
});
|
|
|
|
$baseUrl = config('app.forum_url');
|
|
|
|
try {
|
|
[$prefix, $subName] = explode('.', $routeName, 2);
|
|
|
|
$route = collect($routes)->first(function ($r) use ($prefix, $subName) {
|
|
return $r['route_prefix'] === $prefix && $r['sub_name'] === $subName;
|
|
});
|
|
|
|
if( !$route )
|
|
return $baseUrl . '/' . $prefix;
|
|
|
|
$path = $this->buildRoutePath((array)$route, $arguments);
|
|
return rtrim($baseUrl, '/') . '/' . $path;
|
|
|
|
} catch (\Throwable $th) {
|
|
$prefix = $routeName;
|
|
|
|
$route = collect($routes)->first(function ($r) use ($prefix) {
|
|
return $r['route_prefix'] === $prefix;
|
|
});
|
|
|
|
if( !$route )
|
|
return $baseUrl . '/' . $prefix;
|
|
|
|
$path = $this->buildRoutePath((array)$route, $arguments);
|
|
return rtrim($baseUrl, '/') . '/' . $path;
|
|
}
|
|
|
|
}
|
|
|
|
private function buildRoutePath(array $route, array $arguments): string {
|
|
|
|
$prefix = $route['route_prefix'];
|
|
$format = $route['format'];
|
|
$subName = $route['sub_name'];
|
|
|
|
if (!$format) {
|
|
return $subName
|
|
? $prefix . '-/' . $subName
|
|
: $prefix;
|
|
}
|
|
|
|
if (str_starts_with($format, '-/')) {
|
|
return $prefix . $format;
|
|
}
|
|
|
|
$built = preg_replace_callback(
|
|
'/:\+?(\w+)(?:_\w+)?(?:<([^>]+)>)?/',
|
|
function(array $m) use ($arguments): string {
|
|
$type = $m[1];
|
|
$keys = isset($m[2])
|
|
? explode(',', $m[2])
|
|
: [];
|
|
|
|
return match(true) {
|
|
|
|
$type === 'page' => isset($params['page']) && $params['page'] > 1
|
|
? 'page-' . $params['page']
|
|
: '',
|
|
|
|
$type === 'str_int' && count($keys) >= 2 => implode('.', array_filter([
|
|
$params[$keys[0]] ?? null,
|
|
$params[$keys[1]] ?? null,
|
|
])),
|
|
|
|
$type === 'int' && count($keys) >= 1 => (string) ($params[$keys[0]] ?? ''),
|
|
|
|
in_array($type, ['str', 'any']) && count($keys) >= 1
|
|
=> (string) ($params[$keys[0]] ?? ''),
|
|
|
|
default => isset($params[$type]) ? (string) $params[$type] : '',
|
|
};
|
|
},
|
|
$format
|
|
);
|
|
|
|
$built = preg_replace('/\/+/', '/', $prefix . '/' . $built);
|
|
$built = rtrim($built, '/');
|
|
|
|
return $built;
|
|
|
|
}
|
|
}
|