아키텍처
TubePress가 따르는 코어 구조, 요청 라이프사이클, 그리고 프레임워크를 사용하지 않는 규칙을 설명합니다.
TubePress는 의도적으로 단순하게 설계된 소프트웨어입니다. 프레임워크도, 의존성 주입 컨테이너도, 빌드 단계도 없습니다 — 정적 클래스를 사용하는 잘 정리된 현대적인 PHP만 있습니다. 이 페이지에서는 각 구성 요소가 어떻게 맞물리는지 설명하여, CMS를 자신 있게 확장하고 코드가 어디에 속하는지 정확히 파악할 수 있도록 합니다.
설계 철학
세 가지 아이디어가 전체 코드베이스를 형성합니다:
- 프레임워크 없음. 맞춤형 정적 클래스를 사용하는 순수 PHP입니다. 깨질 Composer 런타임 의존성도 없고, PHP 자체 외에 배울 것도 없습니다.
- 고정된 코어, 자유로운 애드온. 코어는 업데이트 가능하며 직접 수정해서는 안 됩니다. 커스터마이징하는 모든 것은 테마, 플러그인 또는 설정에 저장합니다.
- 확장 및 저가 호스팅 생존을 위해 설계됨. 무거운 작업은 청크로 처리되며, 내장된 pseudo-cron 덕분에 시스템 crontab이 필요하지 않습니다.
디렉토리 구조
저장소는 코어(고정, 업데이트 가능)와 애드온(사용자가 설치 및 제거)을 분리합니다.
CORE — never modified by themes/plugins, replaced by updates
config/ App config, DB config, install marker
src/Core/ App, Database, Router, Pagination, CronManager,
and the managers (Seo, Transcode, Update, …)
src/Auth/ Auth, Gate (permissions)
src/Models/ Video, Category, Tag, Performer, Channel,
Comment, Page, User, Setting, Favorite, History
src/Admin/ Admin CRUD controllers
src/Front/ Public-facing controllers
src/Install/ InstallController, Migrator
src/Helpers/ Format, FileUpload, Sanitizer, Slug, SEO,
Player, RateLimiter, ImpressionTracker
src/Plugin/ HookSystem, PluginInterface, PluginManager
src/Theme/ ThemeManager, ThemeRenderer
sql/ Numbered migrations (001_…sql → 0xx_…sql)
templates/admin/ Admin panel templates (layout + partials)
templates/install/ Install wizard templates
public/ Web root — index.php, uploads/, symlinks
cron/ Optional CLI scripts for a system crontab
ADD-ONS — installable / removable by users
themes/ Theme directories (active: "simply")
plugins/ Plugin directories (agegate, backup, ctr)
lang/ Translation files (en, fr, de, es, ar, …)커스터마이징을 위해 코어를 절대 수정하지 마십시오.
src/, config/, sql/ 또는 templates/ 아래의 모든 항목은 업데이트로 덮어쓸 수 있습니다. 변경 사항이 살아남으려면 테마나 플러그인에 넣으십시오.요청 라이프사이클
모든 요청은 동일한 순서로 public/index.php를 통해 흐릅니다:
- PHP 버전 가드.
config/php-guard.php가 먼저 실행됩니다 — 현대적인 문법이 로드되기 전에 지원되지 않는 PHP 버전에서 부팅을 중단하는 파싱 안전 게이트입니다. - 부트스트랩.
config/app.php가 자동 로딩, 세션 및 핵심 서비스를 설정합니다. - 설치 확인.
App::isInstalled()가 false이면 (config/installed.php없음), 요청이 설치 마법사로 라우팅되며 다른 것은 로드되지 않습니다. - 라우트 등록. Admin, API 및 front 컨트롤러는 각각 정적
::routes()메서드를 통해 라우트를 등록합니다. - 디스패치.
Router::dispatch()가 URL을 매칭하고 컨트롤러 메서드를 호출합니다. - 렌더링. Admin 액션은
templates/admin/*를 렌더링하고, front 액션은ThemeRenderer::render()를 통해 활성 테마를 렌더링합니다. - 렌더링 후 작업. 임프레션이 플러시되고
CronManager::run()이 예정된 작업을 실행합니다.
프론트 페이지 라우트(정적 페이지용 /{slug} 캐치올)는 마지막에 등록되어 실제 라우트를 절대 가리지 않습니다.
핵심 규칙
| 개념 | 규칙 |
|---|---|
| 컨트롤러 | AdminXxxController::routes() / FrontXxxController::routes()가 라우트를 등록하고, 메서드가 요청을 처리합니다. |
| 모델 | 정적 메서드: Video::find($id), Video::all($filters), Video::create($data). |
| 데이터베이스 | Database::fetchOne(), fetchAll(), insert(), update(), delete(), count(), transaction(). |
| 라우터 | Router::get(), Router::post(), Router::param('name'), Router::redirect(). |
| Admin 템플릿 | Router::render('admin/videos', […]) → templates/admin/videos.php (layout.php + _videos.php 파셜 로드). |
| Front 템플릿 | ThemeRenderer::render('home', […]) → 활성 테마 템플릿 + 해당 layout.php. |
| 마이그레이션 | sql/NNN_name.sql, 설치 및 업데이트 중 Migrator::run()에 의해 자동으로 실행됩니다. |
| 훅 | HookSystem::doAction('event') 및 HookSystem::applyFilter('filter', $value). |
웹 서버 지원
TubePress는 Apache와 Nginx 모두에서 실행됩니다:
- Apache —
.htaccess파일이 URL 재작성 및 디렉토리 보호를 처리합니다. - Nginx —
alias지시문이 에셋을 제공하고deny all규칙이 민감한 경로를 보호합니다. - 심볼릭 링크 —
public/themes → ../../themes및public/templates → ../../templates가 PHP 소스를 웹 루트 외부에 유지하면서 테마 및 admin 에셋을 노출합니다.
웹 루트는 항상 public/입니다. 모든 민감한 항목 — config/, src/, sql/, storage/ — 은 웹 루트 외부에 위치하며 서버 수준에서도 추가로 차단됩니다.
커스터마이징 위치
| 원하는 작업… | 위치… |
|---|---|
| 외관 및 레이아웃 변경 | 테마 (또는 코드 없이 변경하려면 외관 설정) |
| 기능 또는 통합 추가 | 액션 & 필터를 사용하는 플러그인 |
| 코드 없이 동작 변경 | 설정 |
| 예약 작업 추가 | 플러그인에서 CronManager 사용 |