v7.0.0-beta.2 release
This commit is contained in:
1 parent
6595fd0eb5
commit
fa8eba7a0d
1165 files changed
+107118
-762127
No files matched your search
@@ -3,24 +3,27 @@
|
||||
namespace App\Extension;
|
||||
|
||||
use App\Contracts\Extension\HookManagerInterface;
|
||||
use App\Events\GenericBroadcastEvent;
|
||||
use App\Models\PermissionHook;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class HookManager implements HookManagerInterface
|
||||
{
|
||||
private static array $hooks = [];
|
||||
|
||||
private static array $filters = [];
|
||||
|
||||
private static array $dispatching = [];
|
||||
|
||||
/**
|
||||
* Hook 이벤트를 발생시켜 등록된 콜백들을 실행합니다.
|
||||
*
|
||||
* @param string $hookName Hook 이름
|
||||
* @param mixed ...$args Hook에 전달할 인수들
|
||||
* @return void
|
||||
* @param string $hookName Hook 이름
|
||||
* @param mixed ...$args Hook에 전달할 인수들
|
||||
*/
|
||||
public static function doAction(string $hookName, ...$args): void
|
||||
{
|
||||
@@ -50,9 +53,9 @@ class HookManager implements HookManagerInterface
|
||||
/**
|
||||
* Filter를 적용하여 데이터를 변환합니다.
|
||||
*
|
||||
* @param string $filterName Filter 이름
|
||||
* @param mixed $value 변환할 원본 값
|
||||
* @param mixed ...$args Filter에 전달할 추가 인수들
|
||||
* @param string $filterName Filter 이름
|
||||
* @param mixed $value 변환할 원본 값
|
||||
* @param mixed ...$args Filter에 전달할 추가 인수들
|
||||
* @return mixed 변환된 값
|
||||
*/
|
||||
public static function applyFilters(string $filterName, $value, ...$args)
|
||||
@@ -60,7 +63,7 @@ class HookManager implements HookManagerInterface
|
||||
$eventName = "filter.{$filterName}";
|
||||
|
||||
// 등록된 필터가 있는지 확인
|
||||
if (!isset(self::$filters[$filterName])) {
|
||||
if (! isset(self::$filters[$filterName])) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
@@ -81,18 +84,17 @@ class HookManager implements HookManagerInterface
|
||||
/**
|
||||
* Hook 이벤트에 콜백 함수를 등록합니다.
|
||||
*
|
||||
* @param string $hookName Hook 이름
|
||||
* @param callable $callback 실행할 콜백 함수
|
||||
* @param int $priority 실행 우선순위 (기본값: 10)
|
||||
* @return void
|
||||
* @param string $hookName Hook 이름
|
||||
* @param callable $callback 실행할 콜백 함수
|
||||
* @param int $priority 실행 우선순위 (기본값: 10)
|
||||
*/
|
||||
public static function addAction(string $hookName, callable $callback, int $priority = 10): void
|
||||
{
|
||||
if (!isset(self::$hooks[$hookName])) {
|
||||
if (! isset(self::$hooks[$hookName])) {
|
||||
self::$hooks[$hookName] = [];
|
||||
}
|
||||
|
||||
if (!isset(self::$hooks[$hookName][$priority])) {
|
||||
if (! isset(self::$hooks[$hookName][$priority])) {
|
||||
self::$hooks[$hookName][$priority] = [];
|
||||
}
|
||||
|
||||
@@ -100,7 +102,7 @@ class HookManager implements HookManagerInterface
|
||||
|
||||
// Laravel 이벤트 시스템에도 등록 (가드 래핑으로 doAction 실행 중 중복 방지)
|
||||
Event::listen("hook.{$hookName}", function (...$args) use ($hookName, $callback) {
|
||||
if (!empty(self::$dispatching[$hookName])) {
|
||||
if (! empty(self::$dispatching[$hookName])) {
|
||||
return; // doAction() 내부 배열에서 이미 실행됨 → 스킵
|
||||
}
|
||||
call_user_func_array($callback, $args);
|
||||
@@ -110,30 +112,63 @@ class HookManager implements HookManagerInterface
|
||||
/**
|
||||
* Filter에 콜백 함수를 등록합니다.
|
||||
*
|
||||
* @param string $filterName Filter 이름
|
||||
* @param callable $callback 실행할 콜백 함수
|
||||
* @param int $priority 실행 우선순위 (기본값: 10)
|
||||
* @return void
|
||||
* @param string $filterName Filter 이름
|
||||
* @param callable $callback 실행할 콜백 함수
|
||||
* @param int $priority 실행 우선순위 (기본값: 10)
|
||||
*/
|
||||
public static function addFilter(string $filterName, callable $callback, int $priority = 10): void
|
||||
{
|
||||
if (!isset(self::$filters[$filterName])) {
|
||||
if (! isset(self::$filters[$filterName])) {
|
||||
self::$filters[$filterName] = [];
|
||||
}
|
||||
|
||||
if (!isset(self::$filters[$filterName][$priority])) {
|
||||
if (! isset(self::$filters[$filterName][$priority])) {
|
||||
self::$filters[$filterName][$priority] = [];
|
||||
}
|
||||
|
||||
self::$filters[$filterName][$priority][] = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* WebSocket 브로드캐스트를 실행합니다.
|
||||
*
|
||||
* broadcast(new Event(...)) 직접 호출 대신 이 메서드를 사용합니다.
|
||||
* 내부적으로 GenericBroadcastEvent를 생성하여 Laravel broadcast()를 실행합니다.
|
||||
*
|
||||
* @param string $channel 채널명 (예: 'admin.dashboard', 'user.notifications.123')
|
||||
* @param string $eventName 이벤트명 (예: 'dashboard.stats.updated', 'notification.received')
|
||||
* @param array $payload 브로드캐스트 데이터
|
||||
*/
|
||||
public static function broadcast(string $channel, string $eventName, array $payload = []): void
|
||||
{
|
||||
$driver = config('broadcasting.default');
|
||||
|
||||
if (in_array($driver, ['null', 'log', null], true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Reverb/Pusher 드라이버: 호스트 미설정 시 연결 시도 없이 건너뜀
|
||||
$connection = config("broadcasting.connections.{$driver}");
|
||||
if (empty($connection['options']['host'] ?? null)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
broadcast(new GenericBroadcastEvent($channel, $eventName, $payload));
|
||||
} catch (\Throwable $e) {
|
||||
Log::warning('브로드캐스트 실패 (Reverb 미실행 가능)', [
|
||||
'channel' => $channel,
|
||||
'event' => $eventName,
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook 이벤트에서 콜백 함수를 제거합니다.
|
||||
*
|
||||
* @param string $hookName Hook 이름
|
||||
* @param callable $callback 제거할 콜백 함수
|
||||
* @return void
|
||||
* @param string $hookName Hook 이름
|
||||
* @param callable $callback 제거할 콜백 함수
|
||||
*/
|
||||
public static function removeAction(string $hookName, callable $callback): void
|
||||
{
|
||||
@@ -153,9 +188,8 @@ class HookManager implements HookManagerInterface
|
||||
/**
|
||||
* Filter에서 콜백 함수를 제거합니다.
|
||||
*
|
||||
* @param string $filterName Filter 이름
|
||||
* @param callable $callback 제거할 콜백 함수
|
||||
* @return void
|
||||
* @param string $filterName Filter 이름
|
||||
* @param callable $callback 제거할 콜백 함수
|
||||
*/
|
||||
public static function removeFilter(string $filterName, callable $callback): void
|
||||
{
|
||||
@@ -192,8 +226,7 @@ class HookManager implements HookManagerInterface
|
||||
/**
|
||||
* 특정 Hook에 등록된 모든 콜백을 제거합니다.
|
||||
*
|
||||
* @param string $hookName Hook 이름
|
||||
* @return void
|
||||
* @param string $hookName Hook 이름
|
||||
*/
|
||||
public static function clearAction(string $hookName): void
|
||||
{
|
||||
@@ -208,8 +241,7 @@ class HookManager implements HookManagerInterface
|
||||
/**
|
||||
* 특정 Filter에 등록된 모든 콜백을 제거합니다.
|
||||
*
|
||||
* @param string $filterName Filter 이름
|
||||
* @return void
|
||||
* @param string $filterName Filter 이름
|
||||
*/
|
||||
public static function clearFilter(string $filterName): void
|
||||
{
|
||||
@@ -222,8 +254,6 @@ class HookManager implements HookManagerInterface
|
||||
* 테스트 환경에서 등록된 모든 Hook과 Filter를 초기화합니다.
|
||||
*
|
||||
* 주의: 이 메서드는 테스트 환경에서만 사용해야 합니다.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function resetAll(): void
|
||||
{
|
||||
@@ -238,15 +268,15 @@ class HookManager implements HookManagerInterface
|
||||
* permission_hooks 테이블에 해당 훅이 매핑되어 있으면
|
||||
* 현재 사용자가 해당 권한을 보유하고 있는지 확인합니다.
|
||||
*
|
||||
* @param string $hookName 훅 이름
|
||||
* @param User|null $user 사용자 (null이면 현재 인증된 사용자)
|
||||
* @return void
|
||||
* @param string $hookName 훅 이름
|
||||
* @param User|null $user 사용자 (null이면 현재 인증된 사용자)
|
||||
*
|
||||
* @throws AuthorizationException 권한이 없는 경우
|
||||
*/
|
||||
public static function checkHookPermission(string $hookName, ?User $user = null): void
|
||||
{
|
||||
// 훅에 권한 매핑이 없으면 모든 사용자 허용
|
||||
if (!PermissionHook::hasPermissionMapping($hookName)) {
|
||||
if (! PermissionHook::hasPermissionMapping($hookName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -254,7 +284,7 @@ class HookManager implements HookManagerInterface
|
||||
$user = $user ?? Auth::user();
|
||||
|
||||
// 비인증 사용자는 권한 매핑된 훅 접근 불가
|
||||
if (!$user) {
|
||||
if (! $user) {
|
||||
throw new AuthorizationException(__('auth.unauthorized'));
|
||||
}
|
||||
|
||||
@@ -278,10 +308,10 @@ class HookManager implements HookManagerInterface
|
||||
/**
|
||||
* 훅 실행 전 권한 체크 후 Action 실행
|
||||
*
|
||||
* @param string $hookName 훅 이름
|
||||
* @param User|null $user 권한 체크 대상 사용자
|
||||
* @param mixed ...$args 훅에 전달할 인자
|
||||
* @return void
|
||||
* @param string $hookName 훅 이름
|
||||
* @param User|null $user 권한 체크 대상 사용자
|
||||
* @param mixed ...$args 훅에 전달할 인자
|
||||
*
|
||||
* @throws AuthorizationException 권한이 없는 경우
|
||||
*/
|
||||
public static function doActionWithPermission(string $hookName, ?User $user = null, ...$args): void
|
||||
@@ -293,11 +323,12 @@ class HookManager implements HookManagerInterface
|
||||
/**
|
||||
* 훅 실행 전 권한 체크 후 Filter 실행
|
||||
*
|
||||
* @param string $hookName 훅 이름
|
||||
* @param User|null $user 권한 체크 대상 사용자
|
||||
* @param mixed $value 필터링할 값
|
||||
* @param mixed ...$args 필터에 전달할 추가 인자
|
||||
* @param string $hookName 훅 이름
|
||||
* @param User|null $user 권한 체크 대상 사용자
|
||||
* @param mixed $value 필터링할 값
|
||||
* @param mixed ...$args 필터에 전달할 추가 인자
|
||||
* @return mixed 필터링된 값
|
||||
*
|
||||
* @throws AuthorizationException 권한이 없는 경우
|
||||
*/
|
||||
public static function applyFiltersWithPermission(string $hookName, ?User $user = null, mixed $value = null, ...$args): mixed
|
||||
|
||||
Reference in new issue
Block a user