Repository navigation
v2.1.2 — Phase 9.6 admin UI extraction
Phase 9.6 — Admin UI Extraction
Extract settings_page() (~705 LOC) and brands_page() (~1,237 LOC) plus three admin-side registrars from the god-class into dedicated, single-responsibility classes under src/Admin/. Main file drops 4,855 → ~2,773 LOC — the largest single phase by LOC of the v2.1.x continuation arc.
What moved out of dataflair-toplists.php
\DataFlair\Toplists\Admin\Pages\SettingsPage— replaces inlinesettings_page(). Constructor takes typed\Closuredependencies (apiBaseUrlResolver,lastSyncLabelFormatter).\DataFlair\Toplists\Admin\Pages\BrandsPage— replaces inlinebrands_page(). Same closure-injection pattern (distinctCsvValuesCollector,lastSyncLabelFormatter).\DataFlair\Toplists\Admin\MenuRegistrar— ownsadd_menu_page+ the twoadd_submenu_pagecalls. Top-level menu icon (dashicons-list-view) and position (30) unchanged.\DataFlair\Toplists\Admin\SettingsRegistrar— owns the nineregister_settingcalls under thedataflair_settingsgroup.\DataFlair\Toplists\Admin\Notices\PermalinkNotice— owns the plain-permalinks admin warning.
Closure injection over hard wiring
The page classes take typed \Closure dependencies in their constructors so they can call back into still-private god-class helpers (get_api_base_url, format_last_sync_label, collect_distinct_csv_values) without inheriting the singleton or widening the deprecated class surface. Strangler-fig pattern continues; no surface area added.
Tests
22 new tests across SettingsPageTest, BrandsPageTest, MenuRegistrarTest, SettingsRegistrarTest, PermalinkNoticeTest. Reflection-based contract tests pin constructor signatures, interface conformance, render-method shape, and class finality without re-rendering the 1,200+ LOC HTML bodies inside PHPUnit.
Full suite: 434 tests, 1,028 assertions, all green.
No public contract change
Every admin URL, AJAX action, settings option name, capability check, nonce, page slug, and submenu position is preserved byte-for-byte. The strict-deprecation contract on DataFlair_Toplists::get_instance() from v2.1.0 is untouched.
Branch: epic/refactor-april
Previous release: v2.1.1
Next planned phase: Phase 9.7 — AJAX handler extraction (v2.1.3)