Files
Gnuboard7/config/attachment.php
T
HeuJung ea58c606a2 fix(core,admin_basic): S3 스토리지 드라이버 실동작 결함 수정 및 S3 호환 스토리지 연결 지원
공개 제보 — 파일 스토리지에서 S3 를 선택해 저장해도 실제 파일 저장이
동작하지 않던 결함의 전면 수정.

- S3 어댑터(league/flysystem-aws-s3-v3)·predis 를 코어 기본 의존성으로 포함
 — 어댑터 부재 즉사, phpredis 확장 없는 서버의 redis 선택 전면 다운 차단
 (부트 시 확장 부재 감지 → predis 자동 폴백)
- storage_driver=s3 저장 시 코어 첨부 업로드 디스크를 s3 로 전환
 (ATTACHMENT_DISK env 명시가 항상 우선, 기존 행은 저장 당시 disk 로 서빙)
- 첨부·템플릿 레이아웃 첨부 서빙을 행 disk 를 따르는 스토리지 스트림으로 교체
 — 로컬 절대 경로 전제 fileResponse 는 S3 행에서 filemtime stat 500
 (streamedFileResponse: 행 메타 기반 ETag/304/Cache-Control)
- S3 호환 스토리지(R2/MinIO/NCP) 연결 지원: 엔드포인트 URL·path-style 설정
 신설, 리전 목록 선택 → 자유 입력 전환, 연결 테스트를 실제 저장 경로와
 동일 설정(endpoint/path-style)으로 정렬
- 사용 불능 드라이버(어댑터·PHP 확장 부재)의 저장/테스트 요청을 사유와 함께
 422 로 차단하는 서버 게이트 신설 (DriverRegistryService 능력 판정)
- 웹소켓 연결 테스트에 서버(백엔드 발송용) endpoint 검사 추가 — 클라이언트만
 검사해 테스트 성공 + 실제 발송 실패가 가능하던 비대칭 해소
- env 빈 값(`KEY=`) 함정 정규화: AWS_URL/AWS_ENDPOINT/ATTACHMENT_DISK 빈 문자열을
 미설정으로 취급 (config 정규화 + 예시 파일 주석 처리)
- 플러그인 드라이버 폴백의 log 카테고리 죽은 키(logging.default) 정정 및
 websocket 유령 설정 키 제거
- 실 AWS S3 종단 검증 완료 (설정 저장 → 업로드 S3 실저장 → 서빙 200/304)
2026-08-13 15:15:19 +09:00

99 lines
4.5 KiB
PHP

<?php
return [
/*
|--------------------------------------------------------------------------
| 스토리지 디스크
|--------------------------------------------------------------------------
|
| 첨부파일 저장에 사용할 디스크를 지정합니다.
| config/filesystems.php에 정의된 디스크 이름을 사용합니다.
|
| 빈 값(`ATTACHMENT_DISK=`)은 미설정으로 간주한다 — env() 는 키가 존재하면
| 빈 문자열을 그대로 돌려주므로(기본값 미적용), `cp .env.example .env` 설치
| 절차에서 빈 값이 그대로 오면 Storage::disk('') 로 업로드가 전면 실패한다.
|
*/
'disk' => env('ATTACHMENT_DISK') ?: 'attachments',
/*
|--------------------------------------------------------------------------
| 디스크 명시 설정 여부 (내부 판별용)
|--------------------------------------------------------------------------
|
| ATTACHMENT_DISK env 가 명시되었는지 판별하기 위한 키. env() 직접 호출은
| config:cache 환경에서 항상 null 이므로, config 캐시에 태워 두고 이 값으로
| 판별한다. null 이면 미명시 — 관리자 환경설정의 storage_driver(s3) 가
| 업로드 디스크를 전환할 수 있다 (SettingsServiceProvider::applyDriverConfig).
| 빈 값(`ATTACHMENT_DISK=`)도 미명시로 정규화한다 (위 disk 의 사유와 동일).
|
*/
'disk_explicit' => env('ATTACHMENT_DISK') ?: null,
/*
|--------------------------------------------------------------------------
| 기본 권한 정책
|--------------------------------------------------------------------------
|
| 역할이 지정되지 않은 첨부파일의 기본 권한 정책을 설정합니다.
|
| 옵션:
| - 'public': 모든 인증된 사용자에게 전체 권한 허용
| - 'owner_only': 업로더와 관리자만 접근 가능
| - 'read_only': 모든 인증된 사용자에게 read만 허용
|
*/
'default_permission_policy' => env('ATTACHMENT_DEFAULT_POLICY', 'public'),
/*
|--------------------------------------------------------------------------
| 최대 파일 크기
|--------------------------------------------------------------------------
|
| 업로드 가능한 최대 파일 크기 (KB 단위 — Laravel `max:` 규칙과 동일 단위).
|
| 단위 규약: config/attachment.* 는 KB, 관리자 환경설정 upload.* 는 MB 다.
| MB → KB 변환은 SettingsServiceProvider::applyUploadConfig() 단 한 곳에서만 수행하며,
| 소비처(FormRequest 등)는 이 값을 변환 없이 그대로 사용한다.
|
*/
'max_file_size' => env('ATTACHMENT_MAX_FILE_SIZE', 10240),
/*
|--------------------------------------------------------------------------
| 허용 확장자
|--------------------------------------------------------------------------
|
| 업로드를 허용할 파일 확장자 목록 (소문자, 점 없이).
| 관리자 환경설정의 `upload.allowed_extensions` 가 저장되면 그 값으로 대체된다.
|
| 빈 배열은 "확장자 제한 없음" 을 의미한다 — 운영 중 예상치 못한 확장자로 업로드가
| 막히는 상황의 탈출구다. 확장은 `core.attachment.allowed_extensions` 필터 훅으로
| 목록을 조정할 수 있다.
|
*/
'allowed_extensions' => [
'jpg', 'jpeg', 'png', 'gif', 'webp',
'pdf', 'doc', 'docx', 'xls', 'xlsx', 'zip',
],
/*
|--------------------------------------------------------------------------
| 이미지 축소
|--------------------------------------------------------------------------
|
| 업로드된 이미지가 이 크기(픽셀)를 넘으면 비율을 유지한 채 축소한다.
| 관리자 환경설정의 `upload.image_max_width` / `image_max_height` / `image_quality`
| 가 저장되면 그 값으로 대체된다.
|
| null = 축소하지 않음. 기본값을 null 로 두는 이유는, 이 기능이 도입됐다는 이유만으로
| 기존 사이트의 업로드 이미지가 갑자기 줄어들지 않게 하기 위함이다.
|
| image_quality 는 1~100 이며 JPEG/WebP 에 그대로, PNG 에는 압축 레벨로 환산해 쓴다.
|
*/
'image_max_width' => env('ATTACHMENT_IMAGE_MAX_WIDTH'),
'image_max_height' => env('ATTACHMENT_IMAGE_MAX_HEIGHT'),
'image_quality' => env('ATTACHMENT_IMAGE_QUALITY', 85),
];