Files
peptide-news-plugin/admin/class-peptide-news-admin.php
peptiderepo 19fea30932 fix(admin): load delegate classes + add WP test stubs (#8)
* fix(admin): load delegate classes from orchestrator + add WP stubs for tests

The admin refactor split introduced delegate classes that the orchestrator
instantiates in its constructor. CI failed because tests require the
orchestrator directly without going through the plugin loader. Fix: add
require_once for all delegate files at the top of the orchestrator, and
add missing WP function stubs to the test bootstrap.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(admin): add missing sanitize_model_id and sanitize_api_key delegators

The refactored orchestrator was missing public method delegations for
sanitize_model_id() and sanitize_api_key(), which tests call directly
on the Peptide_News_Admin instance and WordPress uses as register_setting
callbacks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(phpcs): remove strict_types declaration that breaks file header order

PSR12.Files.FileHeader.IncorrectOrder requires the docblock immediately
after the opening PHP tag. The declare(strict_types=1) was inserted
between them.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: peptiderepo <peptiderepo@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 17:01:34 +07:00

180 lines
5.0 KiB
PHP
Executable File

<?php
/**
* Admin-specific functionality.
*
* Orchestrator class that coordinates admin assets, menu registration,
* settings management, and dashboard/page rendering. Delegates to
* specialized admin classes to keep each focused on a single responsibility.
*
* Preserves the original public interface for backward compatibility
* with existing hooks and loader registrations.
*
* @since 1.0.0
* @see Peptide_News_Admin_Assets — Asset enqueuing
* @see Peptide_News_Admin_Menu — Menu registration
* @see Peptide_News_Admin_Settings — Settings & field renderers
* @see Peptide_News_Admin_Settings_Page — Settings page + log viewer
* @see Peptide_News_Admin_Dashboard_Pages — Dashboard/articles/costs pages
*/
// Load delegate classes that this orchestrator depends on.
require_once __DIR__ . '/class-pn-admin-assets.php';
require_once __DIR__ . '/class-pn-admin-menu.php';
require_once __DIR__ . '/class-pn-admin-field-renderers.php';
require_once __DIR__ . '/class-pn-admin-settings.php';
require_once __DIR__ . '/class-pn-admin-log-viewer.php';
require_once __DIR__ . '/class-pn-admin-settings-page.php';
require_once __DIR__ . '/class-pn-admin-dashboard-pages.php';
class Peptide_News_Admin {
/** @var string Plugin name/slug */
private $plugin_name;
/** @var string Plugin version */
private $version;
/** @var Peptide_News_Admin_Assets */
private $assets;
/** @var Peptide_News_Admin_Menu */
private $menu;
/** @var Peptide_News_Admin_Settings */
private $settings;
/** @var Peptide_News_Admin_Settings_Page */
private $settings_page;
/** @var Peptide_News_Admin_Dashboard_Pages */
private $dashboard_pages;
/**
* Constructor.
*
* Instantiates all delegate admin classes.
*
* @param string $plugin_name Plugin name/slug.
* @param string $version Plugin version.
*/
public function __construct( string $plugin_name, string $version ) {
$this->plugin_name = $plugin_name;
$this->version = $version;
// Initialize delegates.
$this->assets = new Peptide_News_Admin_Assets( $plugin_name, $version );
$this->settings = new Peptide_News_Admin_Settings();
$this->settings_page = new Peptide_News_Admin_Settings_Page( $this->settings );
$this->dashboard_pages = new Peptide_News_Admin_Dashboard_Pages();
// Menu callbacks are closures pointing to dashboard pages instance methods.
$this->menu = new Peptide_News_Admin_Menu(
fn() => $this->dashboard_pages->render_dashboard_page(),
fn() => $this->settings_page->render_settings_page(),
fn() => $this->dashboard_pages->render_articles_page(),
fn() => $this->dashboard_pages->render_cost_dashboard_page()
);
}
/**
* Enqueue admin CSS.
*
* @param string $hook Current admin page hook.
* @return void
*/
public function enqueue_styles( string $hook ): void {
$this->assets->enqueue_styles( $hook );
}
/**
* Enqueue admin JavaScript.
*
* @param string $hook Current admin page hook.
* @return void
*/
public function enqueue_scripts( string $hook ): void {
$this->assets->enqueue_scripts( $hook );
}
/**
* Register all admin menu pages.
*
* @return void
*/
public function add_admin_menu(): void {
$this->menu->add_admin_menu();
}
/**
* Register all WordPress settings.
*
* @return void
*/
public function register_settings(): void {
$this->settings->register_settings();
}
/**
* Render the settings page.
*
* @return void
*/
public function render_settings_page(): void {
$this->settings_page->render_settings_page();
}
/**
* Render the analytics dashboard page.
*
* @return void
*/
public function render_dashboard_page(): void {
$this->dashboard_pages->render_dashboard_page();
}
/**
* Render the articles management page.
*
* @return void
*/
public function render_articles_page(): void {
$this->dashboard_pages->render_articles_page();
}
/**
* Render the LLM cost tracking dashboard page.
*
* @return void
*/
public function render_cost_dashboard_page(): void {
$this->dashboard_pages->render_cost_dashboard_page();
}
/**
* Sanitize and validate an OpenRouter model ID.
*
* Delegates to the settings class. Kept on the orchestrator because
* WordPress register_setting() callbacks may reference $this.
*
* @param string $value Raw model ID from form input.
* @return string Sanitized model ID or empty string on failure.
*/
public function sanitize_model_id( string $value ): string {
return $this->settings->sanitize_model_id( $value );
}
/**
* Sanitize an API key value — encrypt if new, preserve if masked.
*
* Delegates to the settings class. Kept on the orchestrator because
* WordPress register_setting() callbacks may reference $this.
*
* @param string $value Raw API key from form input.
* @param string $option_name The WP option being saved.
* @return string Encrypted key or previous value if input was masked.
*/
public function sanitize_api_key( string $value, string $option_name = '' ): string {
return $this->settings->sanitize_api_key( $value, $option_name );
}
}