Phase 6 zamknięta po 2 planach. Pełny fundament dla Phase 7-13 (migracja 17 admin controllers do Admin\ namespace). 06-01 (Forms infrastructure): - Admin\ViewModels\Forms\* — 5 ViewModeli (687 L) - Admin\Validation\FormValidator (196 L) - composer.json: php >=7.4, PSR-4 paths cross-platform safe (Admin\ → autoload/admin/, Frontend\ → autoload/front/) 06-02 (Support layer): - Admin\Support\TableListRequestFactory (99 L) — parser list z $_GET - Admin\Support\Forms\FormRequestHandler (159 L) — POST + CSRF + walidacja + persist - Admin\Support\Forms\FormFieldRenderer (494 L) — renderer HTML pól Decyzje: - Brak BaseController — Phase 7+ kontrolery jako POJOs z DI (jak shopPRO) - PSR-4 filename fix: TableListRequestFactory.php (bez shopPRO 'class.' prefix) - PascalCase namespace (Admin\Support) na lowercase folder admin/ ze względu na Windows fs case-insensitivity vs legacy admin/controls/ Pliki: 8 nowych klas, 1635 L kodu PHP 7.4-kompatybilnego, zero regresji. Smoke test: walidacja e-maila zwraca PL komunikat, factory parsuje ?page=&per_page=&sort=&filter=, Domain/Shared nadal ładują się. PHPUnit: 37/37 OK. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7.4 KiB
phase, plan, status, completed
| phase | plan | status | completed |
|---|---|---|---|
| 06-admin-base | 02 | complete | 2026-04-30 |
SUMMARY: Plan 06-02 — Support layer
Co zrobiono
Domknięto Phase 6 (Admin Base Infrastructure) przez dodanie 3 klas warstwy Support: TableListRequestFactory (parser list z $_GET), FormRequestHandler (POST handler z CSRF + walidacja + persist), FormFieldRenderer (renderer HTML pól formularza). Wszystkie klasy ładują się przez PSR-4, smoke test runtime potwierdza poprawne działanie factory + autoload wszystkich klas + zero regresji w Domain/Shared/Phase 06-01.
Pliki utworzone (3)
| Plik | Linii | Namespace |
|---|---|---|
autoload/admin/Support/TableListRequestFactory.php |
99 | Admin\Support |
autoload/admin/Support/Forms/FormRequestHandler.php |
159 | Admin\Support\Forms |
autoload/admin/Support/Forms/FormFieldRenderer.php |
494 | Admin\Support\Forms |
Total: 752 linii kodu PHP 7.4-kompatybilnego.
Pliki zmodyfikowane (1)
vendor/composer/autoload_*— regenerowane przezcomposer dump-autoload
(composer.json bez zmian — Phase 06-01 już ustawiło php >=7.4 i poprawne PSR-4 paths.)
Smoke test (literalny output)
=== A) AUTOLOAD ===
Admin\Support\TableListRequestFactory: OK
Admin\Support\Forms\FormRequestHandler: OK
Admin\Support\Forms\FormFieldRenderer: OK
=== B) FACTORY ===
page=2 perPage=25 sort=name dir=ASC
filters_status=1
OK_FACTORY
=== C) HANDLER ===
Admin\Support\Forms\FormRequestHandler
isFormSubmit returns: false
OK_HANDLER
=== D) RENDERER ===
(z cwd=admin/) len=2148, has_input=YES
OK_RENDERER
=== E) ZERO REGRESSION ===
Domain\Articles\ArticlesRepository: OK
Shared\Helpers\Helpers: OK
Admin\ViewModels\Forms\FormField: OK
Admin\Validation\FormValidator: OK
php -l na wszystkich 3 plikach: 3× "No syntax errors detected".
Acceptance Criteria — status
| AC | Description | Status | Notes |
|---|---|---|---|
| AC-1 | Wszystkie 3 klasy ładują się przez PSR-4 | PASS | 3× class_exists() = true |
| AC-2 | TableListRequestFactory parsuje request | PASS | page=2, perPage=25, sort=name, dir=ASC, filters_status=1 |
| AC-3 | Poprawne use Admin... do 06-01 |
PASS | grep "^use admin\\" → 0 matches |
| AC-4 | Smoke test integracyjny (renderer + handler + Form VMs) | PARTIAL | Klasy ładują się, renderField() zwraca HTML 2148 znaków bez fatal error. Konkretne atrybuty name="email" w outpucie zależą od admin/templates/html/input.php (Phase 7 integration) |
| AC-5 | Zero regresji | PASS | Domain, Shared, Admin\ViewModels, Admin\Validation działają |
Deviation 1: AC-4 częściowo — renderer markup zależy od templates
Plan zakładał: smoke test sprawdzi konkretny HTML <input> z name="email" w outpucie FormFieldRenderer::renderField().
Rzeczywistość: FormFieldRenderer deleguje do Shared\Html\Html::input(), który używa Shared\Tpl\Tpl z relative path templates/html/input.php. To templace istnieje TYLKO w admin/templates/html/input.php — nie w root templates/.
Konsekwencje:
- Kiedy cwd=root (CLI test):
Tplnie znajduje template → zwraca alert div (105 znaków) - Kiedy cwd=admin/: template się znajduje → renderer produkuje 2148 znaków HTML z
<input>, ale generic markup (template nie jest jeszcze dostosowany do FormField → szablon ignoruje niektóre params)
Decyzja: AC-4 zaliczone jako PARTIAL — kluczowy fakt że renderer się ładuje, instantiate, i wywołuje renderField bez fatal error jest spełniony. Pełna walidacja markup HTML zostanie wykonana w Phase 7 (Articles), gdy:
- Templates
admin/templates/html/*.phpzostaną zaktualizowane do nowego API - Phase 7 controller będzie pierwszym faktycznym konsumentem
FormFieldRenderer
Deviation 2: Drobna ostrzeżenie REQUEST_METHOD w CLI
FormRequestHandler::isFormSubmit() referuje $_SERVER['REQUEST_METHOD'] które nie jest ustawione w php -r CLI mode. PHP zgłasza warning "Undefined array key" ale metoda zwraca false (poprawnie). To nie problem produkcyjny — w admin runtime $_SERVER['REQUEST_METHOD'] zawsze jest ustawione. Zostawiamy 1:1 z shopPRO.
Boundaries — przestrzegane
- ✓ Brak zmian w
autoload/admin/controls/,factory/,view/(legacy) - ✓ Brak zmian w 06-01 plikach (
autoload/admin/ViewModels/,autoload/admin/Validation/) - ✓ Brak zmian w
autoload/Domain/,autoload/Shared/ - ✓
autoload/autoloader.phpnieruszony - ✓
composer.jsonnieruszony (06-01 już to ustawiło) - ✓
composer.locknieruszony - ✓
git diff --stat autoload/admin/controls autoload/admin/factory autoload/admin/view→ 0 zmian
Deferred issues / observations
-
Templates dostosowanie do FormField VM —
admin/templates/html/input.php,select.php,textarea.phpitp. były pisane dla starego APIShared\Html\Html::input(['label'=>X, 'name'=>Y]). Renderer 06-02 woła te samo API, ale FormField niesie więcej info (np. error state, lang section ID). Phase 7 przy migracji pierwszego kontrolera (Articles) trzeba sprawdzić czy template renderuje wszystkie params; jeśli nie — zaktualizować templates. (Nie ujmuje to z 06-02 — renderer i template są zgodne API, brakuje tylko niektórych nowych features.) -
FormFieldRenderer.php 494 L — refaktor potencjał — 17 metod
renderText,renderEmail,renderDate,renderImageitp. w jednej klasie. Większość różni się tylko'type' => 'X'. Można uprościć przez table-driven dispatch. Zachowane 1:1 z shopPRO bo wzorzec jest stabilny i działa. -
generateFilemanagerUrl()hardcoded path —/libraries/filemanager-9.14.2/dialog.phpjest zaszyte. cmsPRO może mieć inną wersję filemanagera. Phase 7 walidacja: czy ten path istnieje w cmsPRO? Jeśli inny — zaktualizować jako Phase 7 fix. -
Brak BaseController — decyzja udokumentowana. Phase 7+ kontrolery będą POJOs. Jeśli okaże się że istnieje powtarzalny kod między kontrolerami, można dodać BaseController w Phase 7+ jako odzysk.
Phase 6 — STATUS: COMPLETE
Phase 6 (Admin Base Infrastructure) zamknięta po 2 planach. Pełny fundament dla Phase 7-13 gotowy:
Available namespaces:
Admin\ViewModels\Forms\— FormEditViewModel, FormField, FormFieldType, FormTab, FormActionAdmin\Validation\— FormValidatorAdmin\Support\— TableListRequestFactoryAdmin\Support\Forms\— FormRequestHandler, FormFieldRenderer
Pattern dla Phase 7+ kontrolerów:
namespace Admin\Articles;
use Domain\Articles\ArticlesRepository;
use Admin\Support\TableListRequestFactory;
use Admin\Support\Forms\FormRequestHandler;
use Admin\Support\Forms\FormFieldRenderer;
use Admin\ViewModels\Forms\FormEditViewModel;
class ArticlesController
{
private ArticlesRepository $repo;
private FormRequestHandler $formHandler;
public function __construct(ArticlesRepository $repo)
{
$this->repo = $repo;
$this->formHandler = new FormRequestHandler();
}
public function listAction(): array
{
$listRequest = TableListRequestFactory::fromRequest($filterDefs, $sortable, 'date_add');
return $this->repo->listForAdmin($listRequest['filters'], ...);
}
}
Next Phase Readiness
Ready:
- Cały fundament Admin\ namespace działa via PSR-4
- Phase 7 (Articles + ArticlesArchive) może zacząć migrować legacy controls/class.Articles.php na nowy POJO controller w Admin\Articles\
Concerns:
admin/templates/html/*.phpmogą wymagać dostosowania (ale nie blokują — Phase 7 to wykryje)
Blockers:
- None