dev
This commit is contained in:
parent
b6a8133170
commit
4e41390544
15
CLAUDE.md
15
CLAUDE.md
@ -85,6 +85,8 @@ PhpStorm может показывать предупреждение «Namespac
|
||||
| `System\Classes\Session` | Синглтон сессии: `instance(string $name)`, `get/set/delete/destroy/regenerate` |
|
||||
| `System\Classes\Config` | Статический конфиг: lazy-load `App/config/config.php` + merge `config.local.php` |
|
||||
| `System\Classes\Log` | Файловый логгер: уровни, аудит запросов, лог ошибок; `info()/error()`, маскировка |
|
||||
| `System\Classes\LogReader` | Интерфейс чтения логов (`read()`, `dates()`); абстракция над хранилищем |
|
||||
| `System\Classes\FileLogReader` | Чтение/парсинг логов из файлов; реализация `LogReader` (позже возможен `DbLogReader`) |
|
||||
| `System\Classes\Validation` | Валидация входных данных по декларативным правилам; `factory()`, `rule()`, `check()`, `errors()` |
|
||||
| `System\Classes\CSRF` | Защита форм от CSRF; токен в сессии: `token()`, `validate()`, `field()` |
|
||||
| `System\Classes\HTTP` | `redirect()`, `requestHeaders()` |
|
||||
@ -270,6 +272,12 @@ Log::debug(...); Log::warning(...);
|
||||
|
||||
Каталог логов в `.gitignore` (`/App/logs/`).
|
||||
|
||||
**Просмотр логов:** страница `/admin/logs` (`App\Controller\Admin\LogsController`) с фильтрами
|
||||
(дата, канал, уровень, текст). Источник — через интерфейс `LogReader` (реализация
|
||||
`FileLogReader` парсит файлы; позже подменяется на `DbLogReader`). Каталог берётся из
|
||||
`Log::directory()`. Вывод сообщений в шаблоне `App/view/Admin/Logs/logs.html` экранируется
|
||||
(`htmlspecialchars`) — в логах есть пользовательский ввод (XSS-вектор).
|
||||
|
||||
### HTTPException (System\Classes\HTTP\HTTPException)
|
||||
|
||||
```php
|
||||
@ -309,10 +317,12 @@ $response = HTTPException::factory(403)->getResponse();
|
||||
Расстановка имён — как в проекте eoffice_v3:
|
||||
|
||||
- `System\Classes\BaseController` (abstract) — голое ядро: жизненный цикл `executeAction()` (`before()` → экшен → `after()`), хуки по умолчанию пустые. Нейтрально к вебу/API.
|
||||
- `System\Classes\Controller extends BaseController` — веб: `render()` (layout + content), авто-CSRF в `before()`, `json($data, $status)` для JSON-ответов. **Контроллеры приложения наследуют его.**
|
||||
- `System\Classes\Controller extends BaseController` — веб: `render()` (layout + content), авто-CSRF в `before()`, `json($data, $status)` для JSON-ответов, хук `layoutData()` (доп. данные в layout помимо `content`). **Контроллеры приложения наследуют его.**
|
||||
|
||||
API-контроллер делается не отдельным классом, а флагом: `extends Controller` + `$_csrf_protection = false` + ответы через `json()` (так же, как в eoffice_v3).
|
||||
|
||||
**Админка** (`App/Controller/Admin/`): базовый `App\Controller\Admin\AdminController extends Controller` задаёт layout `admin` (боковое меню, `System/view/views/admin.html`, Bootstrap из `/vendor/`) и наполняет `layoutData()` пунктами меню (`menu()` — пока статичный список, задел под БД). `before()` — заготовка под проверку прав (логина пока нет, **админка открыта**). Конкретные страницы наследуют `AdminController`.
|
||||
|
||||
`Request::execute()` вызывает `executeAction({action}Action)`, поэтому `before()/after()` работают для любого контроллера прозрачно. Авторизацию добавлять в `before()` конкретных контроллеров (логина пока нет).
|
||||
|
||||
### Environment
|
||||
@ -349,8 +359,9 @@ PHPUnit 11 в Docker-контейнере `bicycle`. Bootstrap: `tests/bootstrap
|
||||
| `tests/Unit/CSRFTest.php` | `token()` стабильность/формат, `validate()`, `field()`, нет токена в сессии |
|
||||
| `tests/Unit/ControllerTest.php` | `executeAction()`, порядок `before/action/after`, no-op хуки |
|
||||
| `tests/Unit/LogTest.php` | уровни/порог, каналы (action/error), формат, append, `strtr`, маскировка, `requestInfo()` |
|
||||
| `tests/Unit/FileLogReaderTest.php` | парсинг, фильтры (level/q/channel), newest-first, missing file, `dates()` |
|
||||
|
||||
**154 теста, 253 assertion — все проходят.**
|
||||
**162 теста, 270 assertion — все проходят.**
|
||||
|
||||
### Frontend dependencies (через Composer)
|
||||
|
||||
|
||||
@ -64,8 +64,19 @@ class Controller extends BaseController
|
||||
}
|
||||
|
||||
return (new View($this->_layout, 'view/views', [
|
||||
'content' => (new View($template, $dir, $data))->render()
|
||||
]))->render();
|
||||
'content' => (new View($template, $dir, $data))->render(),
|
||||
] + $this->layoutData()))->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Дополнительные данные, передаваемые в layout помимо 'content'
|
||||
* (например меню). Переопределяется наследниками. По умолчанию пусто.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function layoutData(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -152,10 +152,11 @@ class Log
|
||||
|
||||
/**
|
||||
* Каталог логов (из свойства, конфига или дефолт APPPATH/logs).
|
||||
* Публичный — переиспользуется читалками логов (FileLogReader).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function directory(): string
|
||||
public static function directory(): string
|
||||
{
|
||||
return self::$directory ?? Config::get('log', 'path') ?? APPPATH . '/logs';
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user