Files
Gnuboard7/app/Http/Middleware/ExtensionMiddlewareGate.php
T
HeuJung c0e0d82459 refactor(extension): 확장 미들웨어 선언적 self-gate 정규화
확장이 SP Kernel 미들웨어 그룹을 직접 조작하거나 라우트 파일에 미들웨어
FQCN 을 직접 부착하던 임시 방식을, 확장이 부착 대상(targets)을 명시 선언하고
코어가 요청 시점에 라우트명·URI 로 매칭해 실행하는 self-gate 로 정규화.
번들 7건(ecommerce/gdpr/pay 3종) 이전, audit 룰 3건·문서·버전 동기화 동반.

부수적으로 generate-skills.cjs 가 재생성 시 신의성실(부수의무) 섹션을 소실
시키던 회귀를 수정 — 스킬별 불릿을 스크립트 SSoT 로 편입해 재생성에도 보존.
2026-07-16 10:22:51 +09:00

66 lines
2.7 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace App\Http\Middleware;
use App\Contracts\Extension\ExtensionMiddlewareRegistryInterface;
use Closure;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Http\Request;
use Illuminate\Pipeline\Pipeline;
use Symfony\Component\HttpFoundation\Response;
/**
* 확장 선언 미들웨어의 self-gate 실행기.
*
* 확장이 getMiddleware() 로 선언한 미들웨어를 web/api 그룹에 직접 넣는 대신,
* 이 래퍼가 그룹에 등록되어 요청 시점에 현재 라우트 이름·URI 가 각 확장 미들웨어의
* targets 패턴에 매칭될 때만 해당 미들웨어를 동적으로 실행한다. 매칭 없으면
* 즉시 통과 (코어 EnforceIdentityPolicy 의 라우트명 인덱스 조회 모델과 동일).
*
* 부팅 시점 라우트 순회로 확장 간 미들웨어를 부착할 수 없는 제약(확장 라우트는
* booted 지연 등록 + 순서 미보장)을 요청 시점 매칭으로 원천 회피한다.
*
* bootstrap/app.php 에서 web/api × before_core/after_core 로 총 4회 등록된다.
* Kernel 상 prepend/append 위치는 등록 시점 매핑이고, 게이트 실행 로직은 timing 을 안다.
*
* @since 7.0.5
*/
class ExtensionMiddlewareGate
{
/**
* @param Application $app Pipeline 실행용 컨테이너
* @param ExtensionMiddlewareRegistryInterface $registry 확장 미들웨어 매칭 인덱스
*/
public function __construct(
protected Application $app,
protected ExtensionMiddlewareRegistryInterface $registry,
) {}
/**
* 미들웨어 진입점.
*
* @param Request $request HTTP 요청
* @param Closure $next 다음 파이프라인
* @param string $group 이 래퍼가 등록된 그룹 ('web'|'api')
* @param string $timing 이 래퍼 인스턴스가 담당하는 실행 시점 ('before_core'|'after_core')
*/
public function handle(Request $request, Closure $next, string $group, string $timing): Response
{
// 라우트명(무명이면 빈 문자열)과 URI path(항상 존재, 선행 슬래시 없음) 둘 다 전달 —
// 무명 SSR 셸 catch-all 은 URI 패턴 target 으로만 매칭되므로 routeName 빈 값에 조기 통과하지 않는다.
$routeName = $request->route()?->getName() ?? '';
$path = $request->path();
$matched = $this->registry->resolveForRoute($routeName, $path, $group, $timing);
if ($matched === []) {
return $next($request);
}
// 매칭된 확장 미들웨어들을 Laravel Pipeline 으로 순차 실행 후 $next.
return (new Pipeline($this->app))
->send($request)
->through($matched)
->then($next);
}
}